Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/85.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用javascript实现web抓取_Javascript_Html_Css_R_Rvest - Fatal编程技术网

用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")
    
    库(rvest)
    url%
    读取html()%>%
    html#U节点(“轮询平均图”)
    
    没有多少成功。输出结果非常简单

    {xml_nodeset(1)}

    [1] \n

  • 以点为单位的个人投票结果显示在
    ,您可以在其中看到编号为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))