Как очистить несколько страниц с помощью XML и ReadHTMLTable? - PullRequest
3 голосов
/ 15 октября 2011

Я использую пакет XML, чтобы собрать результаты Чикагского марафона в CSV. Проблема в том, что сайт может отображать только 1000 бегунов на одной странице, поэтому мне приходится очищать несколько страниц. Сценарий, который я написал до сих пор, работает для первой страницы:

rm(list=ls())

library(XML)

page_numbers <- 1:1429
urls <- paste(
"http://results.public.chicagomarathon.com/2011/index.php?page", 
page_numbers, 
sep = "="
)

tables <-(for i in page_numbers){
readHTMLTable(urls)
}
n.rows <- unlist(lapply(tables, function(t) dim(t)[1]))

times <- tables[[which.max(n.rows)]]

Как я могу использовать этот код для очистки всех 21 страниц, чтобы получить полные результаты. Должен ли я использовать цикл for() или функцию lapply или что-то еще, я немного растерялся.

Спасибо!

Ответы [ 2 ]

3 голосов
/ 15 октября 2011

Добавьте номер страницы к каждому URL.

page_numbers <- 1:1429
urls <- paste(
  "http://results.public.chicagomarathon.com/2011/index.php?pid=list&page", 
  page_numbers, 
  sep = "="
)

Теперь переберите каждую страницу, очищая каждую. Не имеет большого значения, используете ли вы цикл for или функцию *apply. См., Например, Круг 4 R Inferno (pdf) для обсуждения разницы между циклами for и lapply.

2 голосов
/ 15 октября 2011

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

url1 = 'http://results.public.chicagomarathon.com/2011/index.php?page='
url3 = '&content=list&event=MAR&num_results=25'

# GET TABLE FROM PAGE NUMBER
getPage <- function(page){
  require(XML)
  url = paste(url1, page, url3, sep = "")
  tab = readHTMLTable(url, stringsAsFactors = FALSE)[[1]]
  return(tab)
}

require(plyr)
# for some reason ldply fails, hence the llply + rbind workaround
pages    = llply(1:10, getPage, .progress = 'text') 
marathon = do.call('rbind', pages)
...