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爬虫并传递给爬虫参数的博文分享就完成了。

博文原创,原创不易,如有疑问可以添加博主微信私聊。未经允许请勿转载!

推荐文章:scrapyd部署scrapy爬虫