首页 > 解决方案 > 如何使我可以始终使用单个scrapy蜘蛛绕过站点列表?

问题描述

我编写了从Python脚本启动scrapy spider的代码。现在,我想要始终绕过网站列表,即我为一个网站运行spider,当它完成抓取时,我关闭spider并重复调用另一个网站。

from scrapy.crawler import CrawlerProcess
from scrapy.utils.project import get_project_settings
from datetime import datetime
start_urls=['https://sentek.ru/','http://www.s-kab.ru/',https://sevkab.nt-rt.ru/',http://www.mikroprovod.ru/']

for start_url in start_urls:
    process = CrawlerProcess(get_project_settings())
    domain = start_url.split('//')[-1].split('/')[0].split('www.')[-1]
    current_time = datetime.now().strftime('%Y-%m-%d')
    current_time = current_time.replace("-", ".")
    process.crawl('procurement', start_url=start_url,domain=domain,time=current_time)
    process.start()

但是 twisted.internet.error.ReactorNotRestartable 当我开始抓取第二个站点时会出现错误。我知道这是由于 TwistedReactor 的特性导致它无法重新启动。我想知道,有没有办法让反应堆运行一次并总是在其中重新创建蜘蛛它?谢谢关注!:)

更新!解决方案我决定为每个蜘蛛创建单独的进程,为此我使用了多处理库。这有助于避免错误twisted.internet.error.ReactorNotRestartable并执行顺序抓取网站。这是代码:

from scrapy.crawler import CrawlerProcess
from scrapy.utils.project import get_project_settings
from datetime import datetime
from multiprocessing import Process

def create_spider(start_url):
    process = CrawlerProcess(get_project_settings())
    domain = start_url.split('//')[-1].split('/')[0].split('www.')[-1]
    current_time = datetime.now().strftime('%Y-%m-%d')
    current_time = current_time.replace("-", ".")
    process.crawl('procurement', start_url=start_url, domain=domain, 
    time=current_time)
    process.start()

 if __name__ == '__main__':
    start_urls = [
                  'http://www.samaracable.ru/',
              'http://www.skz67.ru/', 'http://www.uralcable.ru/',
              'http://www.ufimcabel.ru/', 'http://www.chuvashcable.ru/', 
              'https://uncomtech.ru/']
   for start_url in start_urls:
       proc = Process(target=create_spider, args=(start_url,))
       proc.start()
       proc.join()

标签: pythonscrapytwisted

解决方案


您的代码非常接近工作,您只是错过了一个重要的细节。CrawlProcess实际上是为同时运行多个蜘蛛而设计的!

CrawlProcess
在一个进程中同时运行多个scrapy爬虫的类。

因此,要解决这个问题,您需要做的就是将CrawlProcess对象的创建和开始移到循环之外:

process = CrawlerProcess(get_project_settings())
^^^
for start_url in start_urls:
    domain = start_url.split('//')[-1].split('/')[0].split('www.')[-1]
    current_time = datetime.now().strftime('%Y-%m-%d')
    current_time = current_time.replace("-", ".")
    process.crawl('procurement', start_url=start_url,domain=domain,time=current_time)
process.start()
^^^

推荐阅读