【问题标题】:Quickly finding an Xpath with R使用 R 快速查找 Xpath
【发布时间】:2014-04-27 21:13:23
【问题描述】:

我正在抓取以下网站:http://en.wikipedia.org/wiki/List_of_Presidents_of_the_United_States

假设我有兴趣刮掉第四任总统 - 我可以从表格中看到它是“詹姆斯麦迪逊”。使用 Chrome 浏览器,我可以快速识别 Xpath(检查元素,复制 XPath)。这给了我:“//*[@id='mw-content-text']/table[1]/tbody/tr[7]/td[2]/b/a”。但是,这不适用于 R:

library(XML)
url <- "http://en.wikipedia.org/wiki/List_of_Presidents_of_the_United_States"
html <- htmlTreeParse(url,useInternalNodes=T)
xpath <- paste("//*[@id='mw-content-text']/table[1]/tbody/tr[7]/td[2]/b/a",sep="")
xpathSApply(html, xpath, xmlValue)

返回 NULL。此处使用的正确 XPath 是“//*[@id='mw-content-text']/table[1]/tr[7]/td[2]/b/a” .所以我的问题是:

  1. 如何更改 R 中的设置,以便 R 看到与我的 Chrome 浏览器相同的 XPath?我相信这与http用户代理有关吗? This post 提出了类似的问题,但答案没有提供足够的细节。
  2. 如果这不可能,我如何使用 XML 包快速识别导致“James Madison”的正确 XPath?即“//*[@id='mw-content-text']/table[1]/tr[7]/td[2]/b/a

谢谢!

【问题讨论】:

  • 如果 Chrome 自动生成tbody,为什么不在查询中直接生成subxpathSApply(html, sub('tbody', '', xpath), xmlValue)

标签: r xpath web-scraping


【解决方案1】:

原来html中没有tbody标签。这是由浏览器添加的。所以基本上,Chrome推荐的xpath是错误的。

library(httr)
grepl("table",content(GET(url),type="text"))
# [1] TRUE
grepl("tbody",content(GET(url),type="text"))
# [1] FALSE

注意::这绝不是使用正则表达式解析 html 的建议!!!

问题的出现是因为浏览器被设计为对格式不正确的 html 相对宽容。因此,如果一个标签明确缺失,浏览器会添加它(例如,如果您发送一个没有 body 标签的页面,它无论如何都会呈现,因为浏览器在加载页面后将该标签添加到 DOM)。 htmlParse(...) 不是这样工作的:它只是加载和解析服务器响应。 HTML 4 规范中的表格需要 tbody 标记,因此浏览器添加了它。请参阅this post 了解说明。

因此,以“半自动”方式处理此问题的一种方法是:

xpath <-paste("//*[@id='mw-content-text']/table[1]/tbody/tr[7]/td[2]/b/a",sep="")
if (length(html["//tbody"])==0) xpath <- gsub("/tbody","",xpath)
xpathSApply(html, xpath, xmlValue)
# [1] "James Madison"

【讨论】:

    【解决方案2】:

    我建议使用selectr 包,它允许您使用 CSS 样式选择器而不是 XPath,这有时会很麻烦。或者,由于您正在寻找表格,我建议您使用自动抓取页面所有表格的readHTMLTable 函数。

    library(XML)
    library(selectr)
    
    url <- "http://en.wikipedia.org/wiki/List_of_Presidents_of_the_United_States"
    doc <- htmlParse(url)
    tab <- querySelector(doc, 'table.wikitable')
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-11
      • 2019-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多