2009-09-08 27 views
129

Làm cách nào để loại bỏ các bảng html bằng gói XML?Nạo các bảng html vào các khung dữ liệu R bằng gói XML

Lấy, ví dụ: trang wikipedia này trên Brazilian soccer team. Tôi muốn đọc nó trong R và nhận được "danh sách của tất cả các trận đấu Brazil đã chơi với các đội được công nhận FIFA" bảng dưới dạng data.frame. Tôi có thể làm cái này như thế nào?

+9

Để tìm ra bộ chọn xpath, hãy kiểm tra selectorgadget.com/ - thật tuyệt vời – hadley

Trả lời

122

... hoặc thử ngắn hơn:

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])) 

bảng chọn là một trong những lâu nhất trên trang

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

Trợ giúp đọcHTMLTable cũng cung cấp một ví dụ về việc đọc một bảng văn bản thuần túy trong phần tử PRE HTML bằng cách sử dụng htmlParse(), getNodeSet(), textConnection() và 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) 

Edited thêm:

Mẫu đầu ra

     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

Đối với bất kỳ ai may mắn tìm thấy bài đăng này, tập lệnh này có thể sẽ không thực thi trừ khi người dùng thêm thông tin "Tác nhân người dùng" của họ, như được mô tả trong bài đăng hữu ích khác này: http://stackoverflow.com/questions/9056705/setting-an-informative-user-agent-string-in-geturl – Rguy

23

Một tùy chọn sử dụng 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 

Tạo kết quả này

> 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

Tuyệt vời gọi bằng cách sử dụng xpath. Điểm nhỏ: bạn có thể đơn giản hóa đối số đường dẫn bằng cách thay đổi // */thành //, ví dụ: "// table [@ class = 'wikitable sortable']/tr/th" –

+0

Tôi gặp lỗi "Tập lệnh nên sử dụng chuỗi User-Agent thông tin có thông tin liên hệ hoặc có thể bị chặn IP mà không cần thông báo". [2] "Có cách nào để thực hiện phương pháp này không? – pssguy

+2

tùy chọn (RCurlOptions = list (useragent =" zzzz ")). Xem thêm http://www.omegahat.org/RCurl/FAQ.html phần" – learnr

14

Các rvest cùng với xml2 là một gói phổ biến khác để phân tích cú pháp htm l trang web.

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) 

Cú pháp dễ sử dụng hơn gói xml và cho hầu hết các trang web hoặc mã xml cung cấp tất cả các tùy chọn cần.

+0

Read_html cung cấp cho tôi lỗi "'tệp: ///Users/grieb/Auswertungen/tetyana-snp-2016/data/snp-nexus/15/SNP%20Annotation%20Tool.html' không tồn tại trong thư mục làm việc hiện tại ('/ Users/grieb/Auswertungen/tetyana-snp-2016/code '). " – scs

Các vấn đề liên quan