【发布时间】:2017-05-16 08:53:47
【问题描述】:
我们正在尝试编写一个机器人,该机器人声称可以从报纸上抓取文章,这要归功于它的 rss 提要。 所以我们希望我们的脚本可以每天多次重复这个步骤:
1) 查看我们列出的 RSS 源
2) 识别我们尚未抓取的文章
3) 将链接添加到要抓取的 url 列表中
4) 抓取列出的网址
我们用这段代码实现了一次执行这些步骤:
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 列表后,是否可以暂停反应器并取消暂停? 我们还有其他解决方案吗?
[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()
【问题讨论】:
-
AFAIK twister reactor 是全球性的,因此您可以将其导入并使用它做任何您想做的事情。但是查看您的代码,我认为这不是您想要做的。通常人们用好的 ol' crontabs 来解决这个问题。安排
cd project && scrapy crawl spider每 8 小时运行一次,一切顺利!如果您想要更多的原子 url 分发,我建议您查看 redis 或更具体地说是scrapy-redis -
感谢您的回答。事实上,我们想做一个脚本,我们执行一次并重复我们的循环(例如每两个小时),直到我们手动停止脚本运行。我们的循环包括执行我们上面解释的步骤 1 到 4。但是是否有可能为已经打开的扭曲反应堆提供爬行?
-
为什么?长时间运行循环几乎总是一个坏主意,只是一个 cron 或 systemd 作业。
-
我是一个编程菜鸟,所以我不是很了解所有内容。请你能解释一下什么时候这可能是个坏主意吗?您对 cron 是正确的,但理想情况下,如果有另一个不太复杂的解决方案会更好,因为我们希望稍后再使用该程序并在其他计算机上升级它。感谢您抽出宝贵时间回答我们的问题。
-
不要使用
time.sleep这是一个阻塞调用,会阻塞reactor直到睡眠结束