2016-09-22 1 views
1

После новой установки Miniconda 64-битный ех установки для Windows, и Python 2.7 на Windows 7, через которые я получаю Scrapy, вот что установлено:Scrapy API - Паук инициализировать класс аргумент превратился в None

  • Python 2.7.12
  • Scrapy 1.1.1
  • Twisted 16.4.1

Это минимальный код, бегите от "питона scrapy_test.py" (с использованием Scrapy API):

#!/usr/bin/env python2.7 
# -*- coding: utf-8 -*- 

import scrapy.spiders.crawl 
import scrapy.crawler 
import scrapy.utils.project 

class MySpider(scrapy.spiders.crawl.CrawlSpider) : 
    name = "stackoverflow.com" 
    allowed_domains = ["stackoverflow.com"] 
    start_urls = ["http://stackoverflow.com/"] 
    download_delay = 1.5 

    def __init__(self, my_arg = None) : 
     print "def __init__" 

     self.my_arg = my_arg 
     print "self.my_arg" 
     print self.my_arg 

    def parse(self, response) : 
     pass 

def main() : 
    my_arg = "Value" 

    process = scrapy.crawler.CrawlerProcess(scrapy.utils.project.get_project_settings()) 
    process.crawl(MySpider(my_arg)) 
    process.start() 

if __name__ == "__main__" : 
    main() 

дает этот поток вывод:

[scrapy] INFO: Scrapy 1.1.1 started (bot: scrapy_project) 
[scrapy] INFO: Overridden settings: {'NEWSPIDER_MODULE': 'scrapy_project.spiders', 'SPIDER_MODULES': ['scrapy_project.spiders'], 'ROBOTSTXT_OBEY': True, 'BOT_NAME': 'scrapy_project'} 
def __init__ 
self.my_arg 
Value 
[scrapy] INFO: Enabled extensions: 
['scrapy.extensions.logstats.LogStats', 
'scrapy.extensions.telnet.TelnetConsole', 
'scrapy.extensions.corestats.CoreStats'] 
def __init__ 
self.my_arg 
None 
[...] 

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

Если я изменю:

def __init__(self, my_arg = None) : 

к:

def __init__(self, my_arg) : 

выход:

[...] 
Unhandled error in Deferred: 
[twisted] CRITICAL: Unhandled error in Deferred: 


Traceback (most recent call last): 
    File "scrapy_test.py", line 28, in main 
    process.crawl(MySpider(my_arg)) 
    File "C:\Users\XYZ\Miniconda2\lib\site-packages\scrapy\crawler.py", line 163, in crawl 
    return self._crawl(crawler, *args, **kwargs) 
    File "C:\Users\XYZ\Miniconda2\lib\site-packages\scrapy\crawler.py", line 167, in _crawl 
    d = crawler.crawl(*args, **kwargs) 
    File "C:\Users\XYZ\Miniconda2\lib\site-packages\twisted\internet\defer.py", line 1331, in unwindGenerator 
    return _inlineCallbacks(None, gen, Deferred()) 
--- <exception caught here> --- 
    File "C:\Users\XYZ\Miniconda2\lib\site-packages\twisted\internet\defer.py", line 1185, in _inlineCallbacks 
    result = g.send(result) 
    File "C:\Users\XYZ\Miniconda2\lib\site-packages\scrapy\crawler.py", line 90, in crawl 
    six.reraise(*exc_info) 
    File "C:\Users\XYZ\Miniconda2\lib\site-packages\scrapy\crawler.py", line 71, in crawl 
    self.spider = self._create_spider(*args, **kwargs) 
    File "C:\Users\XYZ\Miniconda2\lib\site-packages\scrapy\crawler.py", line 94, in _create_spider 
    return self.spidercls.from_crawler(self, *args, **kwargs) 
    File "C:\Users\XYZ\Miniconda2\lib\site-packages\scrapy\spiders\crawl.py", line 96, in from_crawler 
    spider = super(CrawlSpider, cls).from_crawler(crawler, *args, **kwargs) 
    File "C:\Users\XYZ\Miniconda2\lib\site-packages\scrapy\spiders\__init__.py", line 50, in from_crawler 
    spider = cls(*args, **kwargs) 
exceptions.TypeError: __init__() takes exactly 2 arguments (1 given) 
[twisted] CRITICAL: 
Traceback (most recent call last): 
    File "C:\Users\XYZ\Miniconda2\lib\site-packages\twisted\internet\defer.py", line 1185, in _inlineCallbacks 
    result = g.send(result) 
    File "C:\Users\XYZ\Miniconda2\lib\site-packages\scrapy\crawler.py", line 90, in crawl 
    six.reraise(*exc_info) 
    File "C:\Users\XYZ\Miniconda2\lib\site-packages\scrapy\crawler.py", line 71, in crawl 
    self.spider = self._create_spider(*args, **kwargs) 
    File "C:\Users\XYZ\Miniconda2\lib\site-packages\scrapy\crawler.py", line 94, in _create_spider 
    return self.spidercls.from_crawler(self, *args, **kwargs) 
    File "C:\Users\XYZ\Miniconda2\lib\site-packages\scrapy\spiders\crawl.py", line 96, in from_crawler 
    spider = super(CrawlSpider, cls).from_crawler(crawler, *args, **kwargs) 
    File "C:\Users\XYZ\Miniconda2\lib\site-packages\scrapy\spiders\__init__.py", line 50, in from_crawler 
    spider = cls(*args, **kwargs) 
TypeError: __init__() takes exactly 2 arguments (1 given) 

Понятия не имею, как обойти эту проблему. Есть идеи?

+1

Проверить http://stackoverflow.com/questions/36689190/how-to-pass-parameters-to-scrapy-spiders-in-program/36691285#36691285 и http://doc.scrapy.org/en /latest/topics/api.html#scrapy.crawler.CrawlerProcess. 'CrawlerProcess'' .crawl()' ожидает класс паука *, а не экземпляр паука. Передача аргументов выполняется с помощью 'process.crawl (MySpider, my_arg = myvalue)' –

+0

@paultrmbrth Вот оно! И официальный документ прав.Я упускал из виду тот факт, что сам класс_ должен быть передан как аргумент, а не экземпляр этого класса. Это довольно тонко на глаза, но все имеет значение. – Ooxie

+0

Кажется, это легко пропустить. Я открыл https://github.com/scrapy/scrapy/issues/2283 –

ответ

4

Вот определение метода для scrapy.crawler.CrawlerProcess.crawl():

crawl(crawler_or_spidercls, *args, **kwargs)

  • crawler_or_spidercls (Crawler экземпляр, Spider подкласс или строка) - уже создан гусеничный или класс паука или имя паука в проекте для его создания
  • args (список) - аргументы для инициализации паука
  • kwargs (Dict) - ключевые аргументы для инициализации Паучьей

Это означает, что вы должны передать имя ваш Spider отдельно от kwargs, необходимых для инициализации Spider, например:

process.crawl(MySpider, my_arg = 'Value') 
+0

Да, и вы можете добавить 'args' в' kwargs', для полноты. Также центральная проблема заключается в том, чтобы заметить, что это имя класса, а не экземпляр класса (т. Е. Объект), который ожидается в качестве основного аргумента. – Ooxie

Смежные вопросы