【问题标题】:how to build a webscraper in R using readLines and grep?如何使用 readLines 和 grep 在 R 中构建网络爬虫?
【发布时间】:2011-12-18 23:21:18
【问题描述】:

我对 R 很陌生。我想编译一个 100 万字的报纸文章语料库。所以我正在尝试编写一个网络爬虫来检索报纸文章,例如监护人网站:http://www.guardian.co.uk/politics/2011/oct/31/nick-clegg-investment-new-jobs.

刮板旨在从一页开始,检索文章的正文,删除所有标签并将其保存到文本文件中。然后应该通过这个页面的链接进入下一篇文章,获取文章等等,直到文件包含大约100万字。

不幸的是,我的刮刀没有走得太远。

我使用 readLines() 来获取网站的源代码,现在想获取代码中的相关行。

卫报中的相关版块使用这个id来标记文章的正文:

<div id="article-body-blocks">         
  <p>
    <a href="http://www.guardian.co.uk/politics/boris"
       title="More from guardian.co.uk on Boris Johnson">Boris Johnson</a>,
       the...a different approach."
  </p>
</div>

我尝试使用 grep 和lookbehind 的各种表达式来掌握本节 - 试图获取此 id 之后的行 - 但我认为它不适用于多行。至少我不能让它工作。

有人可以帮忙吗?如果有人能提供一些我可以继续工作的代码,那就太好了!

谢谢。

【问题讨论】:

  • 您不使用支持网络抓取的 R 包的任何特定原因,例如RCurl、XML 还是 scrapeR?参见例如 stackoverflow.com/q/5830705/602276stackoverflow.com/q/7501148/602276stackoverflow.com/q/3746256/602276stackoverflow.com/q/4882123/602276
  • 谢谢!嗯,是的,我也读过。这对我来说似乎更难 - 因为我对 R 还不是很好。所以我在这里找到了这个programmingr.com/content/webscraping-using-readlines-and-rcurl,看起来很容易使用。只是我网站的 HTML 有点复杂。
  • 您已经阅读了《卫报》的 T+C 对吧? “除非监护人明确授权,否则您不得以电子或纸质形式创建包含监护人网站上出现的全部或部分材料的数据库”。
  • @spacedman,是的,我阅读了他们的 T+C。但它们允许个人非商业用途:“您可以下载和打印 Guardian 内容的摘录,仅用于您自己的个人和非商业用途 [...]”。无论如何,我只是将网站用作构建刮板的“模板”。
  • 我认为“不创建数据库”规则会覆盖个人和非商业下载和打印规则,但是,律师不会追你的 :)

标签: r web-scraping


【解决方案1】:

如果你真的坚持使用grepreadLines,你将面临清理刮页的问题,但这当然可以做到。例如:

加载页面:

html <- readLines('http://www.guardian.co.uk/politics/2011/oct/31/nick-clegg-investment-new-jobs')

借助来自stringr 包的str_extract 和一个简单的正则表达式,您就完成了:

library(stringr)
body <- str_extract(paste(html, collapse='\n'), '<div id="article-body-blocks">.*</div>')

好吧,body 看起来很丑,你必须从&lt;p&gt; 和脚本中清理它。这可以通过gsub 和朋友(不错的正则表达式)来完成。例如:

gsub('<script(.*?)script>|<span(.*?)>|<div(.*?)>|</div>|</p>|<p(.*?)>|<a(.*?)>|\n|\t', '', body)

正如@Andrie 建议的那样,您应该为此目的使用一些构建包。小演示:

library(XML)
library(RCurl)
webpage <- getURL('http://www.guardian.co.uk/politics/2011/oct/31/nick-clegg-investment-new-jobs')
webpage <- readLines(tc <- textConnection(webpage)); close(tc)
pagetree <- htmlTreeParse(webpage, useInternalNodes = TRUE, encoding='UTF-8')
body <- xpathSApply(pagetree, "//div[@id='article-body-blocks']/p", xmlValue)

body 生成干净的文本:

> str(body)
 chr [1:33] "The deputy prime minister, Nick Clegg, has said the government's regional growth fund will provide a \"snowball effect that cre"| __truncated__ ...

更新:以上为单行(感谢@Martin Morgan 的建议):

xpathSApply(htmlTreeParse('http://www.guardian.co.uk/politics/2011/oct/31/nick-clegg-investment-new-jobs', useInternalNodes = TRUE, encoding='UTF-8'), "//div[@id='article-body-blocks']/p", xmlValue)

【讨论】:

  • +1 htmlTreeParsexpathSApply 的力量很好的例证
  • 不需要 RCurl / getURL / readLines / textConnection; htmlTreeParse 读取网址。
  • 非常感谢您的帮助 daroczig!你们所有人,真的。这很棒!将着手处理它,并希望自己管理我的刮板的最后步骤。
  • 谢谢@MartinMorgan,这让事情变得简单多了,我将不得不更新我的脚本:) 我现在根据你的建议编辑了我的答案。
  • 这个question 到了重点,不应该使用正则表达式来解析 HTML 文档。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-09
  • 1970-01-01
  • 2021-05-26
  • 1970-01-01
相关资源
最近更新 更多