Найти ячейку в таблице html, содержащую определенный значок

Я ищу код, который может сообщить мне, в какой ячейке html-таблицы находится конкретный значок. Вот с чем я работаю:

u <- "http://www.transfermarkt.nl/lionel-messi/leistungsdaten/spieler/28003/saison/2014/plus/1"
doc <- rvest::html(u)
tab <- rvest::html_table(doc, fill = TRUE)[[6]]

Столбец «Пол.» обозначает положение игрока на поле. Некоторые из них имеют дополнительный значок. Я вижу наличие этих значков на странице следующим образом:

rvest::html_nodes(doc, ".kapitaenicon-table")

но это не говорит мне, ГДЕ они. Я хотел бы, чтобы мой код возвращал, что значок встречается в строках 2, 10, 11, 27 столбца «Позиция» в таблице. Как я могу это сделать?


person Peter Verbeet    schedule 31.05.2015    source источник


Ответы (1)


Еще немного магии rvest и XPath может дать вам индексы:

library(rvest)
library(magrittr)
library(XML)

pg <- html("http://www.transfermarkt.nl/lionel-messi/leistungsdaten/spieler/28003/saison/2014/plus/1")

pg %>% 
  html_nodes("table") %>% 
  extract2(6) %>% 
  html_nodes("tbody > tr") %>% 
  sapply(function(x) {
    length(xpathSApply(x, "./td[8]/span[@class='kapitaenicon-table icons_sprite']")) == 1
  }) %>% which

## [1]  2 10 11 27

Это получает 6-ю таблицу, извлекает trs, затем просматривает их для 8-й td с правильными span/class в ней. Если поиск XPath терпит неудачу, он возвращает пустой список, поэтому вы можете использовать длину, чтобы определить, в каких строках есть td со значком, а в каких нет.

Этот:

pg %>% 
  html_nodes(xpath="//table[6]/tbody/tr/td[8]") %>% 
  xmlSApply(xpathApply, "boolean(./span[@class='kapitaenicon-table icons_sprite'])") %>% 
  which

также работает, и это немного плотнее (и быстрее). Он использует операцию XPath boolean для проверки существования. Это удобно, если у вас нет других операций для выполнения на узле (узлах).

Это версия xml2, хотя я должен верить, что должен быть лучший способ сделать это в xml2:

library(xml2)
library(magrittr)

pg2 <- read_html("http://www.transfermarkt.nl/lionel-messi/leistungsdaten/spieler/28003/saison/2014/plus/1")
pg2 %>% 
  xml_find_all("//table[6]/tbody/tr/td[8]") %>% 
  as_list %>% 
  sapply(function(x) {
    inherits(try(xml_find_one(x, "./span"), silent=TRUE), "xml_node")
  }) %>% which

ОБНОВЛЕНИЕ

Для версии 0.1.0.9000 из xml2 мне пришлось сделать следующее:

pg2 %>% xml_find_all("//table") %>% 
  as_list %>% 
  extract2(6) %>% 
  xml_find_all("./tbody/tr/td[8]") %>% 
  as_list %>% 
  sapply(function(x) {
    inherits(try(xml_find_one(x, "./span"), silent=TRUE), "xml_node")
  }) %>% which

Этого не должно быть, и я отправил отчет об ошибке.

Session info -------------------------------------------------------------------------
 setting  value                       
 version  R version 3.2.0 (2015-04-16)
 system   x86_64, darwin13.4.0        
 ui       RStudio (0.99.441)          
 language (EN)                        
 collate  en_US.UTF-8                 
 tz       America/New_York            

Packages -----------------------------------------------------------------------------
 package    * version date       source        
 curl       * 0.5     2015-02-01 CRAN (R 3.2.0)
 devtools   * 1.7.0   2015-01-17 CRAN (R 3.2.0)
 magrittr     1.5     2014-11-22 CRAN (R 3.2.0)
 Rcpp       * 0.11.5  2015-03-06 CRAN (R 3.2.0)
 rstudioapi * 0.3.1   2015-04-07 CRAN (R 3.2.0)
 xml2         0.1.0   2015-04-20 CRAN (R 3.2.0)
person hrbrmstr    schedule 31.05.2015
comment
Потрясающие! Версия XML работает безупречно и очень поучительна. Однако что-то не так с решением xml2, оно возвращает ошибку (аргумент "который" нелогичен). Я думаю, что это может быть вызвано. pg2 %>% xml_find_all("//table[6]/tbody/tr/td[8]") возвращается {xml_nodeset (0)} Возможно где-то опечатка? - person Peter Verbeet; 31.05.2015
comment
Я добавил 2 вызова library к версии xml2, которую использовал, и повторно запустил код в чистой среде, и ошибок не было. Я добавил информацию о сеансе в ответ. - person hrbrmstr; 01.06.2015
comment
Это странно, я все еще получаю ту же ошибку, и pg2 %>% xml_find_all("//table[6]/tbody/tr/td[8]") все еще возвращает {xml_nodeset (0)} Это приводит к тому, что as.list затем возвращает list(). У меня та же версия R, что и у вас, версии пакетов также очень близки (идентичны или даже более поздние). Я использовал новый сеанс, чтобы убедиться, что на результат не повлияли другие объекты в моей среде. Вы уверены, что нигде нет опечатки? Это озадачивает... - person Peter Verbeet; 01.06.2015
comment
Это была версия 0.1.0.9000, которая вызывала проблему. Ответ обновлен и подача отчета об ошибке. - person hrbrmstr; 01.06.2015
comment
Спасибо, это решает! Это действительно странный код. Моя версия xml2 была 0.1.0.9000, так что это имеет смысл. Спасибо за помощь, я буду следить за решением этой ошибки. - person Peter Verbeet; 01.06.2015