Estou geralmente familiarizado com rvest
. Sei a diferença entre html_elements()
e html_element()
. Mas não consigo entender esse problema:
Suponha que temos dados como os que estão nesta página da web . Os dados estão em um formato hierárquico e cada cabeçalho tem um número diferente de subtítulos.
Quando tento raspar, obtenho 177 cabeçalhos. Mas, os subtítulos são, na verdade, 270. Quero extrair os dados em um formato organizado. Mas com tamanhos de vetores diferentes, não consigo combiná-los facilmente em um tibble.
Aqui está meu código com alguns comentários sobre os resultados:
page <- read_html("https://postdocs.stanford.edu/about/department-postdoc-admins")
person_departments <- page %>%
html_elements(".item-list") %>%
html_element("h3") %>%
html_text2()
# The above code returns
person_names <- page %>%
html_elements(".item-list li") %>%
html_element("h4") %>%
html_text2()
# This one returns 270 names (some departments have more than 1 admin)
# Using the above codes, I can't get a nice table with two columns, one for the name and one for the person's department.
O truque principal é obter os filhos dos
"item-list"
elementos. Então é uma questão de processar em uma tabela. Cada departamento é um elemento de lista de numeração ímpar, as pessoas estão nos de numeração par. Deve-se tomar cuidado com cargos de departamento vagos.Criado em 2024-09-11 com reprex v2.1.0
Aqui está uma abordagem um pouco diferente, comece com
.item-list > ul > li
elementos, de lá você pode extrair diretamente nome, telefone e e-mail. Se algum desses elementos não estiver disponível noli
elemento atual, você convenientemente obtém umNA
valor no quadro resultante (por exemplo, para posições vagas e para casos em que apenas o e-mail é listado).Para
h4
alternar,xpath
pois permite procurar por ancestrais, dessa forma você pode obter correspondênciash4
para cada umli
na lista de elementos.De certa forma, é uma questão de preferência de estilo (bem... desempenho também), mas também podemos usar esses mesmos blocos de construção sem a iteração
map()
/lapply()
. Usar singularhtml_element()
no contexto a seguir pode não soar muito intuitivo, mas há esse pedaço no doc:Devo dizer que eu pessoalmente consegui ignorar isso até hoje.
De qualquer forma, podemos obter um resultado idêntico ao exemplo anterior com:
Becnhmark (observe segundos vs milissegundos):