scrapy如何接受外部传递的参数
发布时间丨2022-04-06 16:09:08作者丨zhaomeng浏览丨22
Scrapy作为爬虫框架的一哥,自然不是简简单单就能了解透彻他的。我们通常都是使用scrapy作为爬虫开发的首选框架。那么们通常都没有给它通过外部传递参数,都是在重写start_requests方法。以及使用分布式的方式接受传递的参数。好像重来没有在外部调用我们的scrapy爬虫并传递参数给他。那么本片博文是接上一篇的百度排名查询的。我想将百度排名做成一个可以通过直接调用并传递参数的的工具。那么希望在浏览器的页面上输入一些关键词并传递给爬虫。开启一个爬虫去采集。本篇博文的主要是记录如何向scrapy传递参数。
首先查阅资料发现只需要在scrapy 的爬虫项目里面添加一个初始化的方法,用于接受外部的参数就可以了,初始化代码如下:
# 这里初始化这个类,可以动态传值并开始爬虫,这里传的是datas
def __init__(self, datas=None, *args, **kwargs):
super(PmSpider, self).__init__(*args, **kwargs)
# self.start_urls = []
if datas is None:
datas = []
self.datas = datas
在这里添加了这样的初始化代码后,就可以像类一样在start_requets(self)函数中调用传递的参数如下图:
def start_requests(self):
for data in eval(self.datas):
word = data.get("keyword")
nums = data.get("page", 1)
author = data.get("author", "")
source = data.get("source", "")
print(word)
就可以输出刚才传递的datas这个参数的内容了。
那么我们怎么运行这个爬虫呢?及如何给它传递参数呢?又该如何调用这个爬虫?
调用爬虫我们使用的还是常规的调用命令,传递参数只需要加上相应的参数-a即可本地运行了,运行代码如下:
from scrapy.cmdline import execute
execute("scrapy crawl pm -a datas=[{'keyword':'17659-49-3','source':'0000000','author':'zm'},{'keyword':'252364-22-0','source':'0000000','author':'zm'}]".split())
怎么调用这个爬虫的呢?这里就需要我们将爬虫发布到scrapyd服务器了。然后调用api去运行。
第一步封装运行爬虫的接口,并传递参数,代码如下:
def start_spider(project, spider, datas=None):
# 运行一个爬虫
url = "http://127.0.0.1:6800/schedule.json"
data = {
"project": project,
"spider": spider,
}
if datas:
data["datas"] = datas
res = requests.post(url, data=data)
return res.json()
第二步:获取运行的爬虫的jobid,用于判断爬虫是否运行及是否完成
def get_jobs(project):
# 获取爬虫运行的任务jobs
url = "http://192.168.1.175:6800/listjobs.json?project={}".format(project)
res = requests.get(url)
return res.json()
第三步:判读爬虫是否运行完毕,运行完毕就返回一个完成的状态个前端页面,通知用户采集完成。
def spider_status(id):
"""
:param id: 爬虫运行的jobid
:return: 返回爬虫是否运行完成
"""
# 循环获取爬虫已完成的jobid,
# 如果当前爬虫的jobid存在finished已完成项目中就返回已完成的状态
while True:
ss = get_jobs(project="baidupm")
for fin in ss.get("finished"):
if id == fin.get("id"):
return {"message": "ok"}
第四步:怎样与django结合使用呢?通过前端ajax的方式获取用户输入的参数并将采集的结果返回个用户,具体看下面的视图函数:
@check_login
def baidu_api(request):
if request.method == "POST":
get_ip(request)
author = request.session['user_name']
data = request.POST.get('data', '')
source = request.POST.get("source", "")
page = request.POST.get("page", "")
txt_pm = []
for keyword in data.split("\n"):
txt_pm.append({"keyword": keyword.strip(), "page": int(page), "author": author, "source": source})
runspider = start_spider(project="baidupm", spider='pm',
datas=str(txt_pm))
message = spider_status(runspider.get("jobid"))
runspider.update(message)
if message.get("message") == "ok":
kwargs = {"source": source, 'author': author}
result_nums = Baidupm.objects.filter(**kwargs).count()
runspider.update({"nums": result_nums})
return JsonResponse(runspider, safe=False, json_dumps_params={'ensure_ascii': False})
首页输入参数:
批量输入:
到此scrapy的爬虫接受外部参数及通过命令运行接受的参数及接口调用scrapy爬虫并传递给爬虫参数的博文分享就完成了。
博文原创,原创不易,如有疑问可以添加博主微信私聊。未经允许请勿转载!