Scrapy-Redis结合POST请求获取数据的方法示例


Posted in Python onMay 07, 2019

前言

通常我们在一个站站点进行采集的时候,如果是小站的话 我们使用scrapy本身就可以满足。

但是如果在面对一些比较大型的站点的时候,单个scrapy就显得力不从心了。

要是我们能够多个Scrapy一起采集该多好啊 人多力量大。

很遗憾Scrapy官方并不支持多个同时采集一个站点,虽然官方给出一个方法:

**将一个站点的分割成几部分 交给不同的scrapy去采集**

似乎是个解决办法,但是很麻烦诶!毕竟分割很麻烦的哇

下面就改轮到我们的额主角Scrapy-Redis登场了!

能看到这篇文章的小伙伴肯定已经知道什么是Scrapy以及Scrapy-Redis了,基础概念这里就不再介绍。默认情况下Scrapy-Redis是发送GET请求获取数据的,对于某些使用POST请求的情况需要重写make_request_from_data函数即可,但奇怪的是居然没在网上搜到简洁明了的答案,或许是太简单了?。

这里我以httpbin.org这个网站为例,首先在settings.py中添加所需配置,这里需要根据实际情况进行修改:

SCHEDULER = "scrapy_redis.scheduler.Scheduler" #启用Redis调度存储请求队列
SCHEDULER_PERSIST = True #不清除Redis队列、这样可以暂停/恢复 爬取
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter" #确保所有的爬虫通过Redis去重
SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.SpiderPriorityQueue'
REDIS_URL = "redis://127.0.0.1:6379"

爬虫代码如下:

# -*- coding: utf-8 -*-
import scrapy
from scrapy_redis.spiders import RedisSpider


class HpbSpider(RedisSpider):
 name = 'hpb'
 redis_key = 'test_post_data'

 def make_request_from_data(self, data):
  """Returns a Request instance from data coming from Redis.
  By default, ``data`` is an encoded URL. You can override this method to
  provide your own message decoding.
  Parameters
  ----------
  data : bytes
   Message from redis.
  """
  return scrapy.FormRequest("https://www.httpbin.org/post",
         formdata={"data":data},callback=self.parse)

 def parse(self, response):
  print(response.body)

这里为了简单直接进行输出,真实使用时可以结合pipeline写数据库等。

然后启动爬虫程序scrapy crawl hpb,由于我们还没向test_post_data中写数据,所以启动后程序进入等待状态。然后模拟向队列写数据:

import redis
rd = redis.Redis('127.0.0.1',port=6379,db=0)
for _ in range(1000):
 rd.lpush('test_post_data',_)

此时可以看到爬虫已经开始获取程序了:

2019-05-06 16:30:21 [hpb] DEBUG: Read 8 requests from 'test_post_data'
2019-05-06 16:30:21 [scrapy.core.engine] DEBUG: Crawled (200) <POST https://www.httpbin.org/post> (referer: None)
2019-05-06 16:30:21 [scrapy.core.engine] DEBUG: Crawled (200) <POST https://www.httpbin.org/post> (referer: None)
2019-05-06 16:30:21 [scrapy.core.engine] DEBUG: Crawled (200) <POST https://www.httpbin.org/post> (referer: None)
2019-05-06 16:30:21 [scrapy.core.engine] DEBUG: Crawled (200) <POST https://www.httpbin.org/post> (referer: None)
2019-05-06 16:30:21 [scrapy.core.engine] DEBUG: Crawled (200) <POST https://www.httpbin.org/post> (referer: None)
2019-05-06 16:30:21 [scrapy.core.engine] DEBUG: Crawled (200) <POST https://www.httpbin.org/post> (referer: None)
2019-05-06 16:30:21 [scrapy.core.engine] DEBUG: Crawled (200) <POST https://www.httpbin.org/post> (referer: None)
2019-05-06 16:30:21 [scrapy.core.engine] DEBUG: Crawled (200) <POST https://www.httpbin.org/post> (referer: None)
b'{\n  "args": {}, \n  "data": "", \n  "files": {}, \n  "form": {\n    "data": "0"\n  }, \n  "headers": {\n    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", \n    "Accept-Encoding": "gzip,deflate", \n    "Accept-Language": "en", \n    "Content-Length": "6", \n    "Content-Type": "application/x-www-form-urlencoded", \n    "Host": "www.httpbin.org", \n    "User-Agent": "Scrapy/1.5.1 (+https://scrapy.org)"\n  }, \n  "json": null, \n  "origin": "1.2.3.48, 1.2.3.48", \n  "url": "https://www.httpbin.org/post"\n}\n'
b'{\n  "args": {}, \n  "data": "", \n  "files": {}, \n  "form": {\n    "data": "1"\n  }, \n  "headers": {\n    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", \n    "Accept-Encoding": "gzip,deflate", \n    "Accept-Language": "en", \n    "Content-Length": "6", \n    "Content-Type": "application/x-www-form-urlencoded", \n    "Host": "www.httpbin.org", \n    "User-Agent": "Scrapy/1.5.1 (+https://scrapy.org)"\n  }, \n  "json": null, \n  "origin": "1.2.3.48, 1.2.3.48", \n  "url": "https://www.httpbin.org/post"\n}\n'
b'{\n  "args": {}, \n  "data": "", \n  "files": {}, \n  "form": {\n    "data": "3"\n  }, \n  "headers": {\n    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", \n    "Accept-Encoding": "gzip,deflate", \n    "Accept-Language": "en", \n    "Content-Length": "6", \n    "Content-Type": "application/x-www-form-urlencoded", \n    "Host": "www.httpbin.org", \n    "User-Agent": "Scrapy/1.5.1 (+https://scrapy.org)"\n  }, \n  "json": null, \n  "origin": "1.2.3.48, 1.2.3.48", \n  "url": "https://www.httpbin.org/post"\n}\n'
b'{\n  "args": {}, \n  "data": "", \n  "files": {}, \n  "form": {\n    "data": "2"\n  }, \n  "headers": {\n    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", \n    "Accept-Encoding": "gzip,deflate", \n    "Accept-Language": "en", \n    "Content-Length": "6", \n    "Content-Type": "application/x-www-form-urlencoded", \n    "Host": "www.httpbin.org", \n    "User-Agent": "Scrapy/1.5.1 (+https://scrapy.org)"\n  }, \n  "json": null, \n  "origin": "1.2.3.48, 1.2.3.48", \n  "url": "https://www.httpbin.org/post"\n}\n'
b'{\n  "args": {}, \n  "data": "", \n  "files": {}, \n  "form": {\n    "data": "4"\n  }, \n  "headers": {\n    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", \n    "Accept-Encoding": "gzip,deflate", \n    "Accept-Language": "en", \n    "Content-Length": "6", \n    "Content-Type": "application/x-www-form-urlencoded", \n    "Host": "www.httpbin.org", \n    "User-Agent": "Scrapy/1.5.1 (+https://scrapy.org)"\n  }, \n  "json": null, \n  "origin": "1.2.3.48, 1.2.3.48", \n  "url": "https://www.httpbin.org/post"\n}\n'
b'{\n  "args": {}, \n  "data": "", \n  "files": {}, \n  "form": {\n    "data": "5"\n  }, \n  "headers": {\n    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", \n    "Accept-Encoding": "gzip,deflate", \n    "Accept-Language": "en", \n    "Content-Length": "6", \n    "Content-Type": "application/x-www-form-urlencoded", \n    "Host": "www.httpbin.org", \n    "User-Agent": "Scrapy/1.5.1 (+https://scrapy.org)"\n  }, \n  "json": null, \n  "origin": "1.2.3.48, 1.2.3.48", \n  "url": "https://www.httpbin.org/post"\n}\n'
b'{\n  "args": {}, \n  "data": "", \n  "files": {}, \n  "form": {\n    "data": "6"\n  }, \n  "headers": {\n    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", \n    "Accept-Encoding": "gzip,deflate", \n    "Accept-Language": "en", \n    "Content-Length": "6", \n    "Content-Type": "application/x-www-form-urlencoded", \n    "Host": "www.httpbin.org", \n    "User-Agent": "Scrapy/1.5.1 (+https://scrapy.org)"\n  }, \n  "json": null, \n  "origin": "1.2.3.48, 1.2.3.48", \n  "url": "https://www.httpbin.org/post"\n}\n'
b'{\n  "args": {}, \n  "data": "", \n  "files": {}, \n  "form": {\n    "data": "7"\n  }, \n  "headers": {\n    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", \n    "Accept-Encoding": "gzip,deflate", \n    "Accept-Language": "en", \n    "Content-Length": "6", \n    "Content-Type": "application/x-www-form-urlencoded", \n    "Host": "www.httpbin.org", \n    "User-Agent": "Scrapy/1.5.1 (+https://scrapy.org)"\n  }, \n  "json": null, \n  "origin": "1.2.3.48, 1.2.3.48", \n  "url": "https://www.httpbin.org/post"\n}\n'
2019-05-06 16:31:09 [scrapy.extensions.logstats] INFO: Crawled 1001 pages (at 280 pages/min), scraped 0 items (at 0 items/min)
2019-05-06 16:32:09 [scrapy.extensions.logstats] INFO: Crawled 1001 pages (at 0 pages/min), scraped 0 items (at 0 items/min)
2019-05-06 16:33:09 [scrapy.extensions.logstats] INFO: Crawled 1001 pages (at 0 pages/min), scraped 0 items (at 0 items/min)

至于数据重复的问题,如果POST的数据重复,这个请求就不会发送出去。如果有特殊情况POST发送同样的数据回得到不同返回值,添加dont_filter=True是没用的,在RFPDupeFilter类中并没考虑这个参数,需要重写。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

Python 相关文章推荐
快速排序的算法思想及Python版快速排序的实现示例
Jul 02 Python
python 实现自动远程登陆scp文件实例代码
Mar 13 Python
python list排序的两种方法及实例讲解
Mar 20 Python
python多线程socket编程之多客户端接入
Sep 12 Python
python3+PyQt5使用数据库表视图
Apr 24 Python
78行Python代码实现现微信撤回消息功能
Jul 26 Python
windows7 32、64位下python爬虫框架scrapy环境的搭建方法
Nov 29 Python
对Python3 序列解包详解
Feb 16 Python
Flask框架重定向,错误显示,Responses响应及Sessions会话操作示例
Aug 01 Python
python的常见矩阵运算(小结)
Aug 07 Python
python中property属性的介绍及其应用详解
Aug 29 Python
pandas的相关系数与协方差实例
Dec 27 Python
Python数据类型之Set集合实例详解
May 07 #Python
Python数据类型之Dict字典实例详解
May 07 #Python
Python分支语句与循环语句应用实例分析
May 07 #Python
Python正则表达式实现简易计算器功能示例
May 07 #Python
深入浅析Python 中 is 语法带来的误解
May 07 #Python
利用python如何在前程无忧高效投递简历
May 07 #Python
Python可迭代对象操作示例
May 07 #Python
You might like
php cookie使用方法学习笔记分享
2013/11/07 PHP
利用浏览器的Javascript控制台调试PHP程序
2014/01/08 PHP
Linux平台php命令行程序处理管道数据的方法
2016/11/10 PHP
JQUERY THICKBOX弹出层插件
2008/08/30 Javascript
JavaScript.The.Good.Parts阅读笔记(二)作用域&amp;闭包&amp;减缓全局空间污染
2010/11/16 Javascript
元素的内联事件处理函数的特殊作用域在各浏览器中存在差异
2011/01/12 Javascript
javaScript arguments 对象使用介绍
2013/10/18 Javascript
判断字符串的长度(优化版)中文占两个字符
2014/10/30 Javascript
Javascript刷新窗口方法小结
2015/10/21 Javascript
Bootstrap导航条可点击和鼠标悬停显示下拉菜单的实现代码
2016/06/23 Javascript
详解Vue.js基于$.ajax获取数据并与组件的data绑定
2017/05/26 Javascript
vue组件父子间通信之综合练习(聊天室)
2017/11/07 Javascript
vue下拉列表功能实例代码
2018/04/08 Javascript
node中modules.exports与exports导出的区别
2018/06/08 Javascript
茶余饭后聊聊Vue3.0响应式数据那些事儿
2019/10/30 Javascript
JavaScript对象属性操作实例解析
2020/02/04 Javascript
如何使用JavaScript实现无缝滚动自动播放轮播图效果
2020/08/20 Javascript
JS操作JSON常用方法(10w阅读)
2020/12/06 Javascript
python获取文件版本信息、公司名和产品名的方法
2014/10/05 Python
Pandas之groupby( )用法笔记小结
2019/07/23 Python
python实现二分查找算法
2020/09/18 Python
python爬虫请求头的使用
2020/12/01 Python
浅谈html5 响应式布局
2014/12/24 HTML / CSS
HTML5制作表格样式
2016/11/15 HTML / CSS
去加拿大的旅行和假期:Canadian Affair
2016/10/25 全球购物
美国经典刺绣和字母儿童服装特卖:Smocked Auctions
2018/07/16 全球购物
德国受欢迎的旅游和休闲网站:lastminute.de
2019/09/23 全球购物
澳大利亚窗帘商店:Curtain Wonderland
2019/12/01 全球购物
求职信内容考虑哪几点
2013/10/05 职场文书
一个大学生十年的职业规划
2014/01/17 职场文书
生日寄语大全
2014/04/08 职场文书
体育馆的标语
2014/06/24 职场文书
离婚协议书范本及离婚须知
2014/10/15 职场文书
2014年党支部书记工作总结
2014/12/04 职场文书
导游词之岳阳楼
2019/09/25 职场文书
vue3语法糖内的defineProps及defineEmits
2022/04/14 Vue.js