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决策树之C4.5算法详解
Dec 20 Python
Python 通过requests实现腾讯新闻抓取爬虫的方法
Feb 22 Python
Python2.7实现多进程下开发多线程示例
May 31 Python
python将字符串list写入excel和txt的实例
Jul 20 Python
基于python解线性矩阵方程(numpy中的matrix类)
Oct 21 Python
从numpy数组中取出满足条件的元素示例
Nov 26 Python
在Django中预防CSRF攻击的操作
Mar 13 Python
pandas DataFrame运算的实现
Jun 14 Python
什么是python的函数体
Jun 19 Python
关于python tushare Tkinter构建的简单股票可视化查询系统(Beta v0.13)
Oct 19 Python
python如何快速拼接字符串
Oct 28 Python
使用Pytorch实现two-head(多输出)模型的操作
May 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
星际原理概述
2020/03/04 星际争霸
免费手机号码归属地API查询接口和PHP使用实例分享
2014/04/10 PHP
PHP封装分页函数实现文本分页和数字分页
2014/10/23 PHP
php实现ip白名单黑名单功能
2015/03/12 PHP
解决jquery submit()提交表单提示:f[s] is not a function
2013/01/23 Javascript
jquery写个checkbox——类似邮箱全选功能
2013/03/19 Javascript
jquery自动将form表单封装成json的具体实现
2014/03/17 Javascript
JavaScript给input的value赋值引发的关于基本类型值和引用类型值问题
2015/12/07 Javascript
jQuery+CSS实现一个侧滑导航菜单代码
2016/05/09 Javascript
jQuery弹出层后禁用底部滚动条(移动端关闭回到原位置)
2016/08/29 Javascript
js 中获取制定的cook信息实现方法
2016/11/19 Javascript
详解jQuery uploadify文件上传插件的使用方法
2016/12/16 Javascript
详解使用Vue.Js结合Jquery Ajax加载数据的两种方式
2017/01/10 Javascript
详解vue2.0 transition 多个元素嵌套使用过渡
2017/06/19 Javascript
使用live-server快速搭建本地服务器+自动刷新的方法
2018/03/09 Javascript
boostrap模态框二次弹出清空原有内容的方法
2018/08/10 Javascript
node.js使用免费的阿里云ip查询获取ip所在地【推荐】
2018/09/03 Javascript
angularJS自定义directive之带参方法传递详解
2018/10/09 Javascript
layDate插件设置开始和结束时间
2018/11/15 Javascript
Vue框架TypeScript装饰器使用指南小结
2019/02/18 Javascript
通过实例讲解JS如何防抖动
2019/06/15 Javascript
基于JS实现数字动态变化显示效果附源码
2019/07/18 Javascript
微信小程序webview与h5通过postMessage实现实时通讯的实现
2019/08/20 Javascript
Python实现快速多线程ping的方法
2015/07/15 Python
Python2中文处理纪要的实现方法
2018/03/10 Python
解决Pandas的DataFrame输出截断和省略的问题
2019/02/08 Python
基于pygame实现童年掌机打砖块游戏
2020/02/25 Python
使用Pyhton 分析酒店针孔摄像头
2020/03/04 Python
Python爬虫入门教程02之笔趣阁小说爬取
2021/01/24 Python
使用jquery实现HTML5响应式导航菜单教程
2014/04/02 HTML / CSS
简历里的自我评价范文
2014/02/24 职场文书
社区综治宣传月活动总结
2014/07/02 职场文书
保密工作目标责任书
2014/07/28 职场文书
爱岗敬业先进典型事迹材料(2016推荐版)
2016/02/26 职场文书
MySQL中InnoDB存储引擎的锁的基本使用教程
2021/05/26 MySQL
CentOS7环境下MySQL8常用命令小结
2022/06/10 Servers