Поиск по блогу

пятница, 1 августа 2014 г.

Первый спайдер-сырец с тремя объектами pipeline (работающий четвертьфабрикат)

Снова подправил mail_csv_2_1.py Получил почти окончательный вариант паука, который парсит csv, и добавляет поле rtesponse.url. Потом первый объект pipeline убирает первые две строчки, а второй pipeline из поля URL выбираеит нужные подстроки. Сначала мы записываем все поля в файл, используя опцию (scrapy crawl mail_csv_2_1 -o items_2_2.csv -t csv), а потом дописываем модуль'scrapy_csv_2.pipelines_tofile.CsvWriterPipeline' Этот пост - решение всех задачек, которые возникали в предыдущих постах.

Пробуем сформулировать подход к решению задачи mail_csv_

В изложении будем придерживаться подхода (и последовательности изложения), принятого в документации:
1. В модуле Items создаем сразу избыточное количество полей (с запасом для будущих столбцов)
2. Затем парсим пауком три поля из строк csv файлов и одно поле response.url
3. Далее первый объект pipeline (ScrapyCsv1Pipeline) убирает первые две "ненужные" строки... В исходном файле есть еще пустая строка, она убирается по умолчанию.
4. Второй объект pipeline (ScrapyCsv2Pipeline) парсит поле purl (url из исходного файла и заполняет подготовленные заранее поля (столбцы)
5. Треий объект pipeline () понадобится, чтобы распарсить поле из response.url по нескольким полям (столбцам). Поскольку мы уже научились парсить URL простой командой "split", то этот объект не будет существенно отличаться от второго. (Здесь не рассмтриваем).
6. И последний объект pipeline будет писать результат в csv файл (попробовал поместить в отдельный модуль - 'scrapy_csv_2.pipelines_tofile.CsvWriterPipeline')

Вот, что получилось при записи в файйл из командной строки

In []:
bodyurl,purlplit,N100,purl,proj_name,N
file://C:/Users/kiss/Documents/GitMyScrapy/scrapy_csv_2/nissan_2.csv,catalogue,"39,46",http://auto.mail.ru/catalogue/nissan/,Users,7371
file://C:/Users/kiss/Documents/GitMyScrapy/scrapy_csv_2/nissan_2.csv,catalogue,"7,58",http://auto.mail.ru/catalogue/nissan/qashqai/,Users,1416
file://C:/Users/kiss/Documents/GitMyScrapy/scrapy_csv_2/nissan_2.csv,catalogue,"6,31",http://auto.mail.ru/catalogue/nissan/x-trail/,Users,1179
Если повторно выполнить команду scrapy crawl mail_csv_2_1 -o items_2_2.csv -t csv, то к этим 4-рем строкам добавятся такие же 4-ре. Ниже сообщения из консоли:
In []:
C:\Users\kiss\Documents\GitMyScrapy\scrapy_csv_2>scrapy crawl mail_csv_2_1 -o items_2_2.csv -t csv
2014-07-27 18:40:36+0400 [scrapy] INFO: Scrapy 0.20.1 started (bot: scrapy_csv_2)
2014-07-27 18:40:36+0400 [scrapy] DEBUG: Optional features available: ssl, http11, boto, django
2014-07-27 18:40:36+0400 [scrapy] DEBUG: Overridden settings: {'NEWSPIDER_MODULE': 'scrapy_csv_2.spiders', 'FEED_FORMAT': 'csv', 'S
IDER_MODULES': ['scrapy_csv_2.spiders'], 'FEED_URI': 'items_2_2.csv', 'BOT_NAME': 'scrapy_csv_2'}
2014-07-27 18:40:38+0400 [scrapy] DEBUG: Enabled extensions: FeedExporter, LogStats, TelnetConsole, CloseSpider, WebService, CoreSt
ts, SpiderState
2014-07-27 18:40:38+0400 [scrapy] DEBUG: Enabled downloader middlewares: HttpAuthMiddleware, DownloadTimeoutMiddleware, UserAgentMi
dleware, RetryMiddleware, DefaultHeadersMiddleware, MetaRefreshMiddleware, HttpCompressionMiddleware, RedirectMiddleware, CookiesMi
dleware, ChunkedTransferMiddleware, DownloaderStats
2014-07-27 18:40:38+0400 [scrapy] DEBUG: Enabled spider middlewares: HttpErrorMiddleware, OffsiteMiddleware, RefererMiddleware, Url
engthMiddleware, DepthMiddleware
2014-07-27 18:40:38+0400 [scrapy] DEBUG: Enabled item pipelines: ScrapyCsv1Pipeline, ScrapyCsv2Pipeline
2014-07-27 18:40:38+0400 [mail_csv_2_1] INFO: Spider opened
2014-07-27 18:40:38+0400 [mail_csv_2_1] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)
2014-07-27 18:40:39+0400 [scrapy] DEBUG: Telnet console listening on 0.0.0.0:6023
2014-07-27 18:40:39+0400 [scrapy] DEBUG: Web service listening on 0.0.0.0:6080
2014-07-27 18:40:39+0400 [mail_csv_2_1] DEBUG: Crawled (200) <GET file://C:/Users/kiss/Documents/GitMyScrapy/scrapy_csv_2/nissan_2.
sv> (referer: None)
2014-07-27 18:40:39+0400 [scrapy] INFO: Hi, this is a row!: {'N100': u'85837', 'purl': u'http://auto.mail.ru', 'N': u'\u0410\u0432\
0442\u043e@Mail.Ru'}
2014-07-27 18:40:39+0400 [mail_csv_2_1] Invalid format string or unformattable object in log message: 'WARNING: Dropped: %(exceptio
)s\r\n%(item)s', {'exception': DropItem(u'Contains forbidden word: \u0410\u0432\u0442\u043e@Mail.Ru',), 'format': 'WARNING: Dropped
 %(exception)s\r\n%(item)s', 'logLevel': 30, 'system': 'mail_csv_2_1', 'spider': <MailCsvSpider 'mail_csv_2_1' at 0x4526438>, 'item
: {'N': u'\u0410\u0432\u0442\u043e@Mail.Ru',
         'N100': u'85837',
         'bodyurl': 'file://C:/Users/kiss/Documents/GitMyScrapy/scrapy_csv_2/nissan_2.csv',
         'proj_name': 'Users',
         'purl': u'http://auto.mail.ru'}, 'time': 1406472039.079, 'message': (), 'isError': 0}
2014-07-27 18:40:39+0400 [scrapy] WARNING: ignoring row 2 (length: 0, should be: 3)
2014-07-27 18:40:39+0400 [scrapy] INFO: Hi, this is a row!: {'N100': u'%', 'purl': u'\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u04
b', 'N': u'\u041f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u044b'}
2014-07-27 18:40:39+0400 [mail_csv_2_1] Invalid format string or unformattable object in log message: 'WARNING: Dropped: %(exceptio
)s\r\n%(item)s', {'exception': DropItem(u'Contains forbidden word: \u041f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u044b',), 'form
t': 'WARNING: Dropped: %(exception)s\r\n%(item)s', 'logLevel': 30, 'system': 'mail_csv_2_1', 'spider': <MailCsvSpider 'mail_csv_2_1
 at 0x4526438>, 'item': {'N': u'\u041f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u044b',
         'N100': u'%',
         'bodyurl': 'file://C:/Users/kiss/Documents/GitMyScrapy/scrapy_csv_2/nissan_2.csv',
         'proj_name': 'Users',
         'purl': u'\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u044b'}, 'time': 1406472039.101, 'message': (), 'isError': 0}
2014-07-27 18:40:39+0400 [scrapy] INFO: Hi, this is a row!: {'N100': u'39,46', 'purl': u'http://auto.mail.ru/catalogue/nissan/', 'N
: u'7371'}
2014-07-27 18:40:39+0400 [mail_csv_2_1] DEBUG: Scraped from <200 file://C:/Users/kiss/Documents/GitMyScrapy/scrapy_csv_2/nissan_2.c
v>
        {'N': u'7371',
         'N100': u'39,46',
         'bodyurl': 'file://C:/Users/kiss/Documents/GitMyScrapy/scrapy_csv_2/nissan_2.csv',
         'proj_name': 'Users',
         'purl': u'http://auto.mail.ru/catalogue/nissan/',
         'purlplit': u'catalogue'}
2014-07-27 18:40:39+0400 [scrapy] INFO: Hi, this is a row!: {'N100': u'7,58', 'purl': u'http://auto.mail.ru/catalogue/nissan/qashqa
/', 'N': u'1416'}
2014-07-27 18:40:39+0400 [mail_csv_2_1] DEBUG: Scraped from <200 file://C:/Users/kiss/Documents/GitMyScrapy/scrapy_csv_2/nissan_2.c
v>
        {'N': u'1416',
         'N100': u'7,58',
         'bodyurl': 'file://C:/Users/kiss/Documents/GitMyScrapy/scrapy_csv_2/nissan_2.csv',
         'proj_name': 'Users',
         'purl': u'http://auto.mail.ru/catalogue/nissan/qashqai/',
         'purlplit': u'catalogue'}
2014-07-27 18:40:39+0400 [scrapy] INFO: Hi, this is a row!: {'N100': u'6,31', 'purl': u'http://auto.mail.ru/catalogue/nissan/x-trai
/', 'N': u'1179'}
2014-07-27 18:40:39+0400 [mail_csv_2_1] DEBUG: Scraped from <200 file://C:/Users/kiss/Documents/GitMyScrapy/scrapy_csv_2/nissan_2.c
v>
        {'N': u'1179',
         'N100': u'6,31',
         'bodyurl': 'file://C:/Users/kiss/Documents/GitMyScrapy/scrapy_csv_2/nissan_2.csv',
         'proj_name': 'Users',
         'purl': u'http://auto.mail.ru/catalogue/nissan/x-trail/',
         'purlplit': u'catalogue'}
2014-07-27 18:40:39+0400 [mail_csv_2_1] INFO: Closing spider (finished)
2014-07-27 18:40:39+0400 [mail_csv_2_1] INFO: Stored csv feed (3 items) in: items_2_2.csv
2014-07-27 18:40:39+0400 [mail_csv_2_1] INFO: Dumping Scrapy stats:
        {'downloader/request_bytes': 265,
         'downloader/request_count': 1,
         'downloader/request_method_count/GET': 1,
         'downloader/response_bytes': 294,
         'downloader/response_count': 1,
         'downloader/response_status_count/200': 1,
         'finish_reason': 'finished',
         'finish_time': datetime.datetime(2014, 7, 27, 14, 40, 39, 245000),
         'item_dropped_count': 2,
         'item_dropped_reasons_count/DropItem': 2,
         'item_scraped_count': 3,
         'log_count/DEBUG': 10,
         'log_count/INFO': 9,
         'log_count/WARNING': 3,
         'response_received_count': 1,
         'scheduler/dequeued': 1,
         'scheduler/dequeued/memory': 1,
         'scheduler/enqueued': 1,
         'scheduler/enqueued/memory': 1,
         'start_time': datetime.datetime(2014, 7, 27, 14, 40, 38, 998000)}
2014-07-27 18:40:39+0400 [mail_csv_2_1] INFO: Spider closed (finished)

C:\Users\kiss\Documents\GitMyScrapy\scrapy_csv_2>

Сам паук выглядит так:

In [2]:
%load "C:\\Users\\kiss\\Documents\\GitMyScrapy\\scrapy_csv_2\\scrapy_csv_2\\spiders\\mail_csv_2_1.py"
In []:
from scrapy.contrib.spiders import CSVFeedSpider
from scrapy_csv_2.items import ScrapyCsv1Item
from scrapy import log

class MailCsvSpider(CSVFeedSpider):
    name = 'mail_csv_2_1'
    #allowed_domains = ['file://C:/Users/kiss/Documents/GitHub_2/scrapy_csv_2/']
    #start_urls = ['nissan_9_1_00.csv']
 
    headers = ['N', 'N100', 'purl']
    delimiter = ';'
    start_urls = ['file://C:/Users/kiss/Documents/GitMyScrapy/scrapy_csv_2/nissan_2.csv']
 
        
   
   # Do any adaptations you need here
   #def adapt_response(self, response):
   #    return response

   # I`m going to ust url splitting Гыыыыы
   # proj_fromurl = response.url.split("/")[-2]
 
    def parse_row(self, response, row):
  i = ScrapyCsv1Item()
  i['N'] = row['N']
  i['N100'] = row['N100']
  i['purl'] = row['purl']
  #i['purlplit'] = i['purl'].split("/")[-3]
  i['bodyurl'] = response.url
  i['proj_name'] = response.url.split("/")[3]
  log.msg('Hi, this is a row!: %r' % row)
  return i
    

 
Здесь я закоментировал строчку #i['purlplit'] = i['purl'].split("/")[-3] Таким образом, объявленной в items.py поле осталось "пустым". Мы его заполним в pipelines (см. ниже)
In [1]:
%load "C:\\Users\\kiss\\Documents\\GitMyScrapy\\scrapy_csv_2\\scrapy_csv_2\\items.py"
In []:
# Define here the models for your scraped items
#
# See documentation in:
# http://doc.scrapy.org/en/latest/topics/items.html

from scrapy.item import Item, Field

class ScrapyCsv1Item(Item):
    # define the fields for your item here like:
    # name = Field()
 N = Field()
 N100=Field()
 purl=Field()
 bodyurl=Field()
 proj_name=Field()
 purlplit=Field()

Чтобы последовательно подключить pipelines нужно добавить в settings.py словарь ITEM_PIPELINES

In [3]:
%load "C:\\Users\\kiss\\Documents\\GitMyScrapy\\scrapy_csv_2\\scrapy_csv_2\\settings.py"
In []:
# Scrapy settings for scrapy_csv_1 project
#
# For simplicity, this file contains only the most important settings by
# default. All the other settings are documented here:
#
#     http://doc.scrapy.org/en/latest/topics/settings.html
#

BOT_NAME = 'scrapy_csv_2'

SPIDER_MODULES = ['scrapy_csv_2.spiders']
NEWSPIDER_MODULE = 'scrapy_csv_2.spiders'

# Crawl responsibly by identifying yourself (and your website) on the user-agent
#USER_AGENT = 'scrapy_csv_1 (+http://www.yourdomain.com)'

ITEM_PIPELINES = {'scrapy_csv_2.pipelines.ScrapyCsv1Pipeline':300, 'scrapy_csv_2.pipelines.ScrapyCsv2Pipeline':310, 'scrapy_csv_2.pipelines_tofile.CsvWriterPipeline':400}

Три объекта pipelines в двух модулях (просто попробовал добавить еще модуль)

In [4]:
%load "C:\\Users\\kiss\\Documents\\GitMyScrapy\\scrapy_csv_2\\scrapy_csv_2\\pipelines.py"
In []:
# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html
from scrapy.exceptions import DropItem

class ScrapyCsv1Pipeline(object):
    """A pipeline for filtering out items which contain certain words in their
    description"""

    # put all words in lowercase
    words_to_filter = [unicode('Авто@Mail.Ru','utf-8'),unicode('Просмотры','utf-8')]

    def process_item(self, item, spider):
        for word in self.words_to_filter:
            if word in item['N']:
                raise DropItem("Contains forbidden word: %s" % word)
        else:
            return item

class ScrapyCsv2Pipeline(object):
    """A pipeline for """

    # put all words in lowercase
    
    def process_item(self, item, spider):
        item['purlplit'] = item['purl'].split("/")[3]
            
        return item
   
Здесь надо бы подправить комментарии (не забыть бы)

A вот из этго Write items to a JSON file я слепил pipelines_tofile.py

In [5]:
%load "C:\\Users\\kiss\\Documents\\GitMyScrapy\\scrapy_csv_2\\scrapy_csv_2\\pipelines_tofile.py"
In []:
class CsvWriterPipeline(object):
    DL = ","
    def __init__(self):
        self.file = open('items_2.csv', 'wb')

    def process_item(self, item, spider):
        line = item['purlplit'] + self.DL + item['proj_name']+"\n"
        self.file.write(line)
        return item
А здесь полуфабрикат, но ясно, что все нужные поля item можно задать в люой последовательности и с любыми разделителями... И стоило столько возиться, чтобы получить вот такую запись в файл 'items_2.csv':
In []:
catalogue,Users
catalogue,Users
catalogue,Users
Очевидно, что для запуска использовалась команда (без опции записи в файл) scrapy crawl mail_csv_2_1
Итак, все работает. "В принципе у нас все есть..." ...Надо бы добавить поддержку прокси и запустить первых спайдеров...


Посты чуть ниже также могут вас заинтересовать

Комментариев нет:

Отправить комментарий