前一段时间做了一个定时爬虫的小demo,遇到了一个问题:
在APScheduler中循环爬虫报错:twisted.internet.error.ReactorNotRestartable
参考:https://blog.csdn.net/nicajonh/article/details/78071265
问题已解决。
原因:在同一个进程中无法重启twisted框架中的reactor堆。
解决方案:通过另外一个进程中启动reactor。
基于flask的定时爬虫代码示例如下:
修改JOBS:
现象:多个爬虫进入run_spider()会引起如上错误
解决方法:run_spider()一次入参一个爬虫;或者修改run_spider(),每次爬虫之后都进行stop reactor操作
import datetime
import os
from multiprocessing import Process
from flask import Flask, jsonify, request
from flask_apscheduler import APScheduler
from scrapy.crawler import CrawlerRunner
from scrapy.utils.log import configure_logging
from scrapy.utils.project import get_project_settings
from twisted.internet import reactor
app = Flask(__name__)
def run_spider(s):
configure_logging()
runner = CrawlerRunner(get_project_settings())
for ss in s:
runner.crawl(ss)
d = runner.join()
d.addBoth(lambda _: reactor.stop())
reactor.run()
def process1():
configure_logging()
# 创建并启动子进程,args参数为爬虫名
mp = Process(target=run_spider, args=(
["spider_爬虫1"]))
mp.start()
mp.join()
def process2():
configure_logging()
# 创建并启动子进程,args参数为爬虫名
mp = Process(target=run_spider, args=(
["spider_爬虫2"]))
mp.start()
mp.join()
class Config(object):
JOBS = [
{
'id': 'job1',
'func': process1,
'trigger': 'interval',
'hours': 24
},{
'id': 'job2',
'func': process2,
'trigger': 'cron',
'hour': 1
}
]
SCHEDULER_API_ENABLED = True
if __name__ == '__main__':
app.config.from_object(Config())
if os.environ.get('WERKZEUG_RUN_MAIN') == 'true':
scheduler = APScheduler()
scheduler.api_enabled = True
scheduler.init_app(app)
scheduler.start()
app.run(
host='0.0.0.0',
port=5001,
debug=True
)