CoderCastrov logo
CoderCastrov
Парсинг

Краулер от начала до конца: Django + Scrapy

Краулер от начала до конца: Django + Scrapy
просмотров
6 мин чтение
#Парсинг

Привет, ребята, как дела?

Давайте начнем первый пост здесь на Medium!!, поехали! 😋

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

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

Действительно, после долгих исследований все стало проще, поэтому я хочу кратко объяснить на примере, как я сделал эту интеграцию...


Используемые версии:

Python 3.6.7

Django 2.1.3

Scrapy 1.5

Сбор информации о лучших фильмах 2018 года

Мы собираемся использовать парсер на веб-сайте Rotten Tomatoes, который является агрегатором американских отзывов. Нашей целью будет получить информацию о 100 лучших фильмах 2018 года. Мы хотим получить такую информацию, как процент одобрения, название, количество отзывов, обложку и другую информацию, которая может быть полезной для нас.

Создание проекта Django

Предполагая, что у вас уже установлен Python на вашем компьютере, давайте начнем!

1. Инициализация проекта

$ django-admin startproject best_movies .

2. Создание и инициализация virtualenv

$ python3 -m venv .venv && source .venv/bin/activate

3. Установка django 2.1.3

$ pip install Django==2.1.3

4. Создание приложения Фильм

$ python manage.py startapp movie

Создание модели...

5. Регистрация нашего приложения в Django Admin

В movie/admin.py чтобы отобразить CRUD в админке

from django.contrib import admin
from .models import Movie

class MovieAdmin(admin.ModelAdmin):
    pass
admin.site.register(Movie, MovieAdmin)

6. Ах, не забудем зарегистрировать наше приложение

В best_movies/settings.py

INSTALLED_APPS = [
    ...
    'django.contrib.staticfiles',
    'movie',
]

Пока мы здесь, давайте добавим важную переменную окружения, которую мы будем использовать для указания пути к обложкам после парсинга:

MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

7. Необходимо установить библиотеку Pillow

Поскольку наше поле изображения требует специальной обработки, Django рекомендует установить библиотеку Pillow для выполнения этой работы. В терминале:

$ pip install Pillow

8. Добавление URL для просмотра локальных изображений

Чтобы просматривать изображения локально, нам необходимо добавить следующий фрагмент в best_movies/urls.py

urlpatterns = [
    url(r'^admin/', admin.site.urls),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

9. Наша модель уже готова, создадим и выполним миграции

$ python manage.py makemigrations && python manage.py migrate

10. Создаем суперпользователя

$ python manage.py createsuperuser

Теперь у нас есть наше приложение.

Запустите python manage.py runserver в терминале и откройте localhost:8000/admin

Теперь у нас есть наше приложение CRUD "вручную", и далее мы будем автоматизировать это!!!


Установка Scrapy в проект

1. Установка библиотек

В папке проекта best_movies установите библиотеку Scrapy

$ pip install scrapy

Также установим другую библиотеку, которую мы будем использовать позже для интеграции с нашей моделью Django:

$ pip install scrapy-djangoitem==1.1.1

2. Инициализация проекта

Давайте создадим проект Scrapy здесь внутри проекта Django, и он будет называться crawling

$ scrapy startproject crawling

Структура файлов проекта Scrapy

├─ crawling│ ├─── init.py│ ├─── items.py│ ├─── middlewares.py│ ├─── pipelines.py│ ├─── __pycache__│ ├─── settings.py│ └─── spiders│ ├─── ___init.py│ └─── _____pycache__└─ scrapy.cfg

3. Trazendo nosso modelo Movie criado no Django anteriormente

Em crawler/items.py

import scrapy
from scrapy_djangoitem import DjangoItem
from movie.models import Movie

class MovieItem(DjangoItem):
    django_model = Movie
    image_urls = scrapy.Field()
    images = scrapy.Field()

4. Settings.py

Em crawler/settings.py

Logo na primeira linha inserimos o seguinte código

import os
import sys
sys.path.append(os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), ".."))
os.environ['DJANGO_SETTINGS_MODULE'] = 'best_movies.settings'
import django
django.setup()

Aqui também vamos retirar o seguinte trecho de código para que o servidor não nos bloqueie. Ah, e também não queremos causar problemas ao nosso amigo Rotten Tomatoes com quantidades absurdas de requisições.

[DOWNLOAD_DELAY](https://doc.scrapy.org/en/latest/topics/settings.html#download-delay) = 3

Uma configuração importante que precisamos colocar aqui é o caminho onde vamos salvar as imagem, lembrando que MEDIA_ROOT é a variável que configuramos lá na primeira parte do tutorial.

from best_movies.settings import MEDIA_ROOT

IMAGES_STORE = MEDIA_ROOT

Nesse arquivo, vamos adicionamos os seguintes ITEM_PIPELINES, que são os responsáveis por tratar as informações coletas.

ITEM_PIPELINES = {
    'scrapy.pipelines.images.ImagesPipeline': 100,
    'crawling.pipelines.CrawlingPipeline': 100,
}

Aparentemente já temos tudo configurado para fazer as nossa primeira spider. Bora?!

5. Создание первого паука

В директории spiders создадим файл с названием rottentomatoes.py

$ cd crawling/spiders && touch rottentomatoes.py

Этот файл будет указывать путь, по которому нужно перемещаться на странице Rotten Tomatoes, чтобы правильно собирать данные. Пути на странице можно указывать двумя способами: с помощью CSS или Xpath. (Подробнее)

Мы выберем Xpath и CSS одновременно, чтобы вы могли увидеть, как они работают на практике.

Мы просто проходим по строкам таблицы с классом table и получаем все ссылки по пути '**/tr/td[3]/'. **Затем мы проходим по каждой из этих ссылок в цикле и получаем доступ к каждой из них с помощью yield, который выполняет новый запрос. Таким образом, мы создаем обратный вызов для новой функции, называемой parse_item, которая фактически отвечает за сбор каждой нужной нам информации с помощью выборок. Теперь мы используем CSS для этого процесса.

После выполнения всех этих шагов и создания экземпляра MOVIE, мы возвращаем его, так как следующим шагом будет файл pipelines.py, где данные будут обрабатываться.

6. Пайплайны

Ответственный за очистку данных, файл pipelines получает информацию, которую мы получили с помощью парсера, и обрабатывает эту информацию в соответствии с ее потребностями. Вот простой пример, который я сделал для удаления пробелов, удаления символов, объединения элементов списка и т. д.

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

В этом же файле я решил создать логику для сохранения элемента в базе данных. Помните, что это можно улучшить и очень много! Но уже работает.

# 6. Пайплайны

Ответственный за очистку данных, файл pipelines получает информацию, которую мы получили с помощью парсера, и обрабатывает эту информацию в соответствии с ее потребностями. Вот простой пример, который я сделал для удаления пробелов, удаления символов, объединения элементов списка и т. д.

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

В этом же файле я решил создать логику для сохранения элемента в базе данных. Помните, что это можно улучшить и очень много! Но уже работает.

7. Давайте посмотрим, как это работает

Готовы??!! Просто перекрестите пальцы и выполните команду в best_movies/crawling

$ scrapy crawl rottentomatoes

И вуаля! В консоли вы сможете видеть в реальном времени получение данных.

Хорошо, если все прошло успешно, теперь, когда вы откроете модель в админке Django, у вас будет результат, похожий на этот:

Захвачено 100 фильмов! 🎉

Надеюсь, вы поняли и вам понравился результат, а дальше все в ваших руках! Будьте креативны, с помощью этого можно сделать много интересного.

Я разместил код учебника на Github, поэтому, если у вас возникнут вопросы, вы можете обратиться туда.

https://github.com/TiagoPiovesan/scrapy_rottentomatoes

До встречи в следующем уроке!