как динамически создать файл csv с именами пауков в scrapy python

Я работаю над скраппингом, очистил сайт и получил всю информацию

На самом деле у меня было 3 паука с разными данными, я создал эти 3 паука в одной папке со следующей структурой

scrapy.cfg
myproject/
    __init__.py
    items.py
    pipelines.py
    settings.py
    spiders/
         __init__.py
           spider1.py
           spider2.py
           spider3.py

Теперь, когда мы запускаем этот конкретный паук, мне нужно создать CSV-файл через конвейер с этим именем паука, например.

spider1.csv,spider2.csv,spider3.csv and so on (Пауки не ограничены, их может быть больше)> В соответствии с количеством пауков и именами пауков я хочу создать файлы csv

Здесь, можем ли мы создать более одного конвейера в pipe.py? также как создать файл csv с именем паука динамически, если существует более одного паука

Здесь у меня было 3 паука, и я хочу запустить все 3 паука одновременно (с помощью scrapyd), когда я запускаю все 3 паука, должны быть созданы 3 CSV-файла с их именами пауков. И я хочу запланировать запуск этих пауков каждые 6 часов. Если что-то не так в моем объяснении, пожалуйста, поправьте меня и дайте мне знать, как этого добиться.

заранее спасибо

Отредактированный код. Например, я вставляю свой код только для spider1.py.

код в Spider1.py:

class firstspider(BaseSpider):
    name = "spider1"
    domain_name = "www.example.com"
    start_urls = [
                   "www.example.com/headers/page-value"
                 ]
def parse(self, response):
    hxs = HtmlXPathSelector(response)
            ........
            .......
            item = Spider1Item()
            item['field1'] = some_result
            item['field2'] = some_result
            .....
            .....
            return item

Код Pipeline.py:

import csv
from csv import DictWriter

class firstspider_pipeline(object):

def __init__(self):
    self.brandCategoryCsv = csv.writer(open('../%s.csv' % (spider.name), 'wb'),
    delimiter=',', quoting=csv.QUOTE_MINIMAL)
    self.brandCategoryCsv.writerow(['field1', 'field2','field3','field4'])



def process_item(self, item, spider):
    self.brandCategoryCsv.writerow([item['field1'],
                                item['field2'],
                                item['field3'],
                                item['field4'])
    return item 

Как я уже говорил, когда я запускаю вышеуказанный паук с именем паука, CSV-файл с именем паука будет создаваться динамически..... но теперь, когда я запускаю остальные пауки, такие как spider2,spider3,spider3 , CSV-файлы с соответствующими именами пауков должен генерировать.

  1. достаточно ли приведенного выше кода для вышеуказанной функциональности?

  2. нужно ли нам создать еще один класс конвейера для создания другого CSV-файла? (Возможно ли создать более одного класса конвейера в одном файле pipe.py?)

  3. Если мы создадим несколько классов конвейера в одном файле pipe.py, как сопоставить конкретного паука с соответствующим классом конвейера

Я хочу добиться той же функциональности при сохранении в базу данных, я имею в виду, что когда я запускаю паука1, все данные паука1 должны сохраняться в базе данных в таблицу с относительным именем паука. Здесь для каждого паука у меня были разные запросы sql (поэтому нужно писать разные классы конвейера)

  1. Здесь намерение заключается в том, что когда мы запускаем несколько пауков одновременно (используя scrapyd), несколько файлов csv должны генерироваться с их именами пауков, а несколько таблиц должны создаваться с именами пауков (при сохранении в базу данных).

Извините, если я где-то ошибаюсь, я надеюсь, что это хорошо объяснено, а если нет, пожалуйста, дайте мне знать.


person Shiva Krishna Bavandla    schedule 05.07.2012    source источник
comment
Покажите нам код, что вы уже пробовали? Или покажите нам хотя бы свое представление об интерфейсе / API, который вы имели в виду.   -  person Don Question    schedule 05.07.2012
comment
@Don Вопрос: я обновил свой код выше, пожалуйста, объясните мне, как это сделать   -  person Shiva Krishna Bavandla    schedule 06.07.2012


Ответы (1)


Вы в целом на правильном пути.

Но есть некоторые моменты, которые я могу сразу отметить:

  1. Вероятно, вам не нужен (= не следует использовать) класс! Питон это не Ява. Если ваш класс состоит только из двух методов, и первый из них - метод __init__, вам почти наверняка не нужен класс, но функция вполне подойдет. Меньше беспорядка = лучший код!

  2. SO — неподходящее место для общего обзора кода. Вместо этого попробуйте codereview. SO-пользователи дружелюбны (в основном) и готовы помочь, но им не нравится писать ваш код. Они любят объяснять, советовать и исправлять. Поэтому попробуйте реализовать свое приложение, и если у вас возникнут проблемы, которые вы не сможете решить самостоятельно, вернитесь снова и попросите совета. Как было сказано выше, вы концептуально на правильном пути, просто попытайтесь реализовать его.

  3. Вы, кажется, неправильно понимаете понятие класса. По крайней мере, пока это python-классы:

    1. Насколько я понимаю, вам не нужен класс BaseSpider. В чем будет разница между базовым классом и подклассами? Получение классов не делает вашу программу объектно-ориентированной или лучше, или что-то в этом роде. Найдите принцип Лискова, чтобы получить общее представление о том, когда подкласс может быть уместным. в питоне. (Это несколько обратная логика, но это один из самых быстрых способов увидеть, следует ли вам создать подкласс или изменить свой подход.)

    2. Существует четкое различие между переменными класса python, которые объявляются сразу после объявления класса, и переменными экземпляра, которые инициализируются в методе __init__. Переменные класса являются ОБЩИМИ между всеми экземплярами класса, где переменные экземпляра являются частными для отдельных экземпляров. Вы почти никогда не хотите использовать переменные класса, которые являются Singleton-Pattern, чего вы хотите избежать в большинстве случаев, потому что это вызывает головную боль и недовольство при отладке.

Поэтому я бы изменил ваш Spider-класс, например:

class Spider(object):
    def __init__(self, name, url=None):
        self.name = name
        self.domain_name = url
        self.start_urls = [url]
        ...

crawlers = [Spider('spider %s' %i) for i in xrange(4)] #creates a list of 4 spiders 

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

Если вы хотите запускать поисковые роботы параллельно, вам следует рассмотреть модуль threading. Он предназначен для последовательных операций ввода-вывода, в отличие от модуля multiprocessing, предназначенного для параллельных вычислений.

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

Только не рассчитывайте получить исчерпывающий ответ на вопрос типа: "Я не хочу воссоздавать Google, как мне сделать это наилучшим образом и в кратчайшие сроки!" ;-)

person Don Question    schedule 06.07.2012