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 相关文章推荐
Djang中静态文件配置方法
Jul 30 Python
Python中的模块导入和读取键盘输入的方法
Oct 16 Python
Python简单实现Base64编码和解码的方法
Apr 29 Python
python 连接sqlite及简单操作
Jun 30 Python
python:按行读入,排序然后输出的方法
Jul 20 Python
python命令 -u参数用法解析
Oct 24 Python
浅析python表达式4+0.5值的数据类型
Feb 26 Python
用python实现学生管理系统
Jul 24 Python
python基于pexpect库自动获取日志信息
Feb 01 Python
python实现层次聚类的方法
Nov 01 Python
python 远程执行命令的详细代码
Feb 15 Python
Python采集股票数据并制作可视化柱状图
Apr 04 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
广播爱好者需要了解的天线知识
2021/03/01 无线电
PHP中用hash实现的数组
2011/07/17 PHP
php更新mysql后获取影响的行数发生异常解决方法
2013/03/28 PHP
php Xdebug的安装与使用详解
2013/06/20 PHP
ThinkPHP之R方法实例详解
2014/06/20 PHP
PHP生成RSS文件类实例
2014/12/05 PHP
PHP中strnatcmp()函数“自然排序算法”进行字符串比较用法分析(对比strcmp函数)
2016/01/07 PHP
php中strtotime函数性能分析
2016/11/20 PHP
CakePHP框架Model关联对象用法分析
2017/08/04 PHP
PHP验证码无法显示的原因及解决办法
2017/08/11 PHP
PHP排序算法之简单选择排序(Simple Selection Sort)实例分析
2018/04/20 PHP
php+Ajax无刷新验证用户名操作实例详解
2019/03/04 PHP
js中页面的重新加载(当前页面/上级页面)及frame或iframe元素引用介绍
2013/01/24 Javascript
JavaScript中setAttribute用法介绍
2013/07/20 Javascript
EasyUI加载完Html内容样式渲染完成后显示
2016/07/25 Javascript
vue仿淘宝订单状态的tab切换效果
2020/06/23 Javascript
vue+element实现批量删除功能的示例
2018/02/28 Javascript
WebPack配置vue多页面的技巧
2018/05/15 Javascript
vue2.0 下拉框默认标题设置方法
2018/08/22 Javascript
移动端(微信等使用vConsole调试console的方法
2019/03/05 Javascript
详解javascript中的Error对象
2019/04/25 Javascript
js prototype和__proto__的关系是什么
2019/08/23 Javascript
基于layui table返回的值的多级嵌套的解决方法
2019/09/19 Javascript
[11:01]2014DOTA2西雅图邀请赛 冷冷带你探秘威斯汀
2014/07/08 DOTA
[01:32]TI奖金增速竟因它再创新高!DOTA2勇士令状不朽珍藏Ⅰ饰品欣赏
2018/05/18 DOTA
Python实现全角半角转换的方法
2014/08/18 Python
Python map和reduce函数用法示例
2015/02/26 Python
浅谈python对象数据的读写权限
2016/09/12 Python
Django中更改默认数据库为mysql的方法示例
2018/12/05 Python
python修改FTP服务器上的文件名
2019/09/11 Python
国际鲜花速递专家:Floraqueen
2016/11/24 全球购物
加拿大的标志性百货公司:Hudson’s Bay(哈得逊湾)
2019/09/03 全球购物
大学生毕业求职的自我评价
2013/09/29 职场文书
小学数学课题方案
2014/06/15 职场文书
2015年保送生自荐信
2015/03/24 职场文书
利用python实时刷新基金估值(摸鱼小工具)
2021/09/15 Python