R Language
Raspare e analizzare il Web
Ricerca…
Osservazioni
Scraping si riferisce all'uso di un computer per recuperare il codice di una pagina web. Una volta ottenuto il codice, deve essere analizzato in una forma utile per un ulteriore utilizzo in R.
Base R non ha molti strumenti necessari per questi processi, quindi lo scraping e l'analisi sono in genere eseguiti con i pacchetti. Alcuni pacchetti sono più utili per lo scraping ( RSelenium
, httr
, curl
, RCurl
), alcuni per l'analisi ( XML
, xml2
) e alcuni per entrambi ( rvest
).
Un processo correlato sta raschiando un'API Web, che a differenza di una pagina Web restituisce dati destinati a essere leggibili dalla macchina. Molti degli stessi pacchetti sono usati per entrambi.
Legalità
Alcuni siti Web obiettano di essere sottoposti a scraping, a causa di un aumento dei carichi del server o di preoccupazioni sulla proprietà dei dati. Se un sito web vieta di scrostare le Condizioni d'uso, raschiarle è illegale.
Raschiatura di base con rvest
rvest
è un pacchetto per scraping web e parsing di Hadley Wickham ispirato a Beautiful Soup di Python. xml2
i collegamenti libxml2
del pacchetto xml2
di Hadley per l'analisi HTML.
Come parte del tidyverse, rvest
viene convogliato . Utilizza
-
xml2::read_html
per raschiare l'HTML di una pagina web, - che può quindi essere sottoinsieme con le sue funzioni
html_node
ehtml_nodes
usando selettori CSS o XPath e - analizzato su oggetti R con funzioni come
html_text
ehtml_table
.
Per raschiare la tabella delle pietre miliari dalla pagina di Wikipedia su R , il codice sarebbe simile
library(rvest)
url <- 'https://en.wikipedia.org/wiki/R_(programming_language)'
# scrape HTML from website
url %>% read_html() %>%
# select HTML tag with class="wikitable"
html_node(css = '.wikitable') %>%
# parse table into data.frame
html_table() %>%
# trim for printing
dplyr::mutate(Description = substr(Description, 1, 70))
## Release Date Description
## 1 0.16 This is the last alpha version developed primarily by Ihaka
## 2 0.49 1997-04-23 This is the oldest source release which is currently availab
## 3 0.60 1997-12-05 R becomes an official part of the GNU Project. The code is h
## 4 0.65.1 1999-10-07 First versions of update.packages and install.packages funct
## 5 1.0 2000-02-29 Considered by its developers stable enough for production us
## 6 1.4 2001-12-19 S4 methods are introduced and the first version for Mac OS X
## 7 2.0 2004-10-04 Introduced lazy loading, which enables fast loading of data
## 8 2.1 2005-04-18 Support for UTF-8 encoding, and the beginnings of internatio
## 9 2.11 2010-04-22 Support for Windows 64 bit systems.
## 10 2.13 2011-04-14 Adding a new compiler function that allows speeding up funct
## 11 2.14 2011-10-31 Added mandatory namespaces for packages. Added a new paralle
## 12 2.15 2012-03-30 New load balancing functions. Improved serialization speed f
## 13 3.0 2013-04-03 Support for numeric index values 231 and larger on 64 bit sy
Mentre questo restituisce un data.frame, si noti che, come è tipico per i dati raschiati, c'è ancora ulteriore pulizia dei dati da fare: qui, date di formattazione, inserimento di NA
e così via.
Si noti che i dati in un formato rettangolare meno coerente possono richiedere il looping o altri ulteriori munging per analizzare correttamente. Se il sito Web utilizza jQuery o altri mezzi per inserire contenuti, read_html
potrebbe non essere sufficiente per raschiare e un raschietto più robusto come RSelenium
potrebbe essere necessario.
Usare rvest quando è richiesto il login
Ho riscontrato un problema comune durante la rottamazione di un sito Web è come immettere un ID utente e una password per accedere a un sito Web.
In questo esempio che ho creato per tracciare le mie risposte pubblicate qui per impilare l'overflow. Il flusso generale è quello di accedere, andare a una pagina web raccogliere informazioni, aggiungerlo a un dataframe e quindi passare alla pagina successiva.
library(rvest)
#Address of the login webpage
login<-"https://stackoverflow.com/users/login?ssrc=head&returnurl=http%3a%2f%2fstackoverflow.com%2f"
#create a web session with the desired login address
pgsession<-html_session(login)
pgform<-html_form(pgsession)[[2]] #in this case the submit is the 2nd form
filled_form<-set_values(pgform, email="*****", password="*****")
submit_form(pgsession, filled_form)
#pre allocate the final results dataframe.
results<-data.frame()
#loop through all of the pages with the desired info
for (i in 1:5)
{
#base address of the pages to extract information from
url<-"http://stackoverflow.com/users/**********?tab=answers&sort=activity&page="
url<-paste0(url, i)
page<-jump_to(pgsession, url)
#collect info on the question votes and question title
summary<-html_nodes(page, "div .answer-summary")
question<-matrix(html_text(html_nodes(summary, "div"), trim=TRUE), ncol=2, byrow = TRUE)
#find date answered, hyperlink and whether it was accepted
dateans<-html_node(summary, "span") %>% html_attr("title")
hyperlink<-html_node(summary, "div a") %>% html_attr("href")
accepted<-html_node(summary, "div") %>% html_attr("class")
#create temp results then bind to final results
rtemp<-cbind(question, dateans, accepted, hyperlink)
results<-rbind(results, rtemp)
}
#Dataframe Clean-up
names(results)<-c("Votes", "Answer", "Date", "Accepted", "HyperLink")
results$Votes<-as.integer(as.character(results$Votes))
results$Accepted<-ifelse(results$Accepted=="answer-votes default", 0, 1)
Il loop in questo caso è limitato a sole 5 pagine, questo deve essere modificato per adattarsi alla tua applicazione. Ho sostituito i valori specifici dell'utente con ******, si spera che ciò fornisca una guida per il tuo problema.