【问题标题】:Unable to scrape multiple pages using phantomjs in r无法在 r 中使用 phantomjs 抓取多个页面
【发布时间】:2016-02-17 06:09:19
【问题描述】:

我正在尝试使用由 RSelenium 控制的 phantomjs 从https://www.washoecounty.us/assessor/cama/?command=assessment_data&parid=07101001 中使用 javascript 生成多个宗地的历史财产价值的县评估员数据。 url 中的“paraid”是 9 位数的包裹号码。我有一个数据框,其中包含我感兴趣的包裹号码列表(总共几百个),但一直试图让代码在其中的一小部分上工作:

parcel_nums
[1] "00905101" "00905102" "00905103" "00905104" "00905105" 
[6] "00905106" "00905107" "00905108" "00905201" "00905202"

我需要为每个包裹在页面上生成的表格中抓取数据并保存。我选择将页面写入文件“output.htm”,然后解析该文件。我的代码如下:

require(plyr)
require(rvest)
require(RSelenium)
require(tidyr)
require(dplyr)

parcel_nums <- prop_attr$APN[1:10]  #Vector of parcel numbers
pJS <- phantom()
remDr <- remoteDriver(browserName = "phantomjs")
remDr$open()

result <- remDr$phantomExecute("var page = this;
                            var fs = require(\"fs\");
                            page.onLoadFinished = function(status) {
                            var file = fs.open(\"output.htm\", \"w\");
                            file.write(page.content);
                            file.close();
                            };")

for (i in 1:length(parcel_nums)){
    url <- paste("https://www.washoecounty.us/assessor/cama/?command=assessment_data&parid=", 
        parcel_nums[i], sep = "")
    Sys.sleep(5)

    emDr$navigate(url)

    dat <- read_html("output.htm", encoding = "UTF-8") %>% 
        html_nodes("table") %>% 
        html_table(, header = T)
    df <- data.frame(dat)

    #assign parcel number to panel
    df$apn <- parcel_nums[i]
    #on first iteratation initialize final data frame, on sebsequent iterations append the final data frame
    ifelse(i == 1, parcel_data <- df, parcel_data <- rbind(parcel_data, df))
}
remDr$close
pJS$stop()

这对于循环的一到两次迭代将非常有效,但它突然停止保存由 javascript 生成的数据并产生错误:

 Error in `$<-.data.frame`(`*tmp*`, "apn", value = "00905105") : 
 replacement has 1 row, data has 0 

这是由于解析器没有在输出文件中找到表,因为它没有被保留。我不确定我选择的实现是否存在问题,或者是否存在导致问题的特定站点的某些特质。我不熟悉 JavaScript,所以使用的代码 sn-p 取自我找到的示例。感谢您的帮助。

以下答案完美无缺。我还将 Sys.sleep(5) 移到 $navigate 之后,以允许页面有时间加载 javascript。循环现在正在执行完成。

【问题讨论】:

    标签: javascript r web-scraping phantomjs rselenium


    【解决方案1】:
    require(plyr)
    require(rvest)
    require(RSelenium)
    require(tidyr)
    require(dplyr)
    
    parcel_nums <- prop_attr$APN[1:10]  #Vector of parcel numbers
    #pJS <- phantom()
    remDr <- remoteDriver()
    remDr$open()
    
    # #result <- remDr$executeScript("var page = this;
    #                                var fs = require(\"fs\");
    #                                page.onLoadFinished = function(status) {
    #                                var file = fs.open(\"output.htm\", \"w\");
    #                                file.write(page.content);
    #                                file.close();
    #                                };")
    #length(parcel_nums)
    for (i in 1:length(parcel_nums)){
      url <- paste("https://www.washoecounty.us/assessor/cama/?command=assessment_data&parid=", 
                   parcel_nums[i], sep = "")
      Sys.sleep(5)
    
      remDr$navigate(url)
      doc <- htmlParse(remDr$getPageSource()[[1]])
      doc_t<-readHTMLTable(doc,header = TRUE)$`NULL`
      df<-data.frame(doc_t)
    
      #assign parcel number to panel
      df$apn <- parcel_nums[i]
      #on first iteratation initialize final data frame, on sebsequent iterations append the final data frame
      ifelse(i == 1, parcel_data <- df, parcel_data <- rbind(parcel_data, df))
    }
    remDr$close
    

    这给了我一个解决方案。这也应该与 phantomJS 一起使用。我请求你测试和回复。

    【讨论】:

    • 我运行了你的代码,但我收到一个错误:'code'(RCurl 调用中的未定义错误。queryRD(paste0(serverURL, "/session/", sessionInfo$id, "/网址"), :)
    • 忽略最后一条评论。我在 $open 命令之后添加了一个 Sys.sleep 并且错误消失了。
    【解决方案2】:

    我花了一整天的时间来解决类似的问题。所以我分享我的学习,以帮助他人节省时间和精力..

    我想我们需要了解通过远程驱动程序打开、导航和其他浏览操作需要时间来完成。 因此,我们必须等待,然后才能尝试在我们希望抓取的页面上阅读或执行任何操作。

    当我在remDr$navigate(url) 通话后介绍Sys.sleep(5) 时,我的问题得到了解决。

    似乎更简洁的解决方案包括插入remDr$setTimeout(type = "page load", milliseconds = 10000),正如how to check if page finished loading in RSelenium 所建议的那样,但尚未对其进行测试。

    【讨论】:

    • 同意。我发现在导航之后也有必要包含一个 Sys.sleep 。所需时间可能取决于被抓取的页面,在使用 chrome 的开发人员工具检查页面加载时间后,我能够将等待时间缩短到每页 3 秒。下次我需要刮擦时,我会尝试您的替代解决方案。
    猜你喜欢
    • 1970-01-01
    • 2019-10-14
    • 1970-01-01
    • 1970-01-01
    • 2017-02-05
    • 1970-01-01
    • 2022-01-21
    • 2022-01-03
    • 2019-02-16
    相关资源
    最近更新 更多