rvest не может захватить таблицу html с помощью html_nodes(«таблица»), несмотря на то, что таблица находится на странице

#r #web-scraping #rvest

Вопрос:

Мы изо всех сил пытаемся захватить главный стол по этой ссылке на фанграфы. С помощью rvest :

 url = 'https://www.fangraphs.com/leaders/splits-leaderboards?splitArr=1amp;splitArrPitch=amp;position=Bamp;autoPt=falseamp;splitTeams=falseamp;statType=teamamp;statgroup=2amp;startDate=2021-07-07amp;endDate=2021-07-21amp;players=amp;filter=amp;groupBy=seasonamp;sort=9,1'
table_nodes = url %>% read_html() %>% html_nodes('table')
table_nodes

 table_nodes
{xml_nodeset (7)}
[1] <table class="menu-standings-table"><tbody><tr>n<td>rn                                            <div class="menu-sub-header">AL East</div>rn                       ...
[2] <table class="menu-team-table">n<tr>n<td>rn                                        <div class="menu-sub-header">AL East</div>rn                                     ...
[3] <table class="menu-team-table">n<tr>n<td>rn                                        <div class="menu-sub-header">AL East</div>rn                                     ...
[4] <table>n<tr>n<td><a href="http://www.fangraphs.com/blogs/top-45-prospects-baltimore-orioles">BAL</a></td>n<td><a href="http://www.fangraphs.com/blogs/top-34-prospects ...
[5] <table>n<tr>n<td><a href="http://www.fangraphs.com/blogs/top-30-prospects-atlanta-braves">ATL</a></td>n<td><a href="http://www.fangraphs.com/blogs/top-49-prospects-ch ...
[6] <table>n<tr>n<td><a href="http://www.fangraphs.com/blogs/top-40-prospects-baltimore-orioles">BAL</a></td>n<td><a href="http://www.fangraphs.com/blogs/top-38-prospects ...
[7] <table>n<tr>n<td><a href="http://www.fangraphs.com/blogs/top-27-prospects-atlanta-braves">ATL</a></td>n<td><a href="http://www.fangraphs.com/blogs/top-41-prospects-ch ...
 

Ни одна из этих 7 таблиц не является основной таблицей по URL-адресу со всей различной статистикой команды. url %>% read_html() %>% html_nodes('div.table-scroll') возвращает пустой набор узлов и div.table-scroll является div-оболочкой, в которой находится основная таблица.

Редактировать: Я предполагаю, что это сетевой запрос, но все еще не уверен, как получить вызов API из этого. Как увидеть полный вызов API для этого?

введите описание изображения здесь

введите описание изображения здесь

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

1. Похоже, что эта таблица заполняется javascript (с отдельным запросом) после загрузки страницы. Я мало что сделал с rvest ним , но я подозреваю, что он, вероятно, не обрабатывает динамический контент.

2. Похоже, что это действительно так. Я копаюсь в инструментах разработчика Chrome > Сеть >> XHR, пытаясь понять, могу ли я найти там что-нибудь, что можно почистить для этой таблицы, но не могу найти, откуда берутся данные для таблицы.

3. Я не вижу таблицы в источнике страницы. ps: в Export Data правом верхнем углу таблицы есть кнопка.

4. да, кнопка «Экспорт данных» удобна, однако мы ищем программный подход к захвату этой таблицы и проведению некоторого анализа в R. Мы пытаемся удалить ручные аспекты (есть и другие таблицы, которые нужно захватить).

Ответ №1:

Данные динамически извлекаются из вызова API. Переключитесь на httr, так как вам нужно сделать запрос на публикацию, который включает дату начала/окончания. Кроме того, переключитесь на бесконечность с точки зрения возврата как можно большего количества данных с минимальным количеством вызовов.

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

 library(httr)
library(purrr)

headers = c(
  'user-agent' = 'Mozilla/5.0',
  'content-type' = 'application/json;charset=UTF-8'
)

data = '{"strPlayerId":"all","strSplitArr":[1],"strGroup":"season","strPosition":"B","strType":"2","strStartDate":"2021-07-07","strEndDate":"2021-07-21","strSplitTeams":false,"dctFilters":[],"strStatType":"team","strAutoPt":"false","arrPlayerId":[],"strSplitArrPitch":[]}'

r <- httr::POST(url = 'https://www.fangraphs.com/api/leaders/splits/splits-leaders', httr::add_headers(.headers=headers), body = data) %>% content()

df <- map_df(r$data, data.frame)
 

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

1. Спасибо, это просто фантастика. Как вы узнали, что нужно обратиться именно с этой POST просьбой?

2. Я использовал вкладку «Сеть браузера» (F12 Chrome) для мониторинга веб-трафика при нажатии клавиши F5 для обновления страницы. Затем я поискал разделенные лидеры в записанном действии и использовал предварительный ответ для проверки правильности запроса.

3. Кстати, вам не нужен заголовок реферера. На самом деле нужен только тип контента.

4. Хорошо, спасибо. Я отредактировал вопрос, чтобы быстро показать 2 скриншота. Я нашел сетевой запрос с split-leaders , но не уверен, как «использовать предварительный просмотр ответа для проверки правильности запроса».