rvest: вернуть NA для пустых узлов при нескольких листингах - PullRequest
0 голосов
/ 01 февраля 2019

Я довольно новичок в R (и использую его, в частности, для просмотра веб-страниц), поэтому любая помощь очень ценится.В настоящее время я пытаюсь создать веб-страницу, которая содержит несколько списков билетов и перечисляет дополнительную информацию по некоторым из них (например, билет с нарушенным видом или только для детей).Я хочу извлечь эти данные, оставляя пустые места или NA для списков билетов, которые не содержат эти детали.

Поскольку исходный сайт требует использования RSelenium, я попытался воспроизвести HTML в более простой форме.Если какая-либо информация отсутствует, пожалуйста, дайте мне знать, и я постараюсь предоставить ее.Спасибо!

До сих пор я пытался принять решения, представленные здесь: rvest отсутствующих узлов -> NA и htmlParse отсутствующих значений NA , но не в состоянии реплицироватьих для моего примера, поскольку я получаю сообщение об ошибке

Ошибка в UseMethod ("xml_find_all"): нет применимого метода для 'xml_find_all', примененного к объекту класса "персонаж"

Полагаю, мне нужно сочетание rvest и lapply, но я не могу заставить его работать.

library(XML)
library(rvest)

html <- '<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div class = "listing" id = "listing_1">
<em> 
<span class="listing_sub3">
Limited view
</span>
</em>
</div>
<div class = "listing" id = "listing_2">
<em> 
<span class="listing_sub2">
Other text I am not interested in
</span>
</em>
</div>
<div class = "listing" id = "listing_3">
<div>
<em> 
<span class="listing_sub3">
Limited view
</span>
</em>
</div>
<div>
<span class="listing_sub1">
Ticket for a child
</span>
</div>
</div>
</body>
</html>'


page_html <- read_html(html)
child <- html_nodes(page_html, xpath ="//*[@class='listing_sub1']") %>%
  html_text()
viewLim <- html_nodes(page_html, xpath ="//*[@class='listing_sub3']") %>%
  html_text()
id <- html_nodes(page_html, xpath = "//*[@class='listing']") %>% 
  html_attr( ,name = "id") 

Я надеюсь получить таблицу, которая выглядит примерно так:

listing  child   viewLim
1        F       T       
2        F       F      
3        T       T  

1 Ответ

0 голосов
/ 01 февраля 2019

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

Использование html_node вместо html_nodes всегда будет возвращатьодно значение (даже если это просто NA) обеспечивает одинаковую длину вектора.

Кроме того, при rvest я предпочитаю использовать синтаксис CSS вместо xpath.В большинстве случаев CSS проще в использовании, чем выражения xpath.

library(rvest)

page_html <- read_html(html)
#find the listing nodes and id of each node
listings<-html_nodes(page_html, "div.listing")
listing<-html_attr(listings ,name = "id") 

#search each listing node for the child ticket and limit view criteria
child<-sapply(listings, function(x) {html_node(x, "span.listing_sub1") %>% html_text()} ) 
viewLim<-sapply(listings, function(x) {html_node(x, "span.listing_sub3") %>% html_text()}) 

#create dataframe
df<-data.frame(listing, child=!is.na(child), viewLim=!is.na(viewLim))

# df
#    listing child viewLim
#1 listing_1 FALSE    TRUE
#2 listing_2 FALSE   FALSE
#3 listing_3  TRUE    TRUE
...