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网络编程调用recv函数完整接收数据的三种方法
Mar 31 Python
Python判断有效的数独算法示例
Feb 23 Python
Python opencv实现人眼/人脸识别以及实时打码处理
Apr 29 Python
Python中的引用知识点总结
May 20 Python
使用Pandas对数据进行筛选和排序的实现
Jul 29 Python
Django 创建新App及其常用命令的实现方法
Aug 04 Python
tensorflow 模型权重导出实例
Jan 24 Python
Python Scrapy框架第一个入门程序示例
Feb 05 Python
Selenium启动Chrome时配置选项详解
Mar 18 Python
python实现梯度下降法
Mar 24 Python
python中scipy.stats产生随机数实例讲解
Feb 19 Python
Python语言内置数据类型
Feb 24 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编写大型网站问题集
2007/03/06 PHP
php目录操作函数之获取目录与文件的类型
2010/12/29 PHP
PHP中定义数组常量(array常量)的方法
2014/11/17 PHP
PHP中遇到的时区问题解决方法
2015/07/23 PHP
PHP实现的多维数组排序算法分析
2018/02/10 PHP
网上抓的一个特效
2007/05/11 Javascript
javascript下阻止表单重复提交、防刷新、防后退
2007/08/17 Javascript
javascript attachEvent和addEventListener使用方法
2009/03/19 Javascript
jquery.AutoComplete.js中文修正版(支持firefox)
2010/04/09 Javascript
利用javascript数组长度循环数组内所有元素
2013/12/27 Javascript
javascript:void(0)的问题使用探讨
2014/04/10 Javascript
手机号码,密码正则验证
2014/09/04 Javascript
javascript去掉代码里面的注释
2015/07/24 Javascript
JQuery的Pager分页器实现代码
2016/05/03 Javascript
Javascript中call,apply,bind方法的详解与总结
2016/12/12 Javascript
AngularJS路由Ui-router模块用法示例
2017/05/29 Javascript
[js高手之路]从原型链开始图解继承到组合继承的产生详解
2017/08/28 Javascript
vue实现前进刷新后退不刷新效果
2018/01/26 Javascript
解决IE11 vue +webpack 项目中数据更新后页面没有刷新的问题
2018/09/25 Javascript
使用Object.defineProperty如何巧妙找到修改某个变量的准确代码位置
2018/11/02 Javascript
koa源码中promise的解读
2018/11/13 Javascript
微信小程序地图(map)组件点击(tap)获取经纬度的方法
2019/01/10 Javascript
微信小程序利用云函数获取手机号码
2019/12/17 Javascript
jQuery操作动画完整实例分析
2020/01/10 jQuery
JS+CSS实现炫酷光感效果
2020/09/05 Javascript
ORM Django 终端打印 SQL 语句实现解析
2019/08/09 Python
Django中使用Json返回数据的实现方法
2020/06/03 Python
CSS3教程(9):设置RGB颜色
2009/04/02 HTML / CSS
HTML5 Canvas 起步(1) - 基本概念
2009/05/12 HTML / CSS
新加坡航空官方网站:Singapore Airlines
2016/10/13 全球购物
乌克兰排名第一的在线旅游超市:Farvater.Travel
2020/01/02 全球购物
军训的自我鉴定
2013/12/10 职场文书
日本语毕业生自荐信
2014/02/01 职场文书
硕士研究生求职自荐信范文
2014/03/11 职场文书
大学生就业意向书
2015/05/11 职场文书
初三语文教学反思
2016/03/03 职场文书