Как преобразовать NewYorkTimes в вашу базу данных :)
Table Of Content
В одной из предыдущих статей мы обсудили, почему кто-то может захотеть извлекать данные из Интернета. В другой статье мы расширяли эту тему и демонстрировали, как использовать парсинг как часть решения для мониторинга цен. Теперь давайте немного углубимся в область журналистики. Это может показаться немного неожиданным, но журналисты в наши дни довольно часто полагаются на парсинг. В качестве примеров я могу привести следующие статьи:
- https://journocode.com/2019/01/web-scraping-tools-journalists-how-to/
- https://coding-for-journalists.readthedocs.io/en/latest/pt2/
- https://datajournalism.com/read/newsletters/data-scraping-for-stories
С нашей стороны мы можем рассмотреть следующий случай использования: Представьте, что вы ведете местный новостной веб-сайт и пытаетесь быть в курсе самых свежих новостей в определенной области. Конечно, вы можете отправить своего человека в каждый город в этой области, или... вы можете периодически парсить данные с их веб-сайтов и создавать оповещение для определенных ключевых слов (например, тех, которые требуют особого внимания).
Постановка задачи
Давайте извлечем данные из одной из категорий онлайн-новостного бюллетеня NewYorkTimes (например, категории "Мир"). Нас будут интересовать заголовки, ссылки и описания. Однако на этот раз мы будем полагаться на RSS-ленту в качестве источника ссылок и другой информации.
Примечание: Иногда просмотренный веб-сайт может быть достаточно сложным. Например, много JavaScript, а также другие нетривиальные задачи. В таких случаях идея начать с их RSS-ленты (или по крайней мере использовать ее для некоторых частей логики парсинга) может изменить игру.
После некоторого исследования целевого веб-сайта мы обнаружили, что они предоставляют хорошую RSS-ленту для работы https://archive.nytimes.com/www.nytimes.com/services/xml/rss/index.html
Итак, давайте использовать ее в качестве отправной точки!
Настройка проекта
Теперь, когда у нас есть задача, выполните следующие шаги из руководства Quickstart:
mix new rss_example — sup
- Добавьте Crawly и SweetXML в файл mix:
defp deps do
[
{:crawly, "0.12.0"},
{:sweet_xml, "0.6.6"}
]
end
Примечание: В этом случае мы не используем Floki, так как мы собираемся разбирать XML-файл. Crawly сам по себе не требует использования предопределенного парсера, поэтому вы можете выбрать парсер, который подходит для вашего случая использования.
- Создайте папку config и файл config.exs
use Mix.Config
config :crawly,
closespider_timeout: 10,
concurrent_requests_per_domain: 8,
middlewares: [
{Crawly.Middlewares.UserAgent, user_agents: ["Crawly Bot"]}
],
pipelines: [
Crawly.Pipelines.JSONEncoder,
{Crawly.Pipelines.WriteToFile, extension: "jl", folder: "/tmp"}
]
Как видите, в этом случае нам не пришлось использовать сложную цепочку промежуточных обработчиков. Всегда проще, когда нужно разобрать ленту!
- Теперь, наконец, мы должны определить селекторы XML, чтобы извлечь нужные данные.
Давайте получим RSS-ленту (например, https://rss.nytimes.com/services/xml/rss/nyt/World.xml) и посмотрим на нее:
Как видите, информация хранится в блоке item. Поэтому нам нужно просмотреть все элементы item и извлечь заголовок, ссылку и описание.
В нашем случае все было суммировано в следующей простой функции parse_item:
@impl Crawly.Spider
def parse_item(response) do
items_list = xpath(response.body, ~x"//item")
items =
Enum.map(
items_list,
fn i ->
%{
title: "#{xpath(i, ~x"//title/text()")}",
link: "#{xpath(i, ~x"//link/text()")}",
description: "#{xpath(i, ~x"//media:description/text()")}"
}
end
)
%{
requests: [],
items: items
}
end
Полный код можно найти здесь: https://github.com/oltarasenko/rss_example.
Выводы
В этой статье показано, как создать паука, который использует RSS-ленту в качестве источника информации, и продемонстрировано, как использовать XML-парсер вместо Floki.
Хотите больше?
Попробуйте наше новое приложение для управления пауками под названием Crawly UI, которое упрощает управление пауками и анализ данных.