Python requests发送post请求的一些疑点


Posted in Python onMay 20, 2018

前言

在Python爬虫中,使用requests发送请求,访问指定网站,是常见的做法。一般是发送GET请求或者POST请求,对于GET请求没有什么好说的,而发送POST请求,有很多朋友不是很清楚,主要是因为容易混淆 POST提交的方式 。今天在微信交流群里,就有朋友遇到了这种问题,特地讲解一下。

在HTTP协议中,post提交的数据必须放在消息主体中,但是协议中并没有规定必须使用什么编码方式,从而导致了 提交方式 的不同。服务端根据请求头中的 Content-Type 字段来获知请求中的消息主体是用何种方式进行编码,再对消息主体进行解析。具体的编码方式包括如下:

  1. application/x-www-form-urlencoded:以form表单形式提交数据,最常见也是大家最熟悉的
  2.  application/json :以json串提交数据。

下面使用requests来发送上述三种编码的POST请求。

1.提交Form表单

requests提交Form表单,一般存在于网站的登录,用来提交用户名和密码。以http://httpbin.org/post 为例,在requests中,以form表单形式发送post请求,只需要将请求的参数构造成一个字典,然后传给requests.post()的data参数即可。代码如下:

url = 'http://httpbin.org/post'
d = {'key1': 'value1', 'key2': 'value2'}
r = requests.post(url, data=d)
print r.text

输出效果如下:

{
"args":{},
"data":"",
"files":{},
"form":{"key1":"value1","key2":"value2"},
"headers":{"Accept":"*/*","Accept-Encoding":"gzip, deflate",
"Connection":"close",
"Content-Length":"23",
"Content-Type":"application/x-www-form-urlencoded",
"Host":"httpbin.org",
"User-Agent":"python-requests/2.12.3"},
"json":null,
"origin":"113.140.11.122",
"url":http://httpbin.org/post}

httpbin.org网站可以显示你提交请求的内容,大家注意一下输出的"Content-Type":"application/x-www-form-urlencoded",证明这是提交Form的方式。大家在登录一个网站时,可以观察一下Content-Type是什么。

2.提交json串

对于提交json串,主要是用于发送ajax请求中,动态加载数据。以拼多多网站为例,加载商品的方式为ajax,商品的内容在响应中。

Python requests发送post请求的一些疑点

下面把请求头和请求实体列举一下:

Python requests发送post请求的一些疑点 

一些初学者根据请求头写爬虫,就会犯requests的使用错误。

错误写法

import requests
__author__ = 'qiye'
__date__ = '2018/5/19 21:59'

url = "http://jinbao.pinduoduo.com/network/api/common/goodsList"
data ={"pageSize":60,"pageNumber":1,"withCoupon":0,"sortType":0}
headers = {
  'Content-Type':'application/json; charset=UTF-8',
  'Host':'jinbao.pinduoduo.com',
  'Origin':'http://jinbao.pinduoduo.com',
  'Referer':'http://jinbao.pinduoduo.com/',
  'User-Agent':'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Mobile Safari/537.36',
  'Accept': 'application/json, text/javascript, */*; q=0.01',
}
r = requests.post(url=url,data =data,headers=headers)
print(r.text)

打印的内容如下:

{"success":false,"errorCode":4000000,"errorMsg":"System Error","result":null}

返回出错了,这时候百思不得其解,请求头我都保持一致了呀,'Content-Type':'application/json; charset=UTF-8'都加上了,为什么会出错呀?

答案在于,你的请求实体的格式错了,服务端无法解码。

正确写法1

正确代码是把data进行json编码,再发送。代码如下:

r = requests.post(url=url,data =json.dumps(data),headers=headers)

这个时候再看一下打印内容,已经正确返回商品内容了。

{"success":true,"errorCode":1000000,"errorMsg":null,"result":{"total":2271278,"goodsList":[{"goodsId":998422995,"goodsName":"【4液+1器】皎洁电热蚊香液 孕妇宝宝驱蚊儿童婴无味防蚊液体","goodsImageUrl":"http://t11img.yangkeduo.com/images/2018-04-12/0292b5e75053dfa748b9762d3f3e74ef.jpeg","soldQuantity":175,"minGroupPrice":24890,"categoryId":4,"categoryName":"母婴","hasCoupon":true,"couponMinOrderAmount":5000,"couponDiscount":5000,"couponTotalQuantity":5000,"couponRemainQuantity":3940,"couponStartTime":1526572800,"couponEndTime":1527782399,"promotionRate":280},
...

正确写法2

处理将data主动编码为json发送之外,requests还提供了一个json参数,自动使用json方式发送,而且在请求头中也不用显示声明'Content-Type':'application/json; charset=UTF-8'。完整代码如下:

import requests

__author__ = 'qiye'
__date__ = '2018/5/19 21:59'

url = "http://jinbao.pinduoduo.com/network/api/common/goodsList"
data ={"pageSize":60,"pageNumber":1,"withCoupon":0,"sortType":0}
headers = {
  'Host':'jinbao.pinduoduo.com',
  'Origin':'http://jinbao.pinduoduo.com',
  'Referer':'http://jinbao.pinduoduo.com/',
  'User-Agent':'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Mobile Safari/537.36',
}
r = requests.post(url=url,json =data,headers=headers)
print(r.text)

3.上传文件

上传文件在爬虫中使用的很少,不过还是使用requests讲解一下使用方式。Content-Type类型为multipart/form-data,以multipart形式发送post请求,只需将一文件传给requests.post()的files参数即可。还是以http://httpbin.org/post 为例,代码如下:

url = 'http://httpbin.org/post'
files = {'file': open('upload.txt', 'rb')}
r = requests.post(url, files=files)
print(r.text)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python编程中time模块的一些关键用法解析
Jan 19 Python
深入理解Python对Json的解析
Feb 14 Python
Python使用sorted排序的方法小结
Jul 28 Python
Python 基础教程之闭包的使用方法
Sep 29 Python
Python自然语言处理 NLTK 库用法入门教程【经典】
Jun 26 Python
Python实现模拟浏览器请求及会话保持操作示例
Jul 30 Python
Python中修改字符串的四种方法
Nov 02 Python
在Python 字典中一键对应多个值的实例
Feb 03 Python
Flask框架学习笔记之模板操作实例详解
Aug 15 Python
python中字典按键或键值排序的实现代码
Aug 27 Python
Python类中self参数用法详解
Feb 13 Python
python opencv检测直线 cv2.HoughLinesP的实现
Jun 18 Python
python中virtualenvwrapper安装与使用
May 20 #Python
django静态文件加载的方法
May 20 #Python
django中静态文件配置static的方法
May 20 #Python
Python中跳台阶、变态跳台阶与矩形覆盖问题的解决方法
May 19 #Python
Python利用公共键如何对字典列表进行排序详解
May 19 #Python
Python中一些不为人知的基础技巧总结
May 19 #Python
Python + selenium自动化环境搭建的完整步骤
May 19 #Python
You might like
配置php网页显示各种语法错误
2013/09/23 PHP
非常重要的php正则表达式详解
2016/01/04 PHP
基于ThinkPHP实现的日历功能实例详解
2017/04/15 PHP
PHP学习笔记之session
2018/05/06 PHP
JavaScript 继承详解(三)
2009/07/13 Javascript
ASP中进行HTML数据及JS数据编码函数
2009/11/11 Javascript
js中查找最近的共有祖先元素的实现代码
2010/12/30 Javascript
使用forever管理nodejs应用教程
2014/06/03 NodeJs
JavaScript中匿名、命名函数的性能测试
2014/09/04 Javascript
详解JS函数重载
2014/12/04 Javascript
JavaScript编写检测用户所使用的浏览器的代码示例
2016/05/05 Javascript
让微信小程序支持ES6中Promise特性的方法详解
2017/06/13 Javascript
详解如何使用webpack打包JS
2018/06/21 Javascript
详解如何配置vue-cli3.0的vue.config.js
2018/08/23 Javascript
Vue瀑布流插件的使用示例
2018/09/19 Javascript
Vue-Quill-Editor富文本编辑器的使用教程
2018/09/21 Javascript
学习node.js 断言的使用详解
2019/03/18 Javascript
7个好用的JavaScript技巧分享(译)
2019/05/07 Javascript
Element-ui中元素滚动时el-option超出元素区域的问题
2019/05/30 Javascript
Vue data的数据响应式到底是如何实现的
2020/02/11 Javascript
解决新建一个vue项目过程中遇到的问题
2020/10/22 Javascript
浅析vue中的nextTick
2020/12/28 Vue.js
Python实现的金山快盘的签到程序
2013/01/17 Python
Python的装饰器模式与面向切面编程详解
2015/06/21 Python
hmac模块生成加入了密钥的消息摘要详解
2018/01/11 Python
python列表的增删改查实例代码
2018/01/30 Python
在Pycharm中执行scrapy命令的方法
2019/01/16 Python
python每5分钟从kafka中提取数据的例子
2019/12/23 Python
pytorch 中forward 的用法与解释说明
2021/02/26 Python
美国知名珠宝首饰品牌:Gemvara
2017/10/06 全球购物
校园环保标语
2014/06/13 职场文书
安全生产标语大全
2014/10/06 职场文书
世界环境日活动总结
2015/02/11 职场文书
胡桃夹子观后感
2015/06/11 职场文书
Python中三种花式打印的示例详解
2022/03/19 Python
Javascript中Microtask和Macrotask鲜为人知的知识点
2022/04/02 Javascript