如何提供目前运行的扭曲反应器?
How to provide a twisted reactor which is currently running?
我们正在尝试编写一个机器人,它声称可以从报纸上抓取文章,这要归功于它的 RSS 提要。
所以我们希望我们的脚本每天可以多次重复这个步骤:
1) 查看我们列出的 rss 提要
2) 识别我们尚未抓取的文章
3) 将链接添加到要抓取的 url 列表
4) 抓取列出的 url
我们用这段代码实现一次执行这些步骤:
rss_feeds_lemonde = [
'http://www.lemonde.fr/rss/une.xml',
'http://www.lemonde.fr/international/rss_full.xml',
'http://www.lemonde.fr/politique/rss_full.xml',
]
db = sqlite3.connect('newspaper_db')
cursor = db.cursor()
urls = []
already_met = False
site = 'lemonde'
for rss_feed in rss_feeds_lemonde:
parsed_rss_feed = feedparser.parse(rss_feed)
for post in parsed_rss_feed.entries:
url = post.link
if url.split('.')[1] == site:
cursor.execute('''SELECT url FROM articles WHERE newspaper = site''')
rows = cursor.fetchall()
for row in rows:
if row[0] == url:
already_met = True
if already_met == False:
cursor.execute('''INSERT INTO articles(url, newspaper) VALUES(?,?)''', (url, site))
urls.append(url)
else:
already_met = False
cursor.close()
db.commit()
db.close()
if urls != []:
process = CrawlerProcess()
process.crawl(LeMondeSpider, start_urls = urls)
process.start()
问题是扭曲的反应器不可重启,所以它允许我们执行一次我们的步骤。在我们提供新的要抓取的 url 列表后,是否可以暂停 reactor 并取消暂停?
我们还有其他解决方案吗?
[edit] for notorious.no,这个例子现在可以正常工作了,多亏了你!
def run_when_crawl_done(null):
time.sleep(10)
urls = [
'http://www.lefigaro.fr/elections/presidentielles/2017/05/05/35003-20170505ARTFIG00129-comment-ils-veulent-bloquer-le-pen-sans-soutenir-macron-ce-dimanche.php',
'http://www.lefigaro.fr/elections/presidentielles/2017/05/04/35003-20170504ARTFIG00259-si-marine-le-pen-atteint-40-ca-serait-deja-une-enorme-victoire-dit-sa-niece.php',
'http://www.lefigaro.fr/elections/presidentielles/2017/05/04/35003-20170504ARTFIG00126-emmanuel-macron-non-je-n-ai-pas-de-compte-aux-bahamas.php',
]
deffered = runner.crawl(LeFigaroSpider, start_urls = urls)
deffered.addCallback(lambda _: reactor.stop())
urls = [
'http://www.lemonde.fr/les-decodeurs/article/2017/04/26/europe-macron-emploi-la-trumpisation-de-marine-le-pen-sur-tf1_5117479_4355770.html',
'http://www.lemonde.fr/syrie/article/2017/04/26/attaque-chimique-la-france-avance-ses-preuves-contre-damas_5117652_1618247.html',
]
if urls != []:
configure_logging()
runner = CrawlerRunner()
deferred = runner.crawl(LeMondeSpider, start_urls = urls)
deferred.addCallback(run_when_crawl_done)
reactor.run()
Twisted的reactor确实无法重启。如果你想一想,你会意识到停止一个事件循环,只是让另一个事件启动它,是违反直觉的。大多数事件驱动的应用程序都是 "long running",除非出现严重错误,否则不应停止。
不要启动-停止-重启事件循环。启动该应用程序,然后永远不要重新启动它(您正在制作一个机器人,所以我假设该机器人从不休眠)。使用 CrawlerRunner
而不是 CrawlerProcess
然后执行 reactor.run()
。这允许更多的灵活性,并允许您同时 运行 更多任务。
def run_when_crawl_done(null):
"""
logic that will be executed after the crawl is done
"""
if urls:
runner = CrawlerRunner()
deferred = runner.crawl(LeMondeSpider, start_urls=urls)
deferred.addCallback(run_when_crawl_done)
reactor.run()
如果你真的想有一个 python 循环 运行 并充当爬行调度程序(这通常不是一个好主意)你应该使用 subprocess
模块来生成一些抓取过程:
import subprocess
import time
while True:
subprocess.open('cd project && scrapy crawl spider')
time.sleep(60 * 30)
你们所有人 sql 逻辑应该放在蜘蛛本身而不是执行脚本中。
我们正在尝试编写一个机器人,它声称可以从报纸上抓取文章,这要归功于它的 RSS 提要。 所以我们希望我们的脚本每天可以多次重复这个步骤:
1) 查看我们列出的 rss 提要
2) 识别我们尚未抓取的文章
3) 将链接添加到要抓取的 url 列表
4) 抓取列出的 url
我们用这段代码实现一次执行这些步骤:
rss_feeds_lemonde = [
'http://www.lemonde.fr/rss/une.xml',
'http://www.lemonde.fr/international/rss_full.xml',
'http://www.lemonde.fr/politique/rss_full.xml',
]
db = sqlite3.connect('newspaper_db')
cursor = db.cursor()
urls = []
already_met = False
site = 'lemonde'
for rss_feed in rss_feeds_lemonde:
parsed_rss_feed = feedparser.parse(rss_feed)
for post in parsed_rss_feed.entries:
url = post.link
if url.split('.')[1] == site:
cursor.execute('''SELECT url FROM articles WHERE newspaper = site''')
rows = cursor.fetchall()
for row in rows:
if row[0] == url:
already_met = True
if already_met == False:
cursor.execute('''INSERT INTO articles(url, newspaper) VALUES(?,?)''', (url, site))
urls.append(url)
else:
already_met = False
cursor.close()
db.commit()
db.close()
if urls != []:
process = CrawlerProcess()
process.crawl(LeMondeSpider, start_urls = urls)
process.start()
问题是扭曲的反应器不可重启,所以它允许我们执行一次我们的步骤。在我们提供新的要抓取的 url 列表后,是否可以暂停 reactor 并取消暂停? 我们还有其他解决方案吗?
[edit] for notorious.no,这个例子现在可以正常工作了,多亏了你!
def run_when_crawl_done(null):
time.sleep(10)
urls = [
'http://www.lefigaro.fr/elections/presidentielles/2017/05/05/35003-20170505ARTFIG00129-comment-ils-veulent-bloquer-le-pen-sans-soutenir-macron-ce-dimanche.php',
'http://www.lefigaro.fr/elections/presidentielles/2017/05/04/35003-20170504ARTFIG00259-si-marine-le-pen-atteint-40-ca-serait-deja-une-enorme-victoire-dit-sa-niece.php',
'http://www.lefigaro.fr/elections/presidentielles/2017/05/04/35003-20170504ARTFIG00126-emmanuel-macron-non-je-n-ai-pas-de-compte-aux-bahamas.php',
]
deffered = runner.crawl(LeFigaroSpider, start_urls = urls)
deffered.addCallback(lambda _: reactor.stop())
urls = [
'http://www.lemonde.fr/les-decodeurs/article/2017/04/26/europe-macron-emploi-la-trumpisation-de-marine-le-pen-sur-tf1_5117479_4355770.html',
'http://www.lemonde.fr/syrie/article/2017/04/26/attaque-chimique-la-france-avance-ses-preuves-contre-damas_5117652_1618247.html',
]
if urls != []:
configure_logging()
runner = CrawlerRunner()
deferred = runner.crawl(LeMondeSpider, start_urls = urls)
deferred.addCallback(run_when_crawl_done)
reactor.run()
Twisted的reactor确实无法重启。如果你想一想,你会意识到停止一个事件循环,只是让另一个事件启动它,是违反直觉的。大多数事件驱动的应用程序都是 "long running",除非出现严重错误,否则不应停止。
不要启动-停止-重启事件循环。启动该应用程序,然后永远不要重新启动它(您正在制作一个机器人,所以我假设该机器人从不休眠)。使用 CrawlerRunner
而不是 CrawlerProcess
然后执行 reactor.run()
。这允许更多的灵活性,并允许您同时 运行 更多任务。
def run_when_crawl_done(null):
"""
logic that will be executed after the crawl is done
"""
if urls:
runner = CrawlerRunner()
deferred = runner.crawl(LeMondeSpider, start_urls=urls)
deferred.addCallback(run_when_crawl_done)
reactor.run()
如果你真的想有一个 python 循环 运行 并充当爬行调度程序(这通常不是一个好主意)你应该使用 subprocess
模块来生成一些抓取过程:
import subprocess
import time
while True:
subprocess.open('cd project && scrapy crawl spider')
time.sleep(60 * 30)
你们所有人 sql 逻辑应该放在蜘蛛本身而不是执行脚本中。