【问题标题】:Download documents from aspx web page in R从 R 中的 aspx 网页下载文档
【发布时间】:2015-08-21 04:24:44
【问题描述】:

我正在尝试使用 R 中的“rvest”和“downloader”包从科罗拉多石油和天然气保护委员会 (COGCC) 自动下载石油和天然气井的文件。

包含特定井文件的表格/表格的链接是; http://ogccweblink.state.co.us/results.aspx?id=12337064

“id=12337064”是井的唯一标识符

表格页面上的文件可以点击下载。 下面是一个例子。 http://ogccweblink.state.co.us/DownloadDocument.aspx?DocumentId=3172781

“DocumentID=3172781”是要下载的文档的唯一文档 ID。在这种情况下,一个 xlsm 文件。文档页面上的其他文件格式包括 PDF 和 xls。

到目前为止,我已经能够编写代码来下载任何井的任何文档,但仅限于第一页。大多数井都有多个页面上的文档,我无法在第 1 页以外的页面上下载文档(所有文档页面都有相似的 URL)

## Extract the document id for document to be downloaded in this case "DIRECTIONAL DATA". Used the SelectorGadget tool to extract the CSS path
library(rvest)
html <- html("http://ogccweblink.state.co.us/results.aspx?id=12337064")
File <- html_nodes(html, "tr:nth-child(24) td:nth-child(4) a")
File <- as(File[[1]],'character')
DocId<-gsub('[^0-9]','',File)
DocId
[1] "3172781"

## To download the document, I use the downloader package
library(downloader)
linkDocId<-paste('http://ogccweblink.state.co.us/DownloadDocument.aspx DocumentId=',DocId,sep='')
download(linkDocId,"DIRECTIONAL DATA" ,mode='wb')

    trying URL 'http://ogccweblink.state.co.us/DownloadDocument.aspx?DocumentId=3172781'
Content type 'application/octet-stream' length 33800 bytes (33 KB)
downloaded 33 KB

有谁知道如何修改我的代码以下载其他页面上的文档?

非常感谢!

【问题讨论】:

  • 当您加载该页面时,会出现一个包含__EVENTARGUMENT=Page%242 之类的帖子请求。这个参数似乎控制着你看到的数据。
  • 有 rcurl 和 httr here 的线索(使用 firefox 或 chrome 中的开发工具包查看浏览器发送的请求并稍后模仿它们)
  • 感谢@user2706569 的建议。我将 Param 更改为 __EVENTARGUMENT=Page$2 并重新运行在 link 上找到的以下代码以查看第 2 页的文档,但发布请求仍在第一页显示文档。对代码所做的唯一细微调整是包括eventargument &lt;- as.character("Page$2"); params &lt;- list('__EVENTARGUMENT' = eventargument); html = postForm('http://ogccweblink.state.co.us/results.aspx?id=12337064', .params = params, curl = curl)

标签: html r web-scraping html-parsing


【解决方案1】:

您必须对第二个查询使用相同的 cookie,并同时传递视图状态和验证字段。快速示例:

  1. 加载 RCurl 并加载 URL 并保留 cookie:

    url   <- 'http://ogccweblink.state.co.us/results.aspx?id=12337064'
    library(RCurl)
    curl  <- curlSetOpt(cookiejar = 'cookies.txt', followlocation = TRUE, autoreferer = TRUE, curl = getCurlHandle())
    page1 <- getURL(url, curl = curl)
    
  2. 解析 HTML 后提取 VIEWSTATEEVENTVALIDATION 值:

    page1 <- htmlTreeParse(page1, useInternal = TRUE)
    viewstate  <- xpathSApply(page1, '//input[@name = "__VIEWSTATE"]', xmlGetAttr, 'value')
    validation <- xpathSApply(page1, '//input[@name = "__EVENTVALIDATION"]', xmlGetAttr, 'value')
    
  3. 使用保存的 cookie 再次查询相同的 URL,提取隐藏的 INPUT 值并请求第二页:

    page2 <- postForm(url, curl = curl,
             .params = list(
                 '__EVENTARGUMENT'   = 'Page$2',
                 '__EVENTTARGET'     = 'WQResultGridView',
                 '__VIEWSTATE'       = viewstate,
                 '__EVENTVALIDATION' = validation))
    
  4. 从第二页显示的表格中提取 URL:

    page2 <- htmlTreeParse(page2, useInternal = TRUE)
    xpathSApply(page2, '//td/font/a', xmlGetAttr, 'href')
    

【讨论】:

  • 感谢@daroczig 的及时回复。我在上面使用了您的代码修改,但无法从 postForm 函数中获取为第二页打印的文档 ID。在从任何页面下载文档之前,需要提取文档 ID。期待你的回复。谢谢!
  • @user2566907 -- postForm 以文本形式返回 HTML,其中包括 ID,并且可以通过 XML(就像我在上面的第二步中所做的那样)或 rvest(由您的原始示例)也是如此。只需保存 postForm 返回的内容并将其传递给您在问题中使用的 html 函数 - 它工作正常。
  • 我按照您的建议做了,并收到以下错误消息 Error in UseMethod("html_nodes") : no applicable method for 'html_nodes' applied to an object of class "character" 用于 html 函数和 Error in UseMethod("xpathApply") : no applicable method for 'xpathApply' applied to an object of class "character" 用于 XML。你能告诉我适合你的代码吗?谢谢!
  • @user2566907 我已经编辑了我的答案以包括该部分的示例,但我认为 SO 是为了询问有关特定问题的一般指南,而不是提供完整解决方案的网站给定的问题。所以下次你应该提出单独的问题(例如如何解析 HTML,如何加载第二页等)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多