Передать аргумент пауку scrapy в скрипте Python

Я могу запустить сканирование в скрипте Python со следующим рецептом из вики:

from twisted.internet import reactor
from scrapy.crawler import Crawler
from scrapy import log, signals
from testspiders.spiders.followall import FollowAllSpider
from scrapy.utils.project import get_project_settings

spider = FollowAllSpider(domain='scrapinghub.com')
settings = get_project_settings()
crawler = Crawler(settings)
crawler.signals.connect(reactor.stop, signal=signals.spider_closed)
crawler.configure()
crawler.crawl(spider)
crawler.start()
log.start()
reactor.run()

Как видите, я могу просто передать domain в FollowAllSpider, но мой вопрос в том, как я могу передать start_urls (на самом деле date, который будет добавлен к фиксированному URL-адресу) в мой класс паука, используя приведенный выше код?

это мой класс пауков:

class MySpider(CrawlSpider):
    name = 'tw'
    def __init__(self,date):
        y,m,d=date.split('-') #this is a test , it could split with regex! 
        try:
            y,m,d=int(y),int(m),int(d)

        except ValueError:
            raise 'Enter a valid date'

        self.allowed_domains = ['mydomin.com']
        self.start_urls = ['my_start_urls{}-{}-{}'.format(y,m,d)]

    def parse(self, response):
        questions = Selector(response).xpath('//div[@class="result-link"]/span/a/@href') 
        for question in questions:
            item = PoptopItem()
            item['url'] = question.extract()
            yield item['url']

и это мой сценарий:

from pdfcreator import convertor
from twisted.internet import reactor
from scrapy.crawler import Crawler
from scrapy import log, signals
#from testspiders.spiders.followall import FollowAllSpider
from scrapy.utils.project import get_project_settings
from poptop.spiders.stackoverflow_spider import MySpider
from poptop.items import PoptopItem

settings = get_project_settings()
crawler = Crawler(settings) 
crawler.signals.connect(reactor.stop, signal=signals.spider_closed)
crawler.configure()

date=raw_input('Enter the date with this format (d-m-Y) : ')
print date
spider=MySpider(date=date)
crawler.crawl(spider)
crawler.start()
log.start()
item=PoptopItem()

for url in item['url']:
    convertor(url)

reactor.run() # the script will block here until the spider_closed signal was sent

Если я просто напечатаю item, я получу следующую ошибку:

2015-02-25 17:13:47+0330 [tw] ERROR: Spider must return Request, BaseItem or None, got 'unicode' in <GET test-link2015-1-17>

Предметы:

import scrapy


class PoptopItem(scrapy.Item):
    titles= scrapy.Field()
    content= scrapy.Field()
    url=scrapy.Field()

person kasravnd    schedule 24.02.2015    source источник


Ответы (1)


Вам нужно изменить конструктор __init__(), чтобы он принимал аргумент date. Кроме того, я бы использовал datetime.strptime() для анализа даты нить:

from datetime import datetime

class MySpider(CrawlSpider):
    name = 'tw'
    allowed_domains = ['test.com']

    def __init__(self, *args, **kwargs):
        super(MySpider, self).__init__(*args, **kwargs) 

        date = kwargs.get('date')
        if not date:
            raise ValueError('No date given')

        dt = datetime.strptime(date, "%m-%d-%Y")
        self.start_urls = ['http://test.com/{dt.year}-{dt.month}-{dt.day}'.format(dt=dt)]

Затем вы должны создать экземпляр паука следующим образом:

spider = MySpider(date='01-01-2015')

Или вы даже можете вообще не анализировать дату, передав экземпляр datetime в первую очередь:

class MySpider(CrawlSpider):
    name = 'tw'
    allowed_domains = ['test.com']

    def __init__(self, *args, **kwargs):
        super(MySpider, self).__init__(*args, **kwargs) 

        dt = kwargs.get('dt')
        if not dt:
            raise ValueError('No date given')

        self.start_urls = ['http://test.com/{dt.year}-{dt.month}-{dt.day}'.format(dt=dt)]

spider = MySpider(dt=datetime(year=2014, month=01, day=01))

И, к сведению, см. этот ответ в качестве подробного примера того, как запустить Скрейпинг из скрипта.

person alecxe    schedule 24.02.2015
comment
Большое спасибо за объяснение! как я уже сказал, анализатор времени - это тест! а также спасибо за предложение ссылки, теперь, когда вы видите, что моя функция parse дает url, как я могу это получить? (после запуска обхода) - person kasravnd; 25.02.2015
comment
Я использовал элементы, но он поднял KeyError, кажется, он не запускает сканирование !! for url in item['url']: - person kasravnd; 25.02.2015
comment
@KasraAD Я думаю, вам просто нужно yield item вместо yield item['url']. Дайте мне знать, помогло это или нет. - person alecxe; 25.02.2015
comment
В моем пауке я только что yield item снова увидел эту ошибку! я отредактирую вопрос! добавляю свой скрипт! надеюсь, что это может помочь! - person kasravnd; 25.02.2015
comment
@KasraAD две вещи: 1. почему вы создаете экземпляр элемента внутри скрипта, в котором вы запускаете сканирование (я думаю, вам это здесь не нужно). Если вы хотите постобработать элемент, возвращенный пауком, - сделайте это в трубопровод. 2. Можете ли вы также показать определение класса PoptopItem. Спасибо. - person alecxe; 25.02.2015
comment
да, я добавляю это, на самом деле я новичок в scrapy! и я не работал с конвейером, но все, что мне здесь нужно, это иметь возможность получить question.extract() внутри моего скрипта! - person kasravnd; 25.02.2015