31 дек. 2012 г.

Scrapy + MongoDB: Пишем парсер Amazon (part3)

В первой и второй части статьи, мы разработали паука, который способный собирать данные с Amazon, по запросу Books.

Теперь нам нужно организовать запись данных в MongoDB. Надеюсь она у вас установлена, если нет, то можете перейти на эту страницу и посмотреть все возможные варианты.

P.S. Как и в случае с Scrapy. На официальном сайте MongoDB содержится отличная документация. Потому, невозможно сделать полное описание этой СУБД, в рамках статьи. Мы просто ограничимся вещами, нужными для завершения нашей, ознакомительной работы...

Связка Scrapy + MongoDB удобна тем, что полученный класс item(см. вторую часть мануала) имеет JSON-подобную структуру. А MongoDB ориентируется на работу с такими данными, благодаря NoSQL архитектуре. Потому работа практически сводится к прямой передаче полученных данных, через драйвер, в базу данных.



Для работы нам понадобится драйвер на Python, которым выступает PyMongo. Устанавливаем его с помощью PIP:
sudo pip install pymongo
После успешной установки, переходим в папку с нашим пауком и смотрим...
Там два нужных нам файла, которые мы еще не использовали: settings.py и pipelines.py

P.S. MongoDB на автомате создаст базу данных, при первом обращении и добавлении материала в нее. Потому сосредотачиваемся просто на работе ;)

В pipelines.py описывается дальнейшая работа с полученными данными, в классе item(см. вторую часть мануала).

Зайдем в этот файл и полностью заменим содержимое:

import pymongo

from scrapy.exceptions import DropItem
from scrapy.conf import settings
from scrapy import log

class AmazonSpiderMongoDB(object):
    def __init__(self):
        connection = pymongo.Connection(settings['MONGODB_SERVER'], settings['MONGODB_PORT'])
        db = connection[settings['MONGODB_DB']]
        self.collection = db[settings['MONGODB_COLLECTION']]
        
    def process_item(self, item, spider):
    valid = True
        for data in item:
         if not data:
            valid = False
            raise DropItem('Missing data')
        if valid:
          self.collection.insert(dict(item))
          log.msg("Item wrote to MongoDB database %s/%s" %
                  (settings['MONGODB_DB'], settings['MONGODB_COLLECTION']),
                  level=log.DEBUG, spider=spider) 
        return item


В двух словах:

1) Мы создаем подключение к серверу MongoDB, через драйвер.
2) Теперь подключаемся к базе данных(она будет создана автоматически).
3) Наследуем отдельную таблицу в self.collection и работаем с ней(тоже создана автоматически).
4) Метод process_item - описывает работу с полученными данными, от паука.
5) Идет проверка на наличие данных.
6) Если данные пусты, то через DropItem передается ошибка.
7) Если данные получены, то в унаследованный self.collection передаются данные, через метод insert. Класс item изменяет тип на словарь.
8) Вызывается класс логинирования, чтобы отобразить успешный результат.


Как замечено выше. Таблица в MongoDB будет создана на автомате и все данные будут записываться напрямую.

Еще вы можете заметить константы MONGODB_SERVER, MONGODB_PORT, MONGODB_DB, MONGODB_COLLECTION.
Их мы укажем в файле settings.py для удобства в работе:


ITEM_PIPELINES = ['amazon_spider.pipelines.AmazonSpiderMongoDB',]

MONGODB_SERVER = "localhost"
MONGODB_PORT = 27017
MONGODB_DB = "scrapy_spiders"
MONGODB_COLLECTION = "amazon_spider_books"


База данных будет иметь название - scrapy_spiders
Таблица - amazon_spider_books
Данные для соединения я указываю со стандартного конфига MongoDB

Кстати, обратите внимание на ITEM_PIPELINES. На самом деле, когда данные получены пауком, то сигнал посылается как раз на ITEM_PIPELINES. А вот в нем уже указывается обработчик для данных. В нашем случае - наследуется класс обработки, созданный в файле pipelines.py

Примерно все изменения выглядят так:



Запустим еще раз паука.
scrapy crawl amazon_spider_books
Подождем пару пройденных страниц...
Теперь остановим роботу CTRL+C

Теперь впишем в терминал:
mongo
show dbs
 
Первая команда запускает shell, вторая - показывает список доступных БД.

Мой скрин:

Как видно создана БД с названием scrapy_spiders. Как мы и указывали в файле settings.py

Теперь мы можем в терминале написать:
use scrapy_spiders
show collections

Мы перешли на нашу БД(scrapy_spiders) и увидели все доступные таблицы.


Давайте тогда и просмотрим результат, пишем в терминале:
db.getCollection('amazon_spider_books').find().pretty()

И...

Как видно на скрине, в БД теперь все данные, которые мы собрали пауком. Изучив API MongoDB вы сможете с легкостью оперировать полученными данными, с помощью Python. И использовать весь материал в дальнейшем.

В принципе, с поставленной задачей мы справились. Конечно результат далеко не идеальный.

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

И .....

Можно еще много чего сделать :) Но мануал ориентирован только на начальный разбор полетов.

2 комментария:

  1. Продолжайте, очень интересует, как сделать сохранение позиции, на которых работа была прервана, и вообще, как он хранит уже посещенные страницы. В русской части интернета очень мало информации о scrapy. Спасибо за статью, очень помогло!

    ОтветитьУдалить
  2. реально крутая статья! мне очень помогла

    ОтветитьУдалить