2016-02-26 4 views
2

Я пытаюсь написать общий паук «Мастер», который я использую с «start_urls» и «allowed_domains», динамически вставленным во время выполнения. (. В конце концов, у меня будет это в базе данных, что я буду тянуть, а затем использовать для инициализации и ползать новый паук для каждой записи БД)Динамическое создание пауков с ошибкой инициализации подкласса Scrapy

На данный момент у меня есть два файла:

  1. MySpider.py - Устанавливает мой «магический» класс пауков.
  2. RunSpider.py - доказательство концепции для выполнения инициализации моих динамически генерируемых пауков.

Для записи этих двух файлов, я ссылается на следующее:

Я считал scrapyD, но я не думаю, что его то, что я ищу ...

Вот что я написал:

MySpider.py -

import scrapy 

class BlackSpider(scrapy.Spider): 
    name = 'Black1' 

    def __init__(self, allowed_domains=[], start_urls=[], *args, **kwargs): 
     super(BlackSpider, self).__init__(*args, **kwargs) 
     self.start_urls = start_urls 
     self.allowed_domains = allowed_domains 
     #For Testing: 
     print start_urls 
     print self.start_urls 
     print allowed_domains 
     print self.allowed_domains 

    def parse(self, response): 
     ############################# 
     # Insert my parse code here # 
     ############################# 
     return items 

RunSpider.py -

import scrapy 
from scrapy.crawler import CrawlerProcess 
from MySpider import BlackSpider 

#Set my allowed domain (this will come from DB later) 
ad = ["example.com"] 
#Set my start url 
sd = ["http://example.com/files/subfile/dir1"] 

#Initialize MySpider with the above allowed domain and start url 
MySpider = BlackSpider(ad,sd) 

#Crawl MySpider 
process = CrawlerProcess({ 
    'USER_AGENT': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)' 
}) 
process.crawl(MySpider) 
process.start() 

ПРОБЛЕМА:

Вот моя проблема - Когда я выполняю это, по-видимому, успешно передать мои аргументы для allowed_domains и start_urls; ОДНАКО, после того, как MySpider инициализирован, когда я запускаю паук для обхода, указанные URL/домены больше не найдены, и ни один веб-сайт не сканируется. Я добавил оператор печати выше, чтобы показать это:

[email protected]:~/$ python RunSpider.py 
['http://example.com/files/subfile/dir1'] 
['http://example.com/files/subfile/dir1'] 
['example.com'] 
['example.com'] 
2016-02-26 16:11:41 [scrapy] INFO: Scrapy 1.0.5 started (bot: scrapybot) 
... 
2016-02-26 16:11:41 [scrapy] INFO: Overridden settings: {'USER_AGENT': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)'} 
... 
[] 
[] 
[] 
[] 
2016-02-26 16:11:41 [scrapy] INFO: Spider opened 
... 
2016-02-26 16:11:41 [scrapy] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min) 
... 
2016-02-26 16:11:41 [scrapy] INFO: Closing spider (finished) 
... 
2016-02-26 16:11:41 [scrapy] INFO: Spider closed (finished) 

Почему мой паук инициализирован правильно, но когда я пытаюсь выполнить паук URL-адрес отсутствует? Является ли это основной ошибкой программирования Python (класс?), Которую я просто пропустил?

ответ

2

Пожалуйста, обратитесь к documentation on CrawlerProcess

  • CrawlerProcess.crawl() ожидает либо crawler или scrapy.Spider подкласс, а не экземпляр Spider
  • аргументы паука должны быть переданы в качестве дополнительных аргументов .crawl()

Итак, вам нужно сделать что-то вроде этого:

import scrapy 
from scrapy.crawler import CrawlerProcess 
from myspider import BlackSpider 

#Set my allowed domain (this will come from DB later) 
ad = ["example.com"] 
#Set my start url 
sd = ["http://example.com/files/subfile/dir1"] 

#Crawl MySpider 
process = CrawlerProcess({ 
    'USER_AGENT': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)' 
}) 
# pass Spider class, and other params as keyword arguments 
process.crawl(MySpider, allowed_domains=ad, start_urls=sd) 
process.start() 

Вы можете увидеть это в действии с командами себя SCRAPY, for example scrapy runspider:

def run(self, args, opts): 
    ... 
    spidercls = spclasses.pop() 

    self.crawler_process.crawl(spidercls, **opts.spargs) 
    self.crawler_process.start() 
+0

Это решило мою проблему полностью. Большое вам спасибо за ссылки и ваш подробный ответ, Пол! – JLR