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

Table Of Content
- Используемые версии:
- **Сбор информации о лучших фильмах 2018 года**
- Создание проекта Django
- **1. Инициализация проекта**
- 2. Создание и инициализация virtualenv
- 3. Установка django 2.1.3
- **4.** **Создание приложения Фильм**
- **5. Регистрация нашего приложения в Django Admin**
- 6. Ах, не забудем зарегистрировать наше приложение
- 7. Необходимо установить библиотеку Pillow
- 8. Добавление URL для просмотра локальных изображений
- 9. Наша модель уже готова, создадим и выполним миграции
- **10. Создаем суперпользователя**
- Установка Scrapy в проект
- 1. Установка библиотек
- 2. Инициализация проекта
- 3. Trazendo nosso modelo Movie criado no Django anteriormente
- 4. Settings.py
- **5. Создание первого паука**
- 6. Пайплайны
- 6. Пайплайны
- 7. Давайте посмотрим, как это работает

Привет, ребята, как дела?
Давайте начнем первый пост здесь на 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
До встречи в следующем уроке!