2009-09-08 8 views
129

मैं XML पैकेज का उपयोग करके HTML टेबल को कैसे स्क्रैप करूं?एक्सएमएल पैकेज का उपयोग कर आर डेटा फ्रेम में एचटीएमएल टेबल स्क्रैप करना

उदाहरण के लिए, Brazilian soccer team पर यह विकिपीडिया पृष्ठ लें। मैं इसे आर में पढ़ना चाहता हूं और डेटा के फ्रेम के रूप में "फीफा मान्यता प्राप्त टीमों के खिलाफ ब्राजील के सभी मैचों की सूची" तालिका प्राप्त कर सकता हूं। मैं यह कैसे कर सकता हूँ? जोड़ने के लिए

+9

एक्सपैथ चयनकर्ताओं को काम करने के लिए, selectorgadget.com/ देखें - यह शानदार है – hadley

उत्तर

122

... या एक छोटी कोशिश:

library(XML) 
library(RCurl) 
library(rlist) 
theurl <- getURL("https://en.wikipedia.org/wiki/Brazil_national_football_team",.opts = list(ssl.verifypeer = FALSE)) 
tables <- readHTMLTable(theurl) 
tables <- list.clean(tables, fun = is.null, recursive = FALSE) 
n.rows <- unlist(lapply(tables, function(t) dim(t)[1])) 

उठाया तालिका पेज

tables[[which.max(n.rows)]] 
+0

readHTMLTable सहायता HTMLParse(), getNodeSet(), textConnection() और read.table() –

46
library(RCurl) 
library(XML) 

# Download page using RCurl 
# You may need to set proxy details, etc., in the call to getURL 
theurl <- "http://en.wikipedia.org/wiki/Brazil_national_football_team" 
webpage <- getURL(theurl) 
# Process escape characters 
webpage <- readLines(tc <- textConnection(webpage)); close(tc) 

# Parse the html tree, ignoring errors on the page 
pagetree <- htmlTreeParse(webpage, error=function(...){}) 

# Navigate your way through the tree. It may be possible to do this more efficiently using getNodeSet 
body <- pagetree$children$html$children$body 
divbodyContent <- body$children$div$children[[1]]$children$div$children[[4]] 
tables <- divbodyContent$children[names(divbodyContent)=="table"] 

#In this case, the required table is the only one with class "wikitable sortable" 
tableclasses <- sapply(tables, function(x) x$attributes["class"]) 
thetable <- tables[which(tableclasses=="wikitable sortable")]$table 

#Get columns headers 
headers <- thetable$children[[1]]$children 
columnnames <- unname(sapply(headers, function(x) x$children$text$value)) 

# Get rows from table 
content <- c() 
for(i in 2:length(thetable$children)) 
{ 
    tablerow <- thetable$children[[i]]$children 
    opponent <- tablerow[[1]]$children[[2]]$children$text$value 
    others <- unname(sapply(tablerow[-1], function(x) x$children$text$value)) 
    content <- rbind(content, c(opponent, others)) 
} 

# Convert to data frame 
colnames(content) <- columnnames 
as.data.frame(content) 

संपादित:

नमूना उत्पादन

     Opponent Played Won Drawn Lost Goals for Goals against  % Won 
    1    Argentina  94 36 24 34  148   150 38.3% 
    2    Paraguay  72 44 17 11  160   61 61.1% 
    3     Uruguay  72 33 19 20  127   93 45.8% 
    ... 
+7

किसी और के लिए जो इस पोस्ट को खोजने के लिए भाग्यशाली है, यह स्क्रिप्ट तब तक निष्पादित नहीं होगी जब तक कि उपयोगकर्ता अपना "उपयोगकर्ता-एजेंट" जानकारी नहीं जोड़ता, जैसा कि इस अन्य सहायक पोस्ट में वर्णित है: http://stackoverflow.com/questions/9056705/setting-an-informative-user-agent-string-in-geturl – Rguy

23

XPath का उपयोग कर एक अन्य विकल्प।

library(RCurl) 
library(XML) 

theurl <- "http://en.wikipedia.org/wiki/Brazil_national_football_team" 
webpage <- getURL(theurl) 
webpage <- readLines(tc <- textConnection(webpage)); close(tc) 

pagetree <- htmlTreeParse(webpage, error=function(...){}, useInternalNodes = TRUE) 

# Extract table header and contents 
tablehead <- xpathSApply(pagetree, "//*/table[@class='wikitable sortable']/tr/th", xmlValue) 
results <- xpathSApply(pagetree, "//*/table[@class='wikitable sortable']/tr/td", xmlValue) 

# Convert character vector to dataframe 
content <- as.data.frame(matrix(results, ncol = 8, byrow = TRUE)) 

# Clean up the results 
content[,1] <- gsub(" ", "", content[,1]) 
tablehead <- gsub(" ", "", tablehead) 
names(content) <- tablehead 

इस परिणाम का उत्पादन

> head(content) 
    Opponent Played Won Drawn Lost Goals for Goals against % Won 
1 Argentina  94 36 24 34  148   150 38.3% 
2 Paraguay  72 44 17 11  160   61 61.1% 
3 Uruguay  72 33 19 20  127   93 45.8% 
4  Chile  64 45 12 7  147   53 70.3% 
5  Peru  39 27  9 3  83   27 69.2% 
6 Mexico  36 21  6 9  69   34 58.3% 
+0

xpath का उपयोग करने पर उत्कृष्ट कॉल। मामूली बिंदु: // // // // // को बदलकर आप पथ तर्क को थोड़ा सा सरल बना सकते हैं। "// टेबल [@ class = 'wikitable sortable']/tr/th" –

+0

मुझे एक त्रुटि मिलती है "स्क्रिप्ट्स को सूचना जानकारी के साथ एक सूचनात्मक उपयोगकर्ता-एजेंट स्ट्रिंग का उपयोग करना चाहिए, या वे बिना किसी सूचना के आईपी अवरुद्ध हो सकते हैं।" [2] "क्या इस विधि को लागू करने के लिए इस तरह का कोई तरीका है? – pssguy

+2

विकल्प (RCurlOptions = list (useragent =" zzzz "))। Http://www.omegahat.org/RCurl/FAQ.html अनुभाग भी देखें" रनटाइम "अन्य विकल्पों और चर्चाओं के लिए। – learnr

14

साथ rvest पर सबसे लंबे समय तक एक है xml2 के साथ htm पार्सिंग के लिए एक और लोकप्रिय पैकेज है एल वेब पेज।

library(rvest) 
theurl <- "http://en.wikipedia.org/wiki/Brazil_national_football_team" 
file<-read_html(theurl) 
tables<-html_nodes(file, "table") 
table1 <- html_table(tables[4], fill = TRUE) 

वाक्य रचना एक्सएमएल पैकेज से और वेब पेज या एक्सएमएल कोड विकल्प लोगों की जरूरत के सभी प्रदान करता है अधिकांश के लिए उपयोग करने के लिए आसान है।

+0

का उपयोग करते हुए एक HTML PRE तत्व से एक सादा पाठ तालिका पढ़ने का एक उदाहरण भी प्रदान करता है read_html देता है मुझे त्रुटि "'फ़ाइल: ///Users/grieb/Auswertungen/tetyana-snp-2016/data/snp-nexus/15/SNP%20Annotation%20Tool.html' वर्तमान कार्यशील निर्देशिका में मौजूद नहीं है ('/ उपयोगकर्ता/grieb/Auswertungen/तेत्याना-एसएनपी-2016/कोड ')। " – scs

संबंधित मुद्दे