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删除文件示例分享
Jan 28 Python
详细探究Python中的字典容器
Apr 14 Python
Python中的下划线详解
Jun 24 Python
Python实现视频下载功能
Mar 14 Python
Python如何快速实现分布式任务
Jul 06 Python
django的csrf实现过程详解
Jul 26 Python
python socket通信编程实现文件上传代码实例
Dec 14 Python
解决Python import docx出错DLL load failed的问题
Feb 13 Python
Mac PyCharm中的.gitignore 安装设置教程
Apr 16 Python
Python实现一个优先级队列的方法
Jul 31 Python
Prometheus开发中间件Exporter过程详解
Nov 30 Python
python+selenium自动化实战携带cookies模拟登陆微博
Jan 19 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的SimpleXML方法读写XML接口文件实例解析
2014/06/16 PHP
PHP中常用的三种设计模式详解【单例模式、工厂模式、观察者模式】
2019/06/14 PHP
获取元素距离浏览器周边的位置的方法getBoundingClientRect
2013/04/17 Javascript
js加载读取内容及显示与隐藏div示例
2014/02/13 Javascript
将HTML格式的String转化为HTMLElement的实现方法
2014/08/07 Javascript
jQuery中removeProp()方法用法实例
2015/01/05 Javascript
原生javascript实现图片按钮切换
2015/01/12 Javascript
C#中使用迭代器处理等待任务
2015/07/13 Javascript
javascript封装addLoadEvent实现页面同时加载执行多个函数的方法
2016/07/25 Javascript
JavaScript正则表达式exec/g实现多次循环用法示例
2017/01/17 Javascript
bootstrap jquery dataTable 异步ajax刷新表格数据的实现方法
2017/02/10 Javascript
node中使用log4js4.x版本记录日志的方法
2019/08/20 Javascript
vue全局使用axios的操作
2020/09/08 Javascript
python 装饰器功能以及函数参数使用介绍
2012/01/27 Python
python解决字典中的值是列表问题的方法
2013/03/04 Python
Python实现的多线程端口扫描工具分享
2015/01/21 Python
Python生成器定义与简单用法实例分析
2018/04/30 Python
解决DataFrame排序sort的问题
2018/06/07 Python
python ddt数据驱动最简实例代码
2019/02/22 Python
python实现给微信指定好友定时发送消息
2019/04/29 Python
pandas的排序和排名的具体使用
2019/07/31 Python
Python Excel vlookup函数实现过程解析
2020/06/22 Python
Python自动化xpath实现自动抢票抢货
2020/09/19 Python
删除pycharm鼠标右键快捷键打开项目的操作
2021/01/16 Python
Booking.com荷兰:全球酒店网上预订
2017/08/22 全球购物
澳大利亚最超值的自行车之家:Reid Cycles
2019/03/24 全球购物
亚洲颇具影响力的男性在线购物零售商:His
2019/11/24 全球购物
写出程序把一个链表中的接点顺序倒排
2014/04/28 面试题
托管代码(Managed Code)和非托管代码(Unmanaged Code)有什么区别
2014/09/29 面试题
大学生求职简历的自我评价范文
2013/10/12 职场文书
小学美术教学反思
2014/02/01 职场文书
《雕塑之美》教学反思
2014/04/24 职场文书
党员自我评议对照检查材料
2014/09/27 职场文书
2014年干部培训工作总结
2014/12/17 职场文书
法律服务所工作总结
2015/08/10 职场文书
Spring Boot优化后启动速度快到飞起技巧示例
2022/07/23 Java/Android