同学们在使用scrapy-redis分布式爬虫框架开发的时候会发现,其默认只能发送GET请求,不能直接发送POST请求,这就导致我们在开发一些爬虫工具的时候出现问题,那么如何才能让scrapy-redis发送POST请求呢?

scrapy-redis爬虫

这里我们以美团网站为例,先来说一说需求,也就是说美团POST请求形式。我们以获取某个地理坐标下,所有店铺类别列表请求为例。获取所有店铺类别列表时,我们需要构造一个包含位置坐标经纬度等信息的表单数据,以及为了向下一层parse方法传递的一些必要数据,即meta,然后发起一个POST请求。
url,请求地址,即url是固定的,如下所示:

url=‘http://i.waimai.meituan.com/openh5/poi/filterconditions?_=1557367197922’

url最后面的13位数字是时间戳,实际应用时用time模块生成一下就好了。

表单数据:

meta数据:

meta数据不是必须的,但是,如果你在发送请求时,有一些数据需要向下一层parse方法(解析爬虫返回的response的方法)中传递的话,就可以构造这一数据,然后作为参数传递进request中。

源码分析

采集店铺类别列表时需要发送怎样一个POST请求在上面已经说明了,那么,在scrapy-redis框架中,这个POST该如何来发送呢?我相信,打开我这篇博文的读者都是用过scrapy的,用scrapy发送POST肯定没问题(重写start_requests方法即可),但scrapy-redis不同,scrapy-redis框架只会从配置好的redis数据库中读取起始url,所以,在scrapy-redis中,就算重写start_requests方法也没用。怎么办呢?我们看看源码。

我们知道,scrapy-redis与scrapy的一个很大区别就是,scrapy-redis不再继承Spider类,而是继承RedisSpider类的,所以,RedisSpider类源码将是我们分析的重点,我们打开RedisSpider类,看看有没有类似于scrapy框架中的start_requests、make_requests_from_url这样的方法。RedisSpider源码如下:

很遗憾,在RedisSpider类中没有找到类似start_requests、make_requests_from_url这样的方法,而且,RedisSpider的源码也太少了吧,不过,从第一行我们可以发现RedisSpider继承了RedisMinxin这个类,所以我猜RedisSpider的很多功能是从父类继承而来的(拼爹的RedisSpider)。继续查看RedisMinxin类源码。RedisMinxin类源码太多,这里就不将所有源码贴出来了,不过,惊喜的是,在RedisMinxin中,真找到了类似于start_requests、make_requests_from_url这样的方法,如:start_requests、next_requests、make_request_from_data等。有过scrapy使用经验的童鞋应该都知道,start_requests方法可以说是构造一切请求的起源,没分析scrapy-redis源码之前,谁也不知道scrapy-redis是不是和scrapy一样(后面打断点的方式验证过,确实一样,话说这个验证有点多余,因为源码注释就是这么说的),不过,还是从start_requests开始分析吧。start_requests源码如下:

直接把所有任务丢给next_requests方法,继续:

上面next_requests方法中,关键的就是那个while循环,每一次循环都调用了一个make_request_from_data方法,从函数名可以函数,这个方法就是根据从redis中读取从来的数据,实例化一个request,那不就是我们要找的方法吗?进入make_request_from_data方法一探究竟:

因为scrapy-redis默认值发送GET请求,所以,在这个make_request_from_data方法中认为data只包含一个url,但如果我们要发送POST请求,这个data包含的东西可就多了,我们上面美团POST请求说明中就说到,至少要包含url、form_data。所以,如果我们要发送POST请求,这里必须改,make_request_from_data方法最后调用的make_requests_from_url是scrapy中的Spider中的方法,不过,我们也不需要继续往下看下去了,我想诸位都也清楚了,要发送POST请求,重写这个make_request_from_data方法,根据传入的data,实例化一个request返回就好了。

代码实例

明白上面这些东西后,就可以开始写代码了。修改源码吗?不,不存在的,改源码可不是好习惯。我们直接在我们自己的Spider类中重写make_request_from_data方法就好了:

搞清楚原理之后,就是这么简单。万事俱备,只欠东风——将url,form_data,meta存储到redis中。另外新建一个模块实现这一部分功能:

在启动scrapy-redis之前,运行一下这一模块即可。如果有很多POI(地理位置兴趣点),循环遍历每一个POI,生成request_data,push到redis中。

本文来自千锋教育,转载请注明出处。

Python开发技巧:scrapy-redis爬虫如何发送POST请求相关推荐

  1. python timeit用法_十大Python开发技巧

    Python开发指南, 超级实用足以让您震撼 > Photo by Christina Morillo from StockSnap 时不时地,当我了解Python的新功能时,或者我发现其他一些 ...

  2. python 技巧视频教程_扣丁学堂Python视频教程之Python开发技巧

    扣丁学堂Python视频教程之Python开发技巧 2018-07-25 14:09:44 808浏览 关于Python开发的技巧小编在上篇文章已经给大家分享过一些,本篇文章扣丁学堂 神秘eval: ...

  3. Python网络编程:使用requests.post发送POST请求

    Python网络编程:使用requests.post发送POST请求 在Python中,requests是一个强大的库,它可以用于发送HTTP请求并且处理响应.requests.post()函数是这个 ...

  4. Python开发技巧-教你制作Python进度条

    进度条相信大家都不会陌生,我们也经常会看到各种各样的进度条,那么你知道在Python里面如何实现进度条吗?下面小千就来告诉你. 4种常见的Python进度条库 1.Progress 第一个要介绍的 P ...

  5. python request url编码_Python 爬虫 (requests) 发送中文编码的 HTTP POST 请求

    向往常一样发送POST请求出现错误 网站信息 表单页面 结果 网页使用 gb2312 编码 使用 requests 发送 post 请求 In [2]: import requests In [3]: ...

  6. scrapy-redis爬虫如何发送POST请求

    同学们在使用scrapy-redis分布式爬虫框架开发的时候会发现,其默认只能发送GET请求,不能直接发送POST请求,这就导致我们在开发一些爬虫工具的时候出现问题,那么如何才能让scrapy-red ...

  7. python+pytest接口自动化框架(5)-requests发送post请求

    在HTTP协议中,与get请求把请求参数直接放在url中不同,post请求的请求数据需通过消息主体(request body)中传递. 且协议中并没有规定post请求的请求数据必须使用什么样的编码方式 ...

  8. python token post403原因_Django中ajax发送post请求 报403错误CSRF验证失败解决方案

    前言 今天学习Django框架,用ajax向后台发送post请求,直接报了403错误,说CSRF验证失败:先前用模板的话都是在里面加一个 {% csrf_token %} 就直接搞定了CSRF的问题了 ...

  9. 【Python】使用Scrapy 网络爬虫框架Demo

    安装 使用PyCharm安装,进入到PyCharm -> Preferences -> Project Interpreter,点击加号 查询框输入'Scrapy',点击'Install ...

最新文章

  1. golang:1.并发编程之互斥锁、读写锁详解
  2. 有福了,J2EE面试题集锦(附答案)
  3. UML学习总结(1)——UML学习入门
  4. hdu 3671 Boonie and Clyde
  5. 论文学习4-An Attentive Neural Architecture for Fine-grained Entity Type Classification
  6. 前端请求接口post_接口自动化测试-WEB资讯专栏-DMOZ中文网站分类目录
  7. SAP License:创建新的库存地点
  8. Python爬取王者荣耀皮肤
  9. Mysql数据库知识总结
  10. Hi,Let's Get Started,Mr Qu
  11. nginx location的命中过程
  12. Python语言程序设计 嵩天
  13. 利用Veeam BackupReplication工具实现vsphere虚拟机备份
  14. 地下城php补丁怎么用,dnf技能补丁怎么用到WeGame(附其使用教程)
  15. 非负大整数加法---网易校招附加题
  16. 程序员笑话常客:“rm -rf *“和 “rm -rf /*“的区别
  17. 未授权下载导致的信息泄露
  18. 计算机显示器上有条纹,电脑屏幕出现条纹,教您电脑屏幕出现条纹怎么办
  19. python debugger extension_Pykd——Python extension for WinDbg
  20. EasyPR-Java新能源车牌识别

热门文章

  1. mysql 一次性导入数据库_Mysql 一次性备份导出/导入恢复所有数据库
  2. Spring配置文件-Bean生命周期配置(init-method方法,destory-method方法)
  3. 湖南人文科技学院没有计算机一级能毕业吗,在湖南人文科技学院读书真的是生不如死...
  4. redis三种架构:主从Cluster哨兵+整合Springboot访问redis
  5. 用拦截器+注解+cookie进行简单限流访问案例
  6. 【后端过程记录】用flask搭建服务器作后端接收数据 将base64字符串码解码为可读取文件 载入训练好的模型进行预测
  7. 基于Solr的HBase多条件查询测试
  8. JavaScript学习笔记06【高级——JavaScript中的事件】
  9. 高三英语作文【展示】——那夕阳下的奔跑是我逝去的青春
  10. Android Flow遇见Retrofit网络请求实践