用javascript实现web抓取
我试图从使用用javascript实现web抓取,javascript,html,css,r,rvest,Javascript,Html,Css,R,Rvest,我试图从使用rvest中获取每日预测,但我感兴趣的对象似乎是一个javascript对象,我甚至很难找到要查找的位置和内容。(我不太精通CSS或Javascript,尽管我在过去几天里努力自学。) 通过检查网页元素和CSS选择器,我得出以下结论: 要查看的位置是,所以我尝试了 library(rvest) url <- "https://projects.fivethirtyeight.com/election-2016/national-primary-polls/democra
rvest
中获取每日预测,但我感兴趣的对象似乎是一个javascript对象,我甚至很难找到要查找的位置和内容。(我不太精通CSS或Javascript,尽管我在过去几天里努力自学。)
通过检查网页元素和CSS选择器,我得出以下结论:
- 要查看的位置是
,所以我尝试了library(rvest) url <- "https://projects.fivethirtyeight.com/election-2016/national-primary-polls/democratic/" url %>% read_html() %>% html_nodes("#polling-avg-chart")
没有多少成功。输出结果非常简单 {xml_nodeset(1)} [1] \n库(rvest) url% 读取html()%>% html#U节点(“轮询平均图”)
- 以点为单位的个人投票结果显示在
代码>,您可以在其中看到编号为502的位置。我猜我必须将每个节点的
和cx
转换为适当的百分比,这是由cy
等完成的..
- 然而,我看不到预测线的基本数据,也看不到点
- 当我将光标悬停在图表上时,我会看到诸如
之类的变化,以及诸如
之类的值的变化,我猜这些值就是创建每日预测行的原因 - 但这些值存储在哪里,以及如何将其转换回“49.1%的克林顿对26.6%的桑德斯”之类的东西,对我来说仍然是个谜
我确实读过一些其他的SO帖子,比如,但似乎没有一篇适合这个特殊问题。在整洁的数据框架中获取预测百分比的最佳方法是什么?那里的图表几乎肯定是用d3.js或包装器构建的。d3非常适合构建基于svg的数据可视化,因为它可以帮助您构建比例,将值(例如40%)映射到屏幕上的位置(例如您看到的内容,例如
cx=100
)。问题是您需要知道这些比例是什么,以便恢复底层数据,并且这些比例可能是动态的,并且根据屏幕大小等而变化
相反,由于数据在下表中,您可以轻松地将其删除。该表位于ID为latest polls
的div
元素中,并且具有类t-polls
我正在使用带有CSS选择器的html\u节点
,html\u表
将表转换为数据帧,清理名称,并将数字列转换为实际的数字列。接下来你还可以做更多的事情,比如格式化日期,但希望这能让你开始
library(tidyverse)
library(rvest)
url <- "https://projects.fivethirtyeight.com/election-2016/national-primary-polls/democratic/"
polls_df <- url %>%
read_html() %>%
html_node("#latest-polls table.t-polls") %>%
html_table() %>%
setNames(c("new", "date", "pollster", "sample_n", "sample_type", names(.)[6:10]) %>% str_remove_all("\\W")) %>%
mutate_at(vars(sample_n, Clinton, Sanders, OMalley),
function(x) str_remove_all(x, "\\D") %>% as.numeric())
head(polls_df)
#> new date pollster sample_n sample_type
#> 1 • Jun. 10-13 Selzer & Co. 486 LV
#> 2 • Jun. 26-28 Fox News 432 RV
#> 3 • Jun. 18-20 YouGov 390 LV
#> 4 • Jun. 15-20 Morning Consult 1733 RV
#> 5 • Jun. 27-Jul. 1 Ipsos, online 142 LV
#> 6 • Jun. 16-19 Opinion Research Corporation 435 RV
#> weight leader Clinton Sanders OMalley
#> 1 1.05 Clinton +2 45 43 NA
#> 2 0.91 Clinton +21 58 37 NA
#> 3 0.79 Clinton +13 55 42 NA
#> 4 0.79 Clinton +18 53 35 NA
#> 5 0.67 Clinton +41 70 29 NA
#> 6 0.66 Clinton +12 55 43 NA
库(tidyverse)
图书馆(rvest)
url%
html#U节点(“#最新轮询表.t-polls”)%>%
html_表()%>%
集合名称(c(“新建”、“日期”、“轮询器”、“样本n”、“样本类型”、名称(.)[6:10])%%>%str\u删除所有(\\W”))%%>%
变异(VAR(样本n、克林顿、桑德斯、奥马利),
函数(x)str_remove_all(x,“\\D”)%%>%as.numeric())
总目(民调及测向)
#>新的日期轮询器样本\u n样本\u类型
#>1•2013年6月10日至13日Selzer&Co.486 LV
#>2•6月26日至28日福克斯新闻432 RV
#>3•6月18日至20日YouGov 390 LV
#>4•6月15日至20日上午咨询1733 RV
#>5•6月27日至7月1日益普索,在线142 LV
#>6•6月16日至19日意见研究公司435 RV
#>举重领袖克林顿·桑德斯·奥马利
#>1 1.05克林顿+2 45 43北美
#>20.91克林顿+2158 37 NA
#>30.79克林顿+135542北美
#>40.79克林顿+18 53 35 NA
#>5 0.67克林顿+41 70 29 NA
#>6 0.66克林顿+12 55 43北美
另一种方法是直接获取资源
在您的浏览器中,打开开发者工具(Chrome/Chrome中的F12),进入“网络”,刷新(F5),然后查找格式良好的JSON。找到后,我们复制链接地址(右键单击资源>复制链接地址)
复制图形:
dat %>%
filter(candidate_name %in% c("Clinton", "Kasich", "Sanders", "Trump")) %>%
ggplot(aes(forecastdate, poll_avg)) +
geom_line(aes(col = candidate_name)) +
facet_wrap(~party)
如果您想要互动性:
library(dygraphs)
library(htmltools)
foo <- dat %>%
filter(candidate_name %in% c("Clinton", "Kasich", "Sanders", "Trump")) %>%
split(.$party) %>%
map(~ {
select(.x, forecastdate, candidate_name, poll_avg) %>%
spread(candidate_name, poll_avg) %>%
{xts(.[-1], .[[1]])} %>%
dygraph(group = "poll-model") %>%
dyRangeSelector()
})
browsable(tagList(foo))
库(动态图)
图书馆(htmltools)
富%
筛选(候选人姓名%c(“克林顿”、“卡西奇”、“桑德斯”、“特朗普”))%>%
拆分(.$方)%>%
地图(~{
选择(.x,预测日期,候选人姓名,投票平均值)%>%
价差(候选人姓名、投票平均值)%>%
{xts(.[1],[1]])}%>%
动态图表(group=“poll model”)%>%
动态范围选择器()
})
可浏览(标记列表(foo))
我明白了。。。真可惜。问题是,FiveThirtyEight使用他们自己的模型从这些数据点估计预测,这不是数据的简单平均值。虽然您的解决方案更加优雅,但我已经收集了基本的民意调查数据。非常好!谢谢你,这是救命恩人。有一件事,我似乎在bind_rows(x,.id)中得到了
错误:参数1是一个列表,必须在第二个代码块的bind_rows
部分包含原子向量。@Kim你的包版本(“dplyr”)是什么?我使用0.7.4
.Hmm,同样的0.7.4
。实际上,它是带有map
函数的,因为在bind_rows
之前的第三行,dat
最后是一个空列表(NULL)——这不是应该的,对吗<代码>purrr
版本为0.2.4。我的意思是我可以解决它,但我只是想知道为什么我会得到一个不同的结果。哈!在rvest
中有一个pluck
。您是否碰巧在purr
之后加载了rvest
?那地图(purrr::purch,“model”)
呢?啊,的确,那是罪魁祸首。不管怎样,谢谢你的回答。从现在起,我将能够应用同样的原则。
dat %>%
filter(candidate_name %in% c("Clinton", "Kasich", "Sanders", "Trump")) %>%
ggplot(aes(forecastdate, poll_avg)) +
geom_line(aes(col = candidate_name)) +
facet_wrap(~party)
library(dygraphs)
library(htmltools)
foo <- dat %>%
filter(candidate_name %in% c("Clinton", "Kasich", "Sanders", "Trump")) %>%
split(.$party) %>%
map(~ {
select(.x, forecastdate, candidate_name, poll_avg) %>%
spread(candidate_name, poll_avg) %>%
{xts(.[-1], .[[1]])} %>%
dygraph(group = "poll-model") %>%
dyRangeSelector()
})
browsable(tagList(foo))