Triggering doPostBack javascript with RSelenium to scrap multi-page table

社会主义新天地 提交于 2020-01-25 06:39:07

问题


I am struggling to 'web-scrap' data from a table which spans over several pages. The pages are linked via javascript.

The data I am interested in is based on the website's search function:

url <- "http://aims.niassembly.gov.uk/plenary/searchresults.aspx?tb=0&tbv=0&tbt=All%20Members&pt=7&ptv=7&ptt=Petition%20of%20Concern&mc=0&mcv=0&mct=All%20Categories&mt=0&mtv=0&mtt=All%20Types&sp=1&spv=0&spt=Tabled%20Between&ss=jc7icOHu4kg=&tm=2&per=1&fd=01/01/2011&td=17/04/2018&tit=0&txt=0&pm=0&it=0&pid=1&ba=0"

I am able to download the first page with the rvest package:

library(rvest)
library(tidyverse)

NI <- read_html(url)

NI.res <- NI %>%
  html_nodes("table") %>% 
  html_table(fill=TRUE)

NI.res <- NI.res[[1]][c(1:10),c(1:5)]

So far so good.

As far as I understood, the RSelenium package is the way forward to navigate on websites with javascript/when html scrapping via changing urls is not possible. I installed the package and run it in combination with the Docker Quicktool Box (all working fine),

library (RSelenium)
shell('docker run -d -p 4445:4444 selenium/standalone-chrome')
remDr <- remoteDriver(remoteServerAddr = "192.168.99.100", 
                      port = 4445L,
                      browserName = "chrome")

remDr$open()

My hope was that by triggering the javascript I could naviate to the next page and repeat the rvest command and obtain the data contained on the e.g. 2nd, 3rd etc page (eventually that should be part of a loop or purrr::map function).

Navigate to the table with search results (1st page):

remDr$navigate("http://aims.niassembly.gov.uk/plenary/searchresults.aspx?tb=0&tbv=0&tbt=All%20Members&pt=7&ptv=7&ptt=Petition%20of%20Concern&mc=0&mcv=0&mct=All%20Categories&mt=0&mtv=0&mtt=All%20Types&sp=1&spv=0&spt=Tabled%20Between&ss=jc7icOHu4kg=&tm=2&per=1&fd=01/01/1989&td=01/04/2018&tit=0&txt=0&pm=0&it=0&pid=1&ba=0")

Trigger the javascript. The content of the javascript is taken from hovering with the mouse over the index of pages on the webiste (below the table). In the case below the javascript leading to page 2 is triggered:

remDr$executeScript("__doPostBack('ctl00$MainContentPlaceHolder$SearchResultsGridView','Page$2');", args=list("dummy"))

Repeat the scrapping with rvest

url <- "http://aims.niassembly.gov.uk/plenary/searchresults.aspx?tb=0&tbv=0&tbt=All%20Members&pt=7&ptv=7&ptt=Petition%20of%20Concern&mc=0&mcv=0&mct=All%20Categories&mt=0&mtv=0&mtt=All%20Types&sp=1&spv=0&spt=Tabled%20Between&ss=jc7icOHu4kg=&tm=2&per=1&fd=01/01/2011&td=17/04/2018&tit=0&txt=0&pm=0&it=0&pid=1&ba=0"
NI <- read_html(url)

NI.res <- NI %>%
  html_nodes("table") %>% 
  html_table(fill=TRUE)
NI.res2 <- NI.res[[1]][c(1:10),c(1:5)]

Unfortunately though, the triggering of the javascript appears not to work. The scrapped results are again those from page 1 and not from page 2. I might be missing something rather basic here, but I can't figure out what.

My attempt is partly informed by SO posts here, here and here. I also saw this post.

Context: Eventually, in further steps, I will have to trigger a click on each single finding/row which shows up on all pages and also scrap the information behind each entry. Hence, as far as I understood, RSelenium will be the main tool here.

Grateful for any hint!

UPDATE

I made 'some' progress following the approach suggested here. It's a) still not doing everything I am intending to do and b) is very likely not the most elegant form of how to do it. But maybe it's of some help to others/opens up a way forward. Note that this approach does not require RSelenium.

I basically created a loop for each javascript (page index) leading to another page of the table which I want to scrap. The crucial detail is the EVENTARGUMENT argument to which I assign the respective page number (my knowledge of js is bascially zero).

for (i in 2:15) {

target<- paste0("Page$",i) 

page<-rvest:::request_POST(pgsession,"http://aims.niassembly.gov.uk/plenary/searchresults.aspx?tb=0&tbv=0&tbt=All%20Members&pt=7&ptv=7&ptt=Petition%20of%20Concern&mc=0&mcv=0&mct=All%20Categories&mt=0&mtv=0&mtt=All%20Types&sp=1&spv=0&spt=Tabled%20Between&ss=jc7icOHu4kg=&tm=2&per=1&fd=01/01/2011&td=17/04/2018&tit=0&txt=0&pm=0&it=0&pid=1&ba=0",
                           body=list(
                             `__VIEWSTATE`=pgform$fields$`__VIEWSTATE`$value,
                             `__EVENTTARGET`="ctl00$MainContentPlaceHolder$SearchResultsGridView",
                             `__EVENTARGUMENT`= target,                                                         `__VIEWSTATEGENERATOR`=pgform$fields$`__VIEWSTATEGENERATOR`$value,
                             `__VIEWSTATEENCRYPTED`=pgform$fields$`__VIEWSTATEENCRYPTED`$value,
                             `__EVENTVALIDATION`=pgform$fields$`__EVENTVALIDATION`$value
                           ),
                           encode="form")

x <- read_html(page) %>% 
  html_nodes(css = "#ctl00_MainContentPlaceHolder_SearchResultsGridView") %>% 
  html_table(fill=TRUE) %>% 
  as.data.frame() 

d<- x[c(1:paste(nrow(x)-2)),c(1:5)]  
page.list[[i]] <- d

i=i+1

}

However, this code is not able to trigger the javascript/go to the pages which are not visible in the page index below the table when opening the site (1 - 11). Only page 2 to 11 can be scrapped with this loop. Since the script for page 12 and subsequent are not visible, they can't be triggered.

来源:https://stackoverflow.com/questions/49770566/triggering-dopostback-javascript-with-rselenium-to-scrap-multi-page-table

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!