Rvest : Extracting clickable content

Viewed 40

I am trying to extract the table in the link below

https://agmarknet.gov.in/SearchCmmMkt.aspx?Tx_Commodity=1&Tx_State=0&Tx_District=0&Tx_Market=0&DateFrom=2022-01-28&DateTo=2022-01-28&Fr_Date=2022-01-28&To_Date=2022-01-28&Tx_Trend=2&Tx_CommodityHead=Wheat&Tx_StateHead=--Select--&Tx_DistrictHead=--Select--&Tx_MarketHead=--Select--

I want the whole table to be extracted and I am using the following code

html_page <- read_html(curl(curl))
tab <- html_page %>% html_table(., fill = TRUE)

I get the table in tab[[1]], however, if you notice that website it has a clickable section within the table that has additional data. That part is missing from the extracted table. Will appreciate any help on how the whole table can be extracted.

1 Answers

I'm not sure what you're getting. However, when I pulled from this website I see that there are multiple tabs but I pulled all of the data.

Here is the bottom of the table, when you show all.

enter image description here

Here are the results, when I query for the last line of this website data.

library(rvest)
library(tidyverse)

hx = "https://agmarknet.gov.in/SearchCmmMkt.aspx?Tx_Commodity=1&Tx_State=0&Tx_District=0&Tx_Market=0&DateFrom=2022-01-28&DateTo=2022-01-28&Fr_Date=2022-01-28&To_Date=2022-01-28&Tx_Trend=2&Tx_CommodityHead=Wheat&Tx_StateHead=--Select--&Tx_DistrictHead=--Select--&Tx_MarketHead=--Select--"

htp <- read_html(hx) %>% html_table(., fill = T)

tbOne = htp[[1]][, 1:10] # just the data

tbOne %>% filter(`State Name` == "Uttar Pradesh",
                 `District Name` == "Badaun",
                 `Market Name` == "Wazirganj")
# # A tibble: 1 × 10
#   `State Name`  `District Name` `Market Name` Variety Group   `Arrivals (Tonnes)`
#   <chr>         <chr>           <chr>         <chr>   <chr>   <chr>              
# 1 Uttar Pradesh Badaun          Wazirganj     Dara    Cereals 3.50    
       
# # … with 4 more variables: `Min Price (Rs./Quintal)` <chr>,
# #   `Max Price (Rs./Quintal)` <chr>, `Modal Price (Rs./Quintal)` <chr>,
# #   `Reported Date` <chr> 


Update

When I pressed the 2, nothing happened (and I did try repeatedly). However, I needed to be really patient and I wasn't. Sorry about that.

The URL has the query in it, so the URL can be used to get all of the data. You could do this by adding the states you're missing, or you could do this for every state. For example, page one ends on Utter Pradesh, but we don't know if this is all of Utter Pradesh. That might make more sense when you see what I did.

Using rvest, I collected all of the states' names from the form. Then I put these name-value pairs into a data frame.

# collect form values for State
ht <- read_html(hx) %>% html_form()
df1 <- as.data.frame(ht[[1]][["fields"]][["ctl00$ddlState"]][["options"]]) %>% 
  rownames_to_column("State")
names(df1)[2] <- "Abb"

To only look at the states that were not included in page one, you could just query the states after Utter Pradesh like this.

which(df1$State == "Uttar Pradesh", arr.ind = T)
# [1] 35 

# split the URL
urone = "https://agmarknet.gov.in/SearchCmmMkt.aspx?Tx_Commodity=1&Tx_State="
urtwo = "&Tx_District=0&Tx_Market=0&DateFrom=2022-01-28&DateTo=2022-01-28&Fr_Date=2022-01-28&To_Date=2022-01-28&Tx_Trend=2&Tx_CommodityHead=Wheat&Tx_StateHead=West+Bengal&Tx_DistrictHead=--Select--&Tx_MarketHead=--Select--"

# collect remaining states' data
df2 <- map(36:nrow(df1),
           function(x){
             # assemble URL
             y = toString(df1$Abb[x])
             urall = paste0(urone, y, urtwo)
             # get table
             tabs <- read_html(urall) %>% html_table(., fill = T)
             tabs
           })

length(df2)
# [1] 2 
length(df2[[1]]) # state 36 is empty
length(df2[[2]]) # state 37 is not

# add the new data to the original data
df3 <- df2[[2]][[1]]
tbOne <- rbind(tbOne, df3) # one data frame of tabled data

If you wanted to make sure that you had all the data for each state, you could expand this. Although, using map for that much data may be slow. So I used the function mclapply from the package parallel. In this code, I used 15 cores. You may need to change this depending on your computer's processor. Using 15 made this take less than a second.

# skip row 1, that's "select" or all
df4 <- mclapply(2:nrow(df1), mc.cores = getOption("mc.cores", 15L),
                function(x){
                  # assemble URL
                  y = toString(df1$Abb[x])
                  urall = paste0(urone, y, urtwo)
                  # get table
                  tabs <- read_html(urall) %>% html_table(., fill = T)
                  tabs
                  })

length(df4)
# [1] 36 

# create storage using first state with data
df5 <- df4[[7]][[1]]

map(8:36,
    function(x){
      y = length(df4[[x]])
      if(y > 0){
        df5 <<- rbind(df5, df4[[x]][[1]])
      }
    })

Now you have a data frame, df5 that started as each state queried separately.

I didn't look at how the data was different. However, my tbOne data frame has 577 observations. My df5 data frame has 584.

Related