Как написать код для обхода веб-страниц и очистки в R

#r #web #screen-scraping #web-crawler

#r #веб #очистка экрана #веб-сканер

Вопрос:

Я пытаюсь написать код, который будет переходить на каждую страницу и брать оттуда информацию. URL <-http://www.wikiart.org/en/claude-monet/mode/all-paintings-by-alphabet

У меня есть код для вывода всех hrefs. Но это не работает.

 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)
  

После того, как у меня будет список URL-адресов всех изображений на этой странице, я хочу перейти на вторую-третью- …-23 страницы, чтобы собрать URL-адреса всех изображений.

Следующий шаг — удалить информацию о каждом изображении. У меня есть рабочий код для одного, и мне нужно собрать его в один общий код.

 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
  

Каждый совет, как это сделать, будет оценен по достоинству!

Ответ №1:

Кажется, это работает.

 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 в порядке; одна проблема заключается в том, что не все изображения содержат всю информацию (например, для некоторых страниц наборы узлов, к которым вы пытаетесь получить доступ, пусты) — обратите внимание на дату для «Ветряная мельница над Заандамом». Таким образом, код должен учитывать эту возможность.

Итак, в этом примере первый цикл захватывает значения атрибута href тегов привязки для каждой страницы (1: 23) и объединяет их в вектор длиной ~ 1300.

Для обработки каждой из этих 1300 страниц, и поскольку нам приходится иметь дело с отсутствующими тегами, проще создать вектор, содержащий строки XPath, и применить его по элементам к каждой странице. Это то, что делает функция get.picture(...) . Последний оператор вызывает эту функцию с каждой из 1300 hrefs и связывает результат по строкам, используя do.call(rbind,...) .

Обратите также внимание, что в этом коде используется несколько более компактная функция индексирования для объектов класса HTMLInternalDocument:, doc[xpath] где xpath — строка XPath. Это позволяет избежать использования xpathSApply(...) , хотя последнее сработало бы.

Ответ №2:

Вы можете попробовать пакет Rcrawler, это параллельный веб-скребок, он может сканировать, сохранять веб-страницы и очищать их содержимое с помощью XPath.

Если вам нужно собрать всю информацию о изображениях, используйте

 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 )
  

Чтобы отфильтровать только изображение Клода Моне

 Rcrawler(Website = "https://www.wikiart.org/", no_cores = 4, no_conn = 4, urlregexfilter ="claude-monet/([^/])*", ExtractPatterns =datapattern )
  

Для завершения работы сканера потребуется некоторое время, поскольку он будет проходить по всем ссылкам на веб-сайт. Однако вы можете остановить выполнение в любое время. По умолчанию очищенные данные находятся в глобальной переменной с именем DATA, другая переменная, называемая INDEX, содержит все просмотренные URL-адреса.

Если вам нужно узнать, как создать свой поисковый робот, обратитесь к этой статье.R crawler