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小技巧分享
Nov 22 Python
python学习笔记之列表(list)与元组(tuple)详解
Nov 23 Python
python实现图书馆研习室自动预约功能
Apr 27 Python
Python设计模式之模板方法模式实例详解
Jan 17 Python
Python中如何导入类示例详解
Apr 17 Python
django中forms组件的使用与注意
Jul 08 Python
Windows10下 python3.7 安装 facenet的教程
Sep 10 Python
基于python操作ES实例详解
Nov 16 Python
python实现大战外星人小游戏实例代码
Dec 26 Python
Python判断三段线能否构成三角形的代码
Apr 12 Python
Python接口自动化测试框架运行原理及流程
Nov 30 Python
Python中非常使用的6种基本变量的操作与技巧
Mar 22 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
Thinkphp结合AJAX长轮询实现PC与APP推送详解
2017/07/31 PHP
EXTJS FORM HIDDEN TEXTFIELD 赋值 使用value不好用的问题
2011/04/16 Javascript
jquery scrollTop方法根据滚动像素显示隐藏顶部导航条
2013/05/27 Javascript
浅谈EasyUI中Treegrid节点的删除
2015/03/01 Javascript
JavaScript如何调试有哪些建议和技巧附五款有用的调试工具
2015/10/28 Javascript
js判断复选框是否选中及选中个数的实现代码
2016/05/30 Javascript
js入门之Function函数的使用方法【新手必看】
2016/11/22 Javascript
JS中微信小程序自定义底部弹出框
2016/12/22 Javascript
Vue获取DOM元素样式和样式更改示例
2017/03/07 Javascript
详解vue跨组件通信的几种方法
2017/06/15 Javascript
Vue中的ref作用详解(实现DOM的联动操作)
2017/08/21 Javascript
利用10行js代码实现上下滚动公告效果
2017/12/08 Javascript
解决bootstrap-select 动态加载数据不显示的问题
2018/08/10 Javascript
详解Vue 单文件组件的三种写法
2020/02/19 Javascript
vue-cli3单页构建大型项目方案
2020/04/07 Javascript
基于Vue.js+Nuxt开发自定义弹出层组件
2020/10/09 Javascript
[38:41]2014 DOTA2国际邀请赛中国区预选赛 LGD VS CNB
2014/05/22 DOTA
windows系统下Python环境的搭建(Aptana Studio)
2017/03/06 Python
Python贪吃蛇游戏编写代码
2020/10/26 Python
Python操作SQLite数据库的方法详解
2017/06/16 Python
只需7行Python代码玩转微信自动聊天
2019/01/27 Python
pymongo中聚合查询的使用方法
2019/03/22 Python
python挖矿算力测试程序详解
2019/07/03 Python
python cv2截取不规则区域图片实例
2019/12/21 Python
python opencv 图像边框(填充)添加及图像混合的实现方法(末尾实现类似幻灯片渐变的效果)
2020/03/09 Python
翻转数列python实现,求前n项和,并能输出整个数列的案例
2020/05/03 Python
python程序需要编译吗
2020/06/19 Python
Python实现GIF图倒放
2020/07/16 Python
css3 column实现卡片瀑布流布局的示例代码
2018/06/22 HTML / CSS
Wiggle中国:英国骑行、跑步、游泳 & 铁三运动装备专卖网店
2016/08/02 全球购物
SmartBuyGlasses荷兰:购买太阳镜和眼镜
2020/03/16 全球购物
大学生职业生涯规划范文——找准自我,定位人生
2014/01/23 职场文书
合伙经营协议书
2014/04/18 职场文书
退货证明模板
2015/06/23 职场文书
小学语文教学随笔
2015/08/14 职场文书
python语言中pandas字符串分割str.split()函数
2022/08/05 Python