【问题标题】:How to scrape with rvest?如何用rvest刮?
【发布时间】:2017-09-23 22:08:42
【问题描述】:

我需要从这个页面获取三个不同的数字(黄色,见图):

https://www.scopus.com/authid/detail.uri?authorId=7006040753

我通过rvestinspectorgadget 使用了这段代码:

site=read_html("https://www.scopus.com/authid/detail.uri?authorId=7006040753") 
hindex=site %>% html_node(".row3 .valueColumn span")%>% html_text()
documents=site %>% html_node("#docCntLnk")%>% html_text()
citations=site %>% html_node("#totalCiteCount")%>% html_text()
print(citations)

我可以得到 h-indexdocuments 但引用不起作用

你能帮帮我吗?

【问题讨论】:

  • 乍一看像是一个快速修复,但这个值似乎是动态加载的(如果你查看源代码,你会注意到数字没有出现在任何地方)意味着你会首先必须使用例如呈现网站PhantomJS 或 RSelenium,然后使用 rvest 下载/处理网站
  • 我刚刚尝试了 PhantomJS 并且在这里也遇到了问题,因为页面处理似乎被阻止了。所以宁愿使用RSelenium(不幸的是我对此一无所知)或者可能使用文档的数量而不是可以更容易抓取的总引用(并且更有意义,因为它更重要的是有多少文件被引用和不是每个文档的频率)
  • 您好 TomS,感谢您的评论...“如果您查看源代码,您会注意到数字没有出现在任何地方”是什么意思。实际上在 html 源代码中我找到了<input type="hidden" name="ctoCount" value="51971"><span id="totalCiteCount">51971</span>
  • 对不起,我有点不准确。如果您使用右键单击 -> 显示页面源代码(而不是例如浏览器的“检查元素”功能),它看起来像这样:<span id="totalCiteCount"></span> 这也是您在使用 PhantomJS 打开和下载页面时得到的结果 =>页面未呈现。此外,如果您刮取父节点div class="valueColumn" data-citedbythreshold="false">,您将获得除所需值之外的整行
  • 嗨 Guglielmo,相关问题:您有没有找到一种方法来获取所有现有 Scopus 作者 ID 的列表?我注意到他们使用了多达 11 个看似随机的数字,因此仅抓取所有数字(990 亿页)似乎非常低效/不可能,但我在任何地方都找不到完整的列表......谢谢!

标签: web-scraping rvest


【解决方案1】:

现在我找到了一个解决方案 - 我注意到该值需要一些时间才能加载,因此我在 PhnatomJS 脚本中加入了一点超时。现在它可以在我的机器上使用以下 R 代码:

setwd("path/to/phantomjs/bin")
system('phantomjs readexample.js') # call PhantomJS script (stored in phantomjs/bin)

totalCiteCount <- "rendered_page.html" %>% # "rendered_page.html" is created by PhantomJS
   read_html() %>%
   html_nodes("#totalCiteCount") %>%
   html_text()

## totalCiteCount
## [1] "52018"

对应的 PhantomJS 脚本文件“readexample.js”如下所示(感谢https://www.r-bloggers.com/web-scraping-javascript-rendered-sites/):

var webPage = require('webpage');
var url ='https://www.scopus.com/authid/detail.uri?authorId=7006040753';
var fs = require('fs'); 
var page = webPage.create();
var system = require('system');

page.settings.userAgent = 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)';

page.open(url, function (status) {
        setTimeout(function() {
               fs.write('rendered_page.html', page.content, 'w');
            phantom.exit();
    }, 2500);
});

代码在 R 中抛出以下错误,但至少该值被正确抓取。

> system('phantomjs readexample.js') TypeError: undefined is not a constructor (evaluating 'mutation.addedNodes.forEach')

  https://www.scopus.com/gzip_N1846232499/bundles/SiteCatalystTop.js:73  :0 in forEach   https://www.scopus.com/gzip_N1846232499/bundles/SiteCatalystTop.js:73 ReferenceError: Can't find variable: SDM

  https://www.scopus.com/gzip_N1729184664/bundles/AuthorProfileTop.js:73 in sendIndex   https://www.scopus.com/gzip_N1729184664/bundles/AuthorProfileTop.js:67 in loadEvents

使用 PhantomJS 非常方便,因为您无需安装任何东西(如果您的机器上没有管理员权限,也可以使用)。只需download .zip 文件并将其解压缩到任何文件夹。然后将R中的工作目录(setwd())设置为“phantomjs/bin”文件夹,它就可以工作了。

您还可以更改 R 中的 PhantomJS 脚本(如果需要,可以迭代),例如在循环中将不同的 URL 传递给脚本。示例:

for (i in 1:n_urls) {

   url_var <- urls[i] # assuming you have created a var "urls" with multiple URLs before
   lines <- readLines("readexample.js")
   lines[2] <- paste0("var url ='", url_var ,"';") # exchange code line with new URL
   writeLines(lines, "readexample.js") # new url is stored in the PhantomJS script

   system('phantomjs readexample.js')

   # <any code> #

} 

希望这能让你更进一步?

【讨论】:

  • 伟大的汤姆斯!我会尝试您的解决方案...谢谢。
  • 超级!!!!尝试了迭代......它工作得很好!非常感谢汤姆!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-22
  • 2018-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多