第一次运行后,在For Loop中运行Scrapy会挂起

时间:2018-08-12 21:19:28

标签: python-3.x scrapy twisted

我想在for循环中运行Scrapy,为列表中的每个URL循环一个。 (注意:我不希望所有这些URL都为start_urls,我需要它们一次运行一个。)

第一次尝试在循环的第一次迭代后给了twisted.internet.error.ReactorNotRestartable个错误。

对SO的搜索给出了先前的答案,表明process.start(stop_after_crawl=False)应该可以解决此问题。这摆脱了Twisted错误,但现在仅在循环的第一次迭代后挂起。这不是该问题的重复。

我当前的代码是:

for url in urls:
    process = CrawlerProcess({
        'USER_AGENT': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)',
        'DEPTH_LIMIT': 4
    })

    process.crawl(MySpider, url)
    process.start(stop_after_crawl=False)

第一个URL运行正常,然后挂起:

 'response_received_count': 1,
 'scheduler/dequeued': 1,
 'scheduler/dequeued/memory': 1,
 'scheduler/enqueued': 1,
 'scheduler/enqueued/memory': 1,
 'start_time': datetime.datetime(2018, 8, 12, 21, 12, 29, 963422)}
2018-08-12 22:12:30 [scrapy.core.engine] INFO: Spider closed (finished)

2 个答案:

答案 0 :(得分:1)

为了使列表中的内容草率地循环,我认为使用“ start_requests”是个好主意:

def start_requests(self):
    with open('./input/id_urls_10k.csv','r') as csvfile:
        urlreader = csv.reader(csvfile, delimiter=',',quotechar='"')
        for row in urlreader:
            if row[1]=="y":
                yield scrapy.Request(url=row[2],meta={'urlkey':row[0]})

答案 1 :(得分:1)

您应该能够使用一些Twisted模块来做到这一点。这是一个简单的示例:

from scrapy.crawler import CrawlerRunner
from twisted.internet import defer, tasks

@tasks.react
@defer.inlineCallbacks
def crawl_my_sites(reactor):
    runner = CrawlerRunner({})
    for url in urls:
        yield runner.crawl(MySpider, url)