如何使用readLines和grep在R中构建webscraper?

Kat*_*Kat 5 r web-scraping

我是R的新手.我想编写一份100万字的报纸文章.所以我想写一个网络刮刀从例如监护人的网站上检索报纸上的文章:http://www.guardian.co.uk/politics/2011/oct/31/nick-clegg-investment-new-jobs.

刮刀用于从一页开始,检索文章的正文,删除所有标签并将其保存到文本文件中.然后它应该通过本页面上的链接转到下一篇文章,获取文章等,直到该文件包含大约100万字.

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

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

Guardian中的相关部分使用此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>
Run Code Online (Sandbox Code Playgroud)

我尝试使用grep和lookbehind的各种表达式来掌握这一部分 - 尝试获取此ID后面的行 - 但我认为它不适用于多行.至少我不能让它发挥作用.

有人可以帮忙吗?如果有人可以提供一些我可以继续工作的代码,那将是很棒的!

谢谢.

dar*_*zig 14

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

加载页面:

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

str_extractstringr包和简单正则表达式的帮助下,您完成了:

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

嗯,body看起来很难看,你也必须从<p>脚本和脚本中清理它.这可以gsub和朋友一起完成(好的正则表达式).例如:

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

正如@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)
Run Code Online (Sandbox Code Playgroud)

在哪里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__ ...
Run Code Online (Sandbox Code Playgroud)

更新:以上作为单行(感谢@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)
Run Code Online (Sandbox Code Playgroud)

  • 不需要RCurl/getURL/readLines/textConnection; `htmlTreeParse`读取网址. (2认同)