从 html_text() 返回的 Rvest 抓取网页内容

Rvest scraping webpage content returned from html_text()

提问人:M.Bergen 提问时间:1/7/2020 最后编辑:M.Bergen 更新时间:1/7/2020 访问量:405

问:

我正在尝试使用 rvest 包从网页中抓取(动态?)内容。我知道动态内容应该需要使用 Selenium 或 PhantomJS 等工具。

然而,我的实验使我相信我仍然能够仅使用标准的网络抓取 r 包 (rvest,httr,xml2) 找到我想要的内容。

在这个例子中,我将使用谷歌地图网页。 这是示例 url...

https://www.google.com/maps/dir/920+nc-16-br,+denver,+nc,+28037/2114+hwy+16,+denver,+nc,+28037/

如果您点击上面的超链接,它将带您进入一个示例网页。在此示例中,我想要的内容是网页左上角的地址“920 NC-16, Crumpler, NC 28617”和“2114 NC-16, Newton, NC 28658”。

使用 css 选择器或 xpath 的标准技术不起作用,这最初是有道理的,因为我认为这个内容是动态的。

url<-"https://www.google.com/maps/dir/920+nc-16-br,+denver,+nc,+28037/2114+hwy+16,+denver,+nc,+28037/"
page<-read_html(url)

# The commands below all return {xml nodeset 0}
html_nodes(page,css=".tactile-searchbox-input")
html_nodes(page,css="#sb_ifc50 > input")
html_nodes(page,xpath='//*[contains(concat( " ", @class, " " ), concat( " ", "tactile-searchbox-input", " " ))]')

上面的命令都返回“{xml nodeset 0}”,我认为这是动态生成此内容的结果,但这是我的困惑所在,如果我使用 html_text() 将整个页面转换为文本,我可以在返回的值中找到地址。

html_text(read_html(url))
substring<-substr(x,33561-100,33561+300)

执行上述命令会生成一个具有以下值的子字符串:

“null,null,null,null,null,[null,null,null,null,null,null,null,[[[\”920 NC-16, Crumpler, NC 28617\“,null,null,null,\”Nzm5FTtId895YoaYC4wZqUnMsBJ2rlGI\“]\n,[\”2114 NC-16, Newton, NC 28658\“,null,null,null,null,null,null,\”RIU-FSdWnM8f-IiOQhDwLoMoaMWYNVGI\“]\n]\n,null,null,0,null,[[null,null,null,null,null,null,3]\n,[null,null,null,null,[null,null,null,nu”

子字符串非常凌乱,但包含我需要的内容。我听说使用正则表达式解析网页是不受欢迎的,但我想不出任何其他方法来获取这些内容,这也可以避免使用动态抓取工具。

如果有人对解析返回的html有任何建议,或者可以解释为什么我无法使用xpath或css选择器找到内容,但可以通过简单地解析原始html文本找到它,将不胜感激。

感谢您抽出时间接受采访。

r 网页抓取 解析 rvest html-content-extraction

评论


答:

1赞 Allan Cameron 1/7/2020 #1

使用 Xpath 或 css 选择器找不到文本的原因是您找到的字符串位于 javascript 数组对象的内容中。您正确地假设您可以在屏幕上看到的文本元素是动态加载的;这些不是您从中读取字符串的地方。

我不认为使用正则表达式解析特定的html有什么问题。我会确保我得到完整的html,而不仅仅是输出,在这种情况下,通过使用包。您可以像这样从页面中获取地址:html_text()httr

library(httr)

GetAddressFromGoogleMaps <- function(url)
{
  GET(url)                %>% 
  content("text")         %>%
  strsplit("spotlight")   %>%
  extract2(1)             %>%
  extract(-1)             %>%
  strsplit("[[]{3}(\")*") %>%
  extract2(1)             %>%
  extract(2)              %>%
  strsplit("\"")          %>%
  extract2(1)             %>%
  extract(1)
}

现在:

GetAddressFromGoogleMaps(url)
#[1] "920 NC-16, Crumpler, NC 28617, USA"

评论

0赞 M.Bergen 1/8/2020
非常感谢,我一直在寻找一种更好的方法来浏览 html,并且非常喜欢使用 httr 和 extract() 函数!