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

Установка

Требования: Python 2.5+ (3-я ветка не поддерживается), Twisted, lxml или libxml2, simplejson, pyopenssl (для поддержки HTTPS)

Без проблем установил из репозитариев Ubuntu. На странице Installation guide описывается установка в других дистрибутивах Linux, а так же в Mac OS X и Windows.

Задача

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

Прежде чем писать паука, надо осмотреть сайт-источник. Заметим, сайт построен на фреймах (?!), во фреймсете ищем фрейм со стартовой страницей. Здесь присутствует форма поиска. Пусть нам нужны только вузы Москвы, поэтому заполняем соответствующее поле, жмем «Найти».

Анализируем. У нас есть страница с ссылками пагинации, 15 вузов на страницу. Параметры фильтра передаются через GET, меняются лишь значение page.

Итак, сформулируем задачу:

  1. Перейти на страницу abitur.nica.ru/new/www/search.php?region=77&town=0&opf=0&type=0&spec=0&ed_level=0&ed_form=0&qualif=&substr=&page=1
  2. Пройтись по каждой странице с результатами, меняя значение page
  3. Перейти в описание вуза abitur.nica.ru/new/www/vuz_detail.php?code=486®ion=77&town=0&opf=0&type=0&spec=0&ed_level=0&ed_form=0&qualif=&substr=&page=1
  4. Сохранить детальное описание вуза в CSV-файле

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

Переходим в папку, где будет располагаться наш проект, создаем его:

В папке abitur нашего проекта находятся файлы:

  • items.py содержит классы, которые перечисляют поля собираемых данных,
  • pipelines.py позволяет задать определенные действия при открытии/закрытии паука, сохранения данных,
  • settings.py содержит пользовательские настройки паука,
  • spiders — папка, в которой хранятся файлы с классами пауков. Каждого паука принято писать в отдельном файле с именем name_spider.py.

Паук

В созданном файле spiders/abitur_spider.py описываем нашего паука

Наш класс наследуется от CrawlSpider, что позволит нам прописать шаблоны ссылок, которые паук будет сам извлекать и переходить по ним.

По порядку:

  • name — имя паука, используется для запуска,
  • allowed_domains — домены сайта, за пределами которого пауку искать ничего не следует,
  • start_urls — список начальных адресов,
  • rules — список правил для извлечения ссылок.

Как вы заметили, среди правил параметром передается callback функция. Мы к ней скоро вернемся.

Элементы

Как я уже говорил, в items.py содержится классы, которые перечисляют поля собираемых данных.
Это можно сделать так:

Распарсенные данные можно обработать перед экспортом. К примеру, учебное заведение может быть «государственное» и «негосударственное», а мы хотим хранить это значение в булевом формате или дату «1 января 2011» записать как «01.01.2011».

Для этого существуют входные и выходные обработчики, поэтому поле state запишем по-другому:

MapCompose применяется к каждому элементу списка state.

Поиск элементов на странице

Возвращаемся к нашему методу parse_item.

Для каждого элемента Item можно использовать свой загрузчик. Его назначение тоже связано с обработкой данных.

В нашем случае из каждого поля удаляются крайние и дублирующиеся пробелы. В загрузчик также можно добавить индивидуальные правила, что мы делали в классе AbiturItem:

Так что, поступайте как вам удобнее.

Функция parse_item() возвращает объект Item, который передается в Pipeline (описываются в pipelines.py). Там можно написать свои классы для сохранения данных в форматах, не предусмотренных стандартным функционалом Scrapy. Например, экспортировать в mongodb.

Поля этого элемента задаются с помощью XPath, о котором можно прочитать здесь или здесь. Если вы используйте FirePath, обратите внимание, что он добавляет тег tbody внутрь таблицы. Для проверки путей XPath используйте встроенную консоль.

И еще одно замечание. Когда вы используете XPath, найденные результаты возвращаются в виде списка, поэтому удобно подключать выходной процессор TakeFirst, который берет первый элемент этого списка.

Запуск

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

Вкратце, я все описал, но это лишь малая часть возможностей Scrapy:

  • поиск и извлечение данных их HTML и XML
  • преобразование данных перед экспортом
  • экспорт в форматы JSON, CSV, XML
  • скачивание файлов
  • расширение фреймворка собственными middlewares, pipelines
  • выполнение POST запросов, поддержка куков и сессий, аутентификации
  • подмена user-agent
  • shell консоль для отладки
  • система логирования
  • мониторинг через Web-интерфейс
  • управление через Telnet-консоль

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

Рабочий пример выложил на GitHub.

Источник: Собираем данные с помощью Scrapy / Python / Хабрахабр.

Собираем данные с помощью Scrapy / Python /
Метки: