Очистка трансфермаркета с помощью Rvest

#r #web-scraping #rvest

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

Вопрос:

У меня возникли проблемы с очисткой Transfermarket. Я хочу очистить данные для 5 лучших европейских лиг (премьер-лига, ла лига, серия а, лига 1, бундеслига) за последние 20 сезонов. В этом я хочу собрать ряд деталей — имя игрока, возраст, позиция игрока, клуб игрока, оставшийся клуб игрока, гонорар. Но даже с этим очень простым кодом, который я написал, чтобы очистить только одну страницу трансферов 18/19 премьер-лиги, собирая команды и названия (дополнения) Я получаю ошибку, которую я не понимаю. Я тоже использовал устройство выбора.

Мой код:

 require(rvest)

page = "https://www.transfermarkt.com/premier-league/transfers/wettbewerb/GB1/plus/?saison_id=2012amp;s_w=amp;leihe=0amp;leihe=1amp;intern=0"

scraped_page <- read_html(page)

Team_html  = html_nodes(page, ".tooltipstered  .tooltipstered") 
Team = html_text(Team_html)
Addition_html = html_nodes(page, ".table-header  .responsive-table .spielprofil_tooltip")
Addition = html_text(Addition_html)


df <- data.frame(Team, Addition)

head(df)
  

Что возвращает R:

 > page = "https://www.transfermarkt.com/premier-league/transfers/wettbewerb/GB1/plus/?saison_id=2012amp;s_w=amp;leihe=0amp;leihe=1amp;intern=0"
> 
> scraped_page <- read_html(page)
> 
> Team_html  = html_nodes(page, ".tooltipstered  .tooltipstered") 
Error in UseMethod("xml_find_all") : 
  no applicable method for 'xml_find_all' applied to an object of class "character"
> Team = html_text(Team_html)
> Addition_html = html_nodes(page, ".table-header  .responsive-table .spielprofil_tooltip")
Error in UseMethod("xml_find_all") : 
  no applicable method for 'xml_find_all' applied to an object of class "character"
> Addition = html_text(Addition_html)
> 
> 
> df <- data.frame(Team, Addition)
Error in data.frame(Team, Addition) : 
  arguments imply differing number of rows: 0, 922
> 
> head(df)

1 function (x, df1, df2, ncp, log = FALSE)    
2 {                                           
3     if (missing(ncp))                       
4         .Call(C_df, x, df1, df2, log)       
5     else .Call(C_dnf, x, df1, df2, ncp, log)
6 }                     
  

Я думал начать здесь, а затем использовать gsub и некоторые другие команды, чтобы в цикле перебирать годы и лиги…

Ответ №1:

Основная проблема, с которой вы сталкиваетесь, заключается в том, что

  Team_html  = html_nodes(page, ".tooltipstered  .tooltipstered") 
  

Должно быть

  Team_html  = html_nodes(scraped_page, ".tooltipstered  .tooltipstered") 
  

Кроме того, я не думаю, что вы правильно указали селектор. Я думаю, вы могли бы захотеть сделать что-то подобное вместо этого…

Обновить

Потенциальное решение 1:

Очистите каждую таблицу отдельно по командам, они вручную добавляют названия команд, прежде чем вы сложите данные. В приведенном ниже коде я делаю это для первых 5 команд

 in1<-html_nodes(scraped_page, '#main > div:nth-child(13) > div.large-8.columns > div:nth-child(4) > div:nth-child(2) > table') %>% html_table()
in2<-html_nodes(scraped_page, '#main > div:nth-child(13) > div.large-8.columns > div:nth-child(5) > div:nth-child(2) > table') %>% html_table()
in3<-html_nodes(scraped_page, '#main > div:nth-child(13) > div.large-8.columns > div:nth-child(6) > div:nth-child(2) > table') %>% html_table()
in4<-html_nodes(scraped_page, '#main > div:nth-child(13) > div.large-8.columns > div:nth-child(7) > div:nth-child(2) > table') %>% html_table()
in5<-html_nodes(scraped_page, '#main > div:nth-child(13) > div.large-8.columns > div:nth-child(8) > div:nth-child(2) > table') %>% html_table()

out1<-html_nodes(scraped_page, '#main > div:nth-child(13) > div.large-8.columns > div:nth-child(4) > div:nth-child(4) > table') %>% html_table()
out2<-html_nodes(scraped_page, '#main > div:nth-child(13) > div.large-8.columns > div:nth-child(5) > div:nth-child(4) > table') %>% html_table()
out3<-html_nodes(scraped_page, '#main > div:nth-child(13) > div.large-8.columns > div:nth-child(6) > div:nth-child(4) > table') %>% html_table()
out4<-html_nodes(scraped_page, '#main > div:nth-child(13) > div.large-8.columns > div:nth-child(7) > div:nth-child(4) > table') %>% html_table()
out5<-html_nodes(scraped_page, '#main > div:nth-child(13) > div.large-8.columns > div:nth-child(8) > div:nth-child(4) > table') %>% html_table()

in1<-in1[[1]]
in2<-in2[[1]]
in3<-in3[[1]]
in4<-in4[[1]]
in5<-in5[[1]]

out1<-out1[[1]]
out2<-out2[[1]]
out3<-out3[[1]]
out4<-out4[[1]]
out5<-out5[[1]]

in1$team<-"Arsenal"
in2$team<-"Man U"
in3$team<-"West Brom"
in4$team<-"Fulham"
in5$team<-"New Castle"


out1$team<-"Arsenal"
out2$team<-"Man U"
out3$team<-"West Brom"
out4$team<-"Fulham"
out5$team<-"New Castle"


ins<-rbind(in1,in2,in3,in4,in5)
outs<-rbind(out1,out2,out3,out4,out5)
  

Потенциальное решение 2 :

Это решение не сохраняет названия команд, а объединяет их для более эффективной очистки.

 tab<-html_nodes(scraped_page, ".responsive-table td") %>% html_text()
temp<-data.frame(value=tab, index=index)
df<-data.frame(x1=character(981), x2=character(981), x3=character(981), x4=character(981), x5=character(981),
               x6=character(981),x7=character(981),x8=character(981),x9=character(981))
for (i in 1:9){
df[,i]<-temp$value[temp$index==i]

}
head(df)
  

Комментарии:

1. это действительно помогает, спасибо — но у меня все еще возникают проблемы с получением данных от всех команд, а не только от первой, поэтому изначально я думал, что сохранение ряда элементов, т. Е. Возраста, должности и т.д., Которые будут собраны в виде отдельных столбцов, Прежде чем быть помещенными в полный фрейм данных, сработает. Когда я исправил вышеупомянутые селекторы team и playername, я все еще получаю эту возвращаемую ошибку — Ошибка в data.frame (команда, дополнение): аргументы подразумевают разное количество строк: 0, 922.

2. Вы получаете эту ошибку, потому что команда пуста, я не вижу, что вы пытаетесь захватить, но селектор «.tooltipstered .tooltipstered» не работает.

3. Я пытаюсь захватить только названия команд, текст которых, похоже, изолирован этим

4. Если вы пытаетесь извлечь названия команд из заголовков таблицы, то даже если вы очистите название команды правильно, вы не сможете объединить их во фрейме данных, поскольку для каждой таблицы будет только одно значение. Вам нужно будет либо присвоить названия команд по таблице (как я делаю в потенциальном решении 1), либо вручную создать вектор названий команд и прикрепить их к вашему окончательному набору данных.