在R中使用`rvest`使用`read_html`时缺少元素

时间:2016-08-31 13:30:42

标签: html r web-scraping rvest

我试图在read_html包中使用rvest函数,但遇到了我正在努力解决的问题。

例如,如果我试图阅读this页面上显示的底部表格,我会使用以下代码:

library(rvest)
html_content <- read_html("https://projects.fivethirtyeight.com/2016-election-forecast/washington/#now")

通过检查浏览器中的HTML代码,我可以看到我想要的内容包含在<table>标记中(具体来说,它都包含在<table class="t-calc">中)。但是当我尝试使用以下方法提取时:

tables <- html_nodes(html_content, xpath = '//table')

我检索以下内容:

> tables
{xml_nodeset (4)}
[1] <table class="tippingpointroi unexpanded">\n  <tbody>\n    <tr data-state="FL" class=" "> ...
[2] <table class="tippingpointroi unexpanded">\n  <tbody>\n    <tr data-state="NV" class=" "> ...
[3] <table class="scenarios">\n  <tbody/>\n  <tr data-id="1">\n    <td class="description">El ...
[4] <table class="t-desktop t-polls">\n  <thead>\n    <tr class="th-row">\n      <th class="t ...

其中包括页面上的一些表格元素,但不包括我感兴趣的表格元素。

对于我出错的地方的任何建议都将非常感激!

1 个答案:

答案 0 :(得分:6)

该表是根据页面本身的JavaScript变量中的数据动态构建的。使用RSelenium在呈现后抓取页面文本并将页面传递到rvest或使用V8抓取所有数据的宝库:

library(rvest)
library(V8)

URL <- "http://projects.fivethirtyeight.com/2016-election-forecast/washington/#now"

pg <- read_html(URL)

js <- html_nodes(pg, xpath=".//script[contains(., 'race.model')]") %>%  html_text()

ctx <- v8()
ctx$eval(JS(js))

race <- ctx$get("race", simplifyVector=FALSE)

str(race) ## output too large to paste here

如果他们改变了JavaScript的格式(这是一个自动化的过程,因此它不太可能,但你永远不知道),那么RSelenium方法会更好,只要他们不会这样做。 t改变表格结构的格式(再次,不太可能,但你永远不知道)。