Scrapy中如何向Spider传入参数的方法实现


Posted in Python onSeptember 28, 2020

在使用Scrapy爬取数据时,有时会碰到需要根据传递给Spider的参数来决定爬取哪些Url或者爬取哪些页的情况。

例如,百度贴吧的放置奇兵吧的地址如下,其中 kw参数用来指定贴吧名称、pn参数用来对帖子进行翻页。

https://tieba.baidu.com/f?kw=放置奇兵&ie=utf-8&pn=250

如果我们希望通过参数传递的方式将贴吧名称和页数等参数传给Spider,来控制我们要爬取哪一个贴吧、爬取哪些页。遇到这种情况,有以下两种方法向Spider传递参数。

方式一

通过 scrapy crawl 命令的 -a 参数向 spider 传递参数。

# -*- coding: utf-8 -*-
import scrapy

class TiebaSpider(scrapy.Spider):
  name = 'tieba' # 贴吧爬虫
  allowed_domains = ['tieba.baidu.com'] # 允许爬取的范围
  start_urls = [] # 爬虫起始地址

  # 命令格式: scrapy crawl tieba -a tiebaName=放置奇兵 -a pn=250
  def __init__(self, tiebaName=None, pn=None, *args, **kwargs):
    print('< 贴吧名称 >: ' + tiebaName)
    super(eval(self.__class__.__name__), self).__init__(*args, **kwargs)
    self.start_urls = ['https://tieba.baidu.com/f?kw=%s&ie=utf-8&pn=%s' % (tiebaName,pn)]

  def parse(self, response):
    print(response.request.url) # 结果:https://tieba.baidu.com/f?kw=%E6%94%BE%E7%BD%AE%E5%A5%87%E5%85%B5&ie=utf-8&pn=250

方式二

仿照 scrapy 的 crawl 命令的源代码,重新自定义一个专用命令。

Scrapy中如何向Spider传入参数的方法实现

settings.py

首先,需要在settings.py文件中增加如下配置来指定自定义 scrapy 命令的存放目录。

# 指定 Scrapy 命令存放目录
COMMANDS_MODULE = 'baidu_tieba.commands'

run.py

在指定的命令存放目录中创建命令文件,在这里我们创建的命令文件为 run.py ,将来执行的命令格式为:
scrapy run [ -option option_value]

import scrapy.commands.crawl as crawl
from scrapy.exceptions import UsageError
from scrapy.commands import ScrapyCommand


class Command(crawl.Command):

  def add_options(self, parser):
    # 为命令添加选项
    ScrapyCommand.add_options(self, parser)
    parser.add_option("-k", "--keyword", type="str", dest="keyword", default="",
             help="set the tieba's name you want to crawl")
    parser.add_option("-p", "--pageNum", type="int", action="store", dest="pageNum", default=0,
             help="set the page number you want to crawl")

  def process_options(self, args, opts):
    # 处理从命令行中传入的选项参数
    ScrapyCommand.process_options(self, args, opts)
    if opts.keyword:
      tiebaName = opts.keyword.strip()
      if tiebaName != '':
        self.settings.set('TIEBA_NAME', tiebaName, priority='cmdline')
    else:
      raise UsageError("U must specify the tieba's name to crawl,use -kw TIEBA_NAME!")
    self.settings.set('PAGE_NUM', opts.pageNum, priority='cmdline')

  def run(self, args, opts):
    # 启动爬虫
    self.crawler_process.crawl('tieba')
    self.crawler_process.start()

pipelines.py

在BaiduTiebaPipeline的open_spider()方法中利用 run 命令传入的参数对TiebaSpider进行初始化,在这里示例设置了一下start_urls。

# -*- coding: utf-8 -*-
import json

class BaiduTiebaPipeline(object):

  @classmethod
  def from_settings(cls, settings):
    return cls(settings)

  def __init__(self, settings):
    self.settings = settings

  def open_spider(self, spider):
    # 开启爬虫
    spider.start_urls = [
      'https://tieba.baidu.com/f?kw=%s&ie=utf-8&pn=%s' % (self.settings['TIEBA_NAME'], self.settings['PAGE_NUM'])]

  def close_spider(self, spider):
    # 关闭爬虫
    pass

  def process_item(self, item, spider):
    # 将帖子内容保存到文件
    with open('tieba.txt', 'a', encoding='utf-8') as f:
      json.dump(dict(item), f, ensure_ascii=False, indent=2)
    return item

设置完成后,别忘了在settings.py中启用BaiduTiebaPipeline。 

ITEM_PIPELINES = {
  'baidu_tieba.pipelines.BaiduTiebaPipeline': 50,
}

启动示例

大功告成,参照如下命令格式启动贴吧爬虫。 

scrapy run -k 放置奇兵 -p 250

Scrapy中如何向Spider传入参数的方法实现

参考文章:

https://blog.csdn.net/c0411034/article/details/81750028 

https://blog.csdn.net/qq_24760381/article/details/80361400 

https://blog.csdn.net/qq_38282706/article/details/80991196 

到此这篇关于Scrapy中如何向Spider传入参数的方法实现的文章就介绍到这了,更多相关Scrapy Spider传入参数内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python zip文件 压缩
Dec 24 Python
python实现的一个火车票转让信息采集器
Jul 09 Python
Python functools模块学习总结
May 09 Python
django实现分页的方法
May 26 Python
python执行使用shell命令方法分享
Nov 08 Python
对python numpy数组中冒号的使用方法详解
Apr 17 Python
python调用OpenCV实现人脸识别功能
May 25 Python
详解Django+uwsgi+Nginx上线最佳实战
Mar 14 Python
python PIL/cv2/base64相互转换实例
Jan 09 Python
Python中import导入不同目录的模块方法详解
Feb 18 Python
python实现图片素描效果
Sep 26 Python
Python基础详解之描述符
Apr 28 Python
详解向scrapy中的spider传递参数的几种方法(2种)
Sep 28 #Python
小结Python的反射机制
Sep 28 #Python
scrapy与selenium结合爬取数据(爬取动态网站)的示例代码
Sep 28 #Python
scrapy结合selenium解析动态页面的实现
Sep 28 #Python
互斥锁解决 Python 中多线程共享全局变量的问题(推荐)
Sep 28 #Python
python 常见的反爬虫策略
Sep 27 #Python
python 5个实用的技巧
Sep 27 #Python
You might like
PHP数据类型之整数类型、浮点数的介绍
2013/04/28 PHP
微信支付开发教程(一)微信支付URL配置
2014/05/28 PHP
让GoogleCode的SVN下的HTML文件在FireFox下正常显示.
2009/05/25 Javascript
js有关元素内容操作小结
2011/12/20 Javascript
JQuery中关于jquery.js与jquery.min.js的比较探讨
2013/05/15 Javascript
利用javascript判断文件是否存在
2013/12/31 Javascript
一个简单的jQuery插件ajaxfileupload.js实现ajax上传文件例子
2014/06/26 Javascript
基于javascript的COOkie的操作实现只能点一次
2014/12/26 Javascript
使用Jasmine和Karma对AngularJS页面程序进行测试
2016/03/05 Javascript
jquery中validate与form插件提交的方式小结
2016/03/26 Javascript
Kindeditor在线文本编辑器如何过滤HTML
2016/04/14 Javascript
Vue.js实现拖放效果的实例
2016/09/30 Javascript
xmlplus组件设计系列之网格(DataGrid)(10)
2017/05/05 Javascript
浅谈node中的exports与module.exports的关系
2017/08/01 Javascript
什么是Vue.js框架 为什么选择它?
2017/10/17 Javascript
详解vue项目中如何引入全局sass/less变量、function、mixin
2018/06/02 Javascript
JavaScript实现的弹出遮罩层特效经典示例【基于jQuery】
2019/07/10 jQuery
JavaScript函数Call、Apply原理实例解析
2020/02/17 Javascript
使用Vant完成Dialog弹框案例
2020/11/11 Javascript
Python自定义scrapy中间模块避免重复采集的方法
2015/04/07 Python
Python的Django框架中自定义模版标签的示例
2015/07/20 Python
python3使用urllib模块制作网络爬虫
2016/04/08 Python
django 按时间范围查询数据库实例代码
2018/02/11 Python
30秒轻松实现TensorFlow物体检测
2018/03/14 Python
全面解析CSS Media媒体查询使用操作(推荐)
2017/08/15 HTML / CSS
使用HTML5 Canvas API控制字体的显示与渲染的方法
2016/03/24 HTML / CSS
如何从一个文件档案的尾端新增记录
2016/12/02 面试题
教师自荐书
2013/10/08 职场文书
水利水电专业自荐信
2014/07/08 职场文书
社会实践的活动方案
2014/08/22 职场文书
爱护公共设施倡议书
2014/08/29 职场文书
优秀党员自我评价范文
2014/09/15 职场文书
企业法人代表证明书
2014/09/27 职场文书
2015年见习期工作总结
2014/12/12 职场文书
2015年推广普通话演讲稿
2015/03/20 职场文书
导游词之苏州寒山寺
2019/12/05 职场文书