首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在R中编写web爬行和抓取的代码

如何在R中编写web爬行和抓取的代码
EN

Stack Overflow用户
提问于 2014-07-04 22:59:25
回答 2查看 17.7K关注 0票数 6

我正在尝试编写代码,将转到每个页面,并从那里获取信息。Url <- http://www.wikiart.org/en/claude-monet/mode/all-paintings-by-alphabet

我有输出所有href的代码。但它不起作用。

代码语言:javascript
复制
library(XML)
library(RCurl)
library(stringr)
tagrecode <- readHTMLTable ("http://www.wikiart.org/en/claude-monet/mode/all-            paintings-by-alphabet")
tabla <- as.data.frame(tagrecode)
str(tabla)
names (tabla) <- c("name", "desc", "cat", "updated")
str(tabla)
res <- htmlParse ("http://www.wikiart.org/en/claude-monet/mode/all-paintings-by- alphabet")
enlaces <- getNodeSet (res, "//p[@class='pb5']/a/@href")
enlaces <- unlist(lapply(enlaces, as.character))
tabla$enlace <- paste("http://www.wikiart.org/en/claude-monet/mode/all-paintings-by- alphabet")
str(tabla)
lisurl <- tabla$enlace

fu1 <- function(url){
print(url)
pas1 <- htmlParse(url, useInternalNodes=T)

pas2 <- xpathSApply(pas1, "//p[@class='pb5']/a/@href")
}
urldef <- lapply(lisurl,fu1)

在我有了这个页面上所有图片的网址列表后,我想去第二-第三-...-23页收集所有图片的网址。

下一步-删除每一张图片的信息。我有一个可以工作的代码,我需要在一个通用代码中构建它。

代码语言:javascript
复制
library(XML)
url = "http://www.wikiart.org/en/claude-monet/camille-and-jean-monet-in-the-garden-at-argenteuil"
doc = htmlTreeParse(url, useInternalNodes=T)
pictureName <- xpathSApply(doc,"//h1[@itemprop='name']", xmlValue)
date <- xpathSApply(doc, "//span[@itemprop='dateCreated']", xmlValue)
author <- xpathSApply(doc, "//a[@itemprop='author']", xmlValue)
style <- xpathSApply(doc, "//span[@itemprop='style']", xmlValue)
genre <- xpathSApply(doc, "//span[@itemprop='genre']", xmlValue)

pictureName
date
author
style
genre

每一条如何做到这一点的建议都将受到感谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-07-05 01:19:22

这似乎是可行的。

代码语言:javascript
复制
library(XML)
library(httr)
url <- "http://www.wikiart.org/en/claude-monet/mode/all-paintings-by-alphabet/"
hrefs <- list()
for (i in 1:23) {
  response <- GET(paste0(url,i))
  doc      <- content(response,type="text/html")
  hrefs    <- c(hrefs,doc["//p[@class='pb5']/a/@href"])
}
url      <- "http://www.wikiart.org"
xPath    <- c(pictureName = "//h1[@itemprop='name']",
              date        = "//span[@itemprop='dateCreated']",
              author      = "//a[@itemprop='author']",
              style       = "//span[@itemprop='style']",
              genre       = "//span[@itemprop='genre']")
get.picture <- function(href) {
  response <- GET(paste0(url,href))
  doc      <- content(response,type="text/html")
  info     <- sapply(xPath,function(xp)ifelse(length(doc[xp])==0,NA,xmlValue(doc[xp][[1]])))
}
pictures <- do.call(rbind,lapply(hrefs,get.picture))
head(pictures)
#      pictureName                           date     author         style           genre           
# [1,] "A Corner of the Garden at Montgeron" "1877"   "Claude Monet" "Impressionism" "landscape"     
# [2,] "A Corner of the Studio"              "1861"   "Claude Monet" "Realism"       "self-portrait" 
# [3,] "A Farmyard in Normandy"              "c.1863" "Claude Monet" "Realism"       "landscape"     
# [4,] "A Windmill near Zaandam"             NA       "Claude Monet" "Impressionism" "landscape"     
# [5,] "A Woman Reading"                     "1872"   "Claude Monet" "Impressionism" "genre painting"
# [6,] "Adolphe Monet Reading in the Garden" "1866"   "Claude Monet" "Impressionism" "genre painting"

其实你们已经很接近了。你的xPath是好的;一个问题是,并不是所有的图片都有所有的信息(例如,对于你试图访问的一些页面的nodeSets是空的)-注意"A Windnill nead Zaandam“的日期。所以代码必须处理这种可能性。

因此,在本例中,第一个循环获取每个页面的锚标记的href属性值(1:23),并将这些值组合成一个长度约为1300的向量。

为了处理这1300个页面中的每一个,由于我们必须处理缺失的标记,因此创建一个包含xPath字符串的向量并将该元素逐个应用于每个页面更简单。这就是函数get.picture(...)所做的事情。最后一条语句使用1300个href调用此函数,并使用do.call(rbind,...)将结果逐行绑定在一起。

还要注意,这段代码对HTMLInternalDocument:doc[xpath]类的对象使用了更紧凑的索引特性,其中xpath是一个xPath字符串。这就避免了使用xpathSApply(...),尽管后者本可以工作。

票数 9
EN

Stack Overflow用户

发布于 2017-06-29 20:00:12

你可以试试Rcrawler package,它是一个并行的网络抓取器,它可以使用XPath抓取、存储网页和抓取内容。

如果您需要收集所有图片信息,请使用

代码语言:javascript
复制
datapattern<-c(
  "//h1/span[@itemprop='name']",
  "//a[@class='artist-name']",
  "//*[@id='headSection']/article/form/div[1]/div/div/div[2]/div[2]/span[2]",
  "//*[@id='headSection']/article/form/div[1]/div/div/div[2]/div[3]/a/span",
  "//*[@id='headSection']/article/form/div[1]/div/div/div[2]/div[4]/a/span"
)

Rcrawler(Website = "https://www.wikiart.org/", no_cores = 4, no_conn = 4, ExtractPatterns =datapattern )

只过滤掉Claud Monet图片

代码语言:javascript
复制
Rcrawler(Website = "https://www.wikiart.org/", no_cores = 4, no_conn = 4, urlregexfilter ="claude-monet/([^/])*", ExtractPatterns =datapattern )

爬虫需要一些时间才能完成,因为它将遍历所有网站链接。但是,您可以随时停止执行。默认情况下,scraped在一个全局变量中命名为DATA,另一个名为INDEX的变量包含所有抓取的URL。

如果你需要学习如何构建你的爬虫,请参考这篇文章。R crawler

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24576962

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档