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中函数及默认参数的定义与调用操作实例分析
Jul 25 Python
python分治法求二维数组局部峰值方法
Apr 03 Python
python Pandas 读取txt表格的实例
Apr 29 Python
python中字符串的操作方法大全
Jun 03 Python
使用python Fabric动态修改远程机器hosts的方法
Oct 26 Python
修改python plot折线图的坐标轴刻度方法
Dec 13 Python
利用python在excel里面直接使用sql函数的方法
Feb 08 Python
python SQLAlchemy 中的Engine详解
Jul 04 Python
浅析Python语言自带的数据结构有哪些
Aug 27 Python
python+jinja2实现接口数据批量生成工具
Aug 28 Python
python爬虫模拟浏览器访问-User-Agent过程解析
Dec 28 Python
python列表推导和生成器表达式知识点总结
Jan 10 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调用三种数据库的方法(3)
2006/10/09 PHP
解析用PHP读写音频文件信息的详解(支持WMA和MP3)
2013/05/10 PHP
PHP统一页面编码避免乱码问题
2015/04/09 PHP
FleaPHP框架数据库查询条件($conditions)写法总结
2016/03/19 PHP
PHP 根据key 给二维数组分组
2016/12/09 PHP
jQuery EasyUI 的EasyLoader功能介绍
2010/09/12 Javascript
jquery选择器(常用选择器说明)
2010/09/28 Javascript
js toFixed()方法的重写实现精度的统一
2014/03/06 Javascript
javascript的document中的动态添加标签实现方法
2016/10/24 Javascript
vue父组件向子组件(props)传递数据的方法
2018/01/02 Javascript
jquery 输入框查找关键字并提亮颜色的实例代码
2018/01/23 jQuery
vue.js动画中的js钩子函数的实现
2018/07/06 Javascript
vue超时计算的组件实例代码
2018/07/09 Javascript
vue axios数据请求及vue中使用axios的方法
2018/09/10 Javascript
利用React Router4实现的服务端直出渲染(SSR)
2019/01/07 Javascript
koa+jwt实现token验证与刷新功能
2019/05/30 Javascript
vue实现简单学生信息管理
2020/05/30 Javascript
Python中的装饰器用法详解
2015/01/14 Python
详解Python中的Cookie模块使用
2015/07/06 Python
浅谈python为什么不需要三目运算符和switch
2016/06/17 Python
使用python遍历指定城市的一周气温
2017/03/31 Python
Python(Django)项目与Apache的管理交互的方法
2018/05/16 Python
详解python异步编程之asyncio(百万并发)
2018/07/07 Python
对matplotlib改变colorbar位置和方向的方法详解
2018/12/13 Python
对python判断ip是否可达的实例详解
2019/01/31 Python
python如何从文件读取数据及解析
2019/09/19 Python
python如何求数组连续最大和的示例代码
2020/02/04 Python
详解HTML5表单新增属性
2016/12/21 HTML / CSS
美国瑜伽品牌:Gaiam
2017/10/31 全球购物
威盛公司软件C++工程师笔试题面试题
2012/07/16 面试题
大学生专科毕业生自我评价
2013/11/17 职场文书
书法比赛获奖感言
2014/02/10 职场文书
财务科科长岗位职责
2014/03/10 职场文书
党风廉政承诺书
2014/03/27 职场文书
服务行业标语口号
2015/12/26 职场文书
HTML静态页面获取url参数和UserAgent的实现
2022/08/05 HTML / CSS