CoderCastrov logo
CoderCastrov
Веб-разработка

Задание по парсингу Hacker News

Задание по парсингу Hacker News
просмотров
4 мин чтение
#Веб-разработка
Scrape Hacker News with Dataflow kit

Почти все веб-страницы в Интернете содержат некоторые шумные блоки, такие как навигация, боковые панели, информация о авторских правах, уведомления о конфиденциальности и реклама, которые не имеют прямого отношения к теме веб-страницы.

Важно отличать основные блоки контента от шумных блоков. Давайте назовем их информативными блоками. Извлечение информации из информативных блоков является наиболее важной задачей для парсера веб-страниц.

Все дочерние HTML-элементы внутри каждого информативного блока обычно группируются в похожие структуры.


1. Задача. Извлечение информативных блоков с веб-сайта Hacker News.

Мы будем использовать сервис Dataflow kit для выполнения парсинга данных с веб-сайта HN.

Open Hacker News main page Parsed results returned by Datafalow Kit in CSV and JSON formats.

К сожалению, у нас есть два независимых списка "Оценок" и "Ссылок на истории". Кажется, что полученные поля не сгруппированы, как ожидалось!

На самом деле, мы ожидали, что "Ссылки на истории" будут сгруппированы вместе со своими соответствующими "Оценками".

Так что не так?

Давайте посмотрим на следующий HTML-код, описывающий блок, содержащий вышеупомянутые поля. Я опустил некоторые HTML-элементы из реального кода для краткости.

<tbody>
    <tr> ... 
        <td>
            <a href="http://example.com" class="storylink"> Recreating the Death Star Trench Run Scene with Lego
            </a>
        </td>
    </tr>
    <tr>...
        <td>
            <span class="score">10 points</span>
        </td>
    </tr>
    
    <tr> ... 
        <td>
            <a href="http://example2.com" class="storylink"> Show HN: JournalBook – Privacy centric, offline first, personal journal app
            </a>
        </td>
    </tr>
    <tr>...
        <td>
            <span class="score">36 points</span>
        </td>
    </tr>
</tbody>

В этом конкретном случае общим родительским элементом для всех соседних элементов является <tbody>, и нет родительского элемента, объединяющего элементы внутри информативных блоков.

Проблема заключается в том, что наш алгоритм парсинга объединяет все поля внутри блока, учитывая их общий родительский узел в дереве DOM. Все эти элементы "Ссылки на истории" и "Оценки" на самом деле являются соседними узлами. Но, хотя визуально они кажутся сгруппированными внутри этих похожих блоков.

Результаты, полученные с помощью аналогичных конкурентных сервисов парсинга с веб-сайта Hacker News, выглядят примерно одинаково. Почти все они используют тот же метод определения общего родительского элемента для группировки их вместе.

Проблему можно легко исправить другим подходом.

В Dataflow kit есть специальный тип селектора Path, который предназначен только для навигации. Когда указана опция Path, результаты с текущей страницы не возвращаются. Вместо этого, все веб-страницы по ссылкам Path будут посещены для извлечения подробной информации.

В нашем случае мы можем выбрать поле "Комментарии" в качестве селектора Path, как показано на изображениях ниже.

Select “Path” Selectors on the main page Add selectors on detailed page
  1. Показана подробная страница, где вы можете указать все необходимые CSS-селекторы для извлечения данных. Как вы можете заметить, здесь можно найти ту же информацию, что и на главной странице, такую как "Ссылка на историю", "Оценка", "Пользователь" и дополнительные поля "комментарии".

  2. Вернитесь на главную страницу, нажав "Стрелку влево вверху", и нажмите кнопку "Предварительный просмотр".

  3. Вы можете увидеть здесь некоторые строки в Табличном виде, содержащие извлеченные данные. Если данные имеют подробные поля, как в этом случае, их можно лучше представить в виде структуры JSON в Древовидном виде.

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

2. Задача. Извлечение информационных блоков с веб-сайта Hacker News.

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

К сожалению, в нашей первой попытке нам не удалось получить все 30 строк, как ожидалось, хотя все запросы возвращаются с успешными ответами 200 OK.

Что произошло?

После расследования мы обнаружили, что веб-сайт Hacker News всегда возвращает код состояния 200, даже если что-то пошло не так.

В нашем случае некоторые страницы пришли с чем-то вроде этого.

Обычно веб-API возвращают код состояния 429, что означает, что на сервер было отправлено слишком много запросов. Но Hacker News уведомляет о ограничении скорости запросов с кодом состояния 200.

Экспериментально мы определили, что 3 - оптимальное количество одновременных запросов к веб-серверу HN с одного IP.

После уменьшения количества одновременных загрузчиков мы успешно просканировали все 30 детальных страниц и извлекли всю необходимую информацию из них.

Выберите формат JSON и нажмите кнопку Запустить, чтобы начать парсинг данных. После завершения работы по извлечению данных нажмите Скачать, чтобы получить результаты в выбранном формате.

Запуск извлечения данных и загрузка результатов.

Как видно, было выполнено 31 запрос (1 главная страница + 30 ссылок Path) к веб-сайту Hacker News, и это заняло около 33 секунд.

3. D.I.Y Challenge :)

Вот ссылка на профиль Hacker News, который мы подготовили для вас, чтобы вы могли попробовать.

slotix/dataflowkit

Извлекайте структурированные данные с веб-сайтов. Парсинг веб-сайтов. - slotix/dataflowkit

github.com

Просто скачайте эту коллекцию news.ycombinator.collection.json и импортируйте ее. Посмотрите https://dataflowkit.com/collections для получения более подробной информации о функции экспорта/импорта.

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

Резюме.

У каждого веб-сайта есть своя уникальная структура. Методы парсинга одинаковы для всех ресурсов, хотя некоторые требуют индивидуального подхода для задач извлечения данных.

Мы ценим ваши отзывы и комментарии.

Счастливого парсинга!