Создание скрапера RSS-канала с помощью Python

Код этого проекта доступен на моем GitHub в разделе web_scraping_example.

В этом руководстве с помощью Python мы создадим простой скрапер RSS-канала, который можно использовать на любом сайте.

Необходимые ресурсы:

Начинаем

Сначала создадим каталог проекта и перейдем в него из командной строки.

$ mkdir web_scraping_example && cd web_scraping_example

Затем создадим файл проекта.

$ touch scraping.py

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

После этого установите пакеты, которые мы будем использовать. Вы можете сделать это с помощью pip:

$ pip install requests
$ pip install bs4

Импортируем библиотеки

В файле scraping.py мы импортируем установленные пакеты с помощью pip.

# scraping.pyimport requests
from bs4 import BeautifulSoup

Это позволит использовать функции, предоставляемые библиотеками Requests и BeautifulSoup.

Тестирование запроса

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

Начнем с создания базовой функции скрапинга.

# scraping.py
# импорт библиотек пропущен
...# функция скрапинга
def hackernews_rss('https://news.ycombinator.com/rss'):
    try:
        r = requests.get()
        return print('The scraping job succeeded: ', r.status_code)
    except Exception as e:
        print('The scraping job failed. See exception: ')
        print(e)print('Starting scraping')
hackernews_rss()
print('Finished scraping')

Мы вызываем библиотеку Requests и загружаем сайт с помощью request.get(...). Затем выводим код состояния в терминал, используя r.status_code, чтобы проверить подключение к сайту. Также для отслеживания ошибок мы используем блок try: except:.

После запуска программы мы получи код состояния 200. Это означает, что мы можем пропинговать сайт и «получить» информацию.

$ python scraping.py
Starting scraping
The scraping job succeeded: 200
Finsihed scraping

Скрапинг содержимого

Теперь начинаем извлекать XML-контент с сайта с помощью BS4 и Requests.

# scraping.py...def hackernews_rss():
    try:
        r = requests.get('https://news.ycombinator.com/rss')
        soup = BeautifulSoup(r.content, features='xml')
        
        return print(soup)
...

Этот код запишет извлекаемый XML-контент в переменную soup. Мы используем r.content для передачи возвращенного контента в BeautifulSoup. Обратите внимание, что мы используем features='xml'.

Разбор данных

Начнем с рассмотрения структуры RSS-канала:

<item>
<title>...</title>
<link>...</link>
<pubDate>...</pubDate>
<comments>...</comments>
<description>...</description>
</item>

Каждая из статей, доступных в RSS, имеет приведенную выше структуру. Она содержит всю необходимую информацию в тегах элементов - <item> ... </ item>. Мы будем использовать постоянные теги элементов для анализа информации.

# scraping.py def hackernews_rss():
    article_list = []    try:
        r = requests.get('https://news.ycombinator.com/rss')
        soup = BeautifulSoup(r.content, features='xml')        articles = soup.findAll('item')                for a in articles:
            title = a.find('title').text
            link = a.find('link').text
            published = a.find('pubDate').text            article = {
                'title': title,
                'link': link,
                'published': published
                }
            article_list.append(article)        return print(article_list)
...

Начнем с проверки articles = soup.findAll('item'). Это позволит извлечь каждый из тегов <item> ... </ item> из XML.

Каждая из статей будет разделена с помощью цикла: for a in articles:. Это позволит разделить данные на отдельные переменные и добавить их в созданный пустой словарь.

Библиотека BS4 модифицировала код XML в строку. Это позволяет вызывать функцию find() для каждого из объектов, чтобы найти теги. Используя .text, очистим элементы от <tag> ... </ tag> и сохраним только строку. Затем поместим элементы в список, чтобы позже получить к ним доступ через article_list.append(article).

Сейчас при запуске программы-скрапера будут выведены извлеченные из RSS данные.

Вывод в файл

Теперь RSS-канал успешно выводится через функцию print(). Теперь поместим данные в .txt-файл с помощью JSON.

Начнем с создания еще одной функции def save_function ():. В качестве аргументов она принимает список из функции hackernews_rss().

# scraping.py
import json...
def save_function(article_list):
    with open('articles.txt', 'w') as outfile:
        json.dump(article_list, outfile)...

Для записи результатов веб-скрапинга в файл article.txt используется библиотека JSON. Этот файл будет перезаписан при выполнении программы.

Другой метод записи в .txt-файл – использование цикла for:

# scraping.py
...
def save_function(article_list):
with open('articles.txt', 'w') as f:
for a in article_list:
f.write(a+'n')
f.close()

Теперь перейдем к адаптации функции веб-скрапинга для сохранения данных.

# scraping.py...
def hackernews_rss():
    ...
    try:
        ...
        return save_function(article_list)
...

Изменив return print(article_list) на функцию save_function (article_list), мы можем перенести данные в текстовый файл. Запустив программу, вы получите .txt файл с данными, извлеченными из RSS-канала.

Заключение

Мы успешно создали инструмент веб-скрапинга RSS-каналов, используя Python, Requests и BeautifulSoup. Они позволяют преобразовывать информацию из XML в читаемый формат.

Что дальше?

В этой статье были рассмотрены только основы веб-скрапинга. Вы можете улучшить данный проект, используя Celery и Django.

Вадим Дворниковавтор-переводчик статьи «Building an RSS feed scraper with Python»