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下的Mysql模块MySQLdb安装详解
Apr 09 Python
Python爬虫辅助利器PyQuery模块的安装使用攻略
Apr 24 Python
python对配置文件.ini进行增删改查操作的方法示例
Jul 28 Python
python检测空间储存剩余大小和指定文件夹内存占用的实例
Jun 11 Python
Flask实现图片的上传、下载及展示示例代码
Aug 03 Python
Python3.4学习笔记之 idle 清屏扩展插件用法分析
Mar 01 Python
python使用turtle绘制国际象棋棋盘
May 23 Python
pycharm通过ssh连接远程服务器教程
Feb 12 Python
Python unittest基本使用方法代码实例
Jun 29 Python
Python函数__new__及__init__作用及区别解析
Aug 31 Python
Python 3.9的到来到底是意味着什么
Oct 14 Python
利用Python判断整数是否是回文数的3种方法总结
Jul 07 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函数scandir排除特定目录
2014/06/12 PHP
WordPress中"无法将上传的文件移动至"错误的解决方法
2015/07/01 PHP
php大小写转换函数(strtolower、strtoupper)用法介绍
2017/11/17 PHP
[原创]网络复制内容时常用的正则+editplus
2006/11/30 Javascript
JQuery+JS实现仿百度搜索结果中关键字变色效果
2011/08/02 Javascript
判断文件是否正在被使用的JS代码
2013/12/21 Javascript
2014最热门的JavaScript代码高亮插件推荐
2014/11/25 Javascript
Javascript 是你的高阶函数(高级应用)
2015/06/15 Javascript
简单解析JavaScript中的__proto__属性
2016/05/10 Javascript
微信小程序 页面之间传参实例详解
2017/01/13 Javascript
nodejs+express实现文件上传下载管理网站
2017/03/15 NodeJs
vue分类筛选filter方法简单实例
2017/03/30 Javascript
JavaScript标准对象_动力节点Java学院整理
2017/06/27 Javascript
JavaScript数组push方法使用注意事项
2017/10/30 Javascript
浅谈vue生命周期共有几个阶段?分别是什么?
2020/08/07 Javascript
[01:34]DAC2018主赛事第四日五佳镜头 Gh巨牙海民助Miracle-死里逃生
2018/04/07 DOTA
[02:08]什么藏在DOTA2 TI9“小紫本”里?斧王历险记告诉你!
2019/05/17 DOTA
Python检测一个对象是否为字符串类的方法
2015/05/21 Python
探究python中open函数的使用
2016/03/01 Python
Python如何获取系统iops示例代码
2016/09/06 Python
python爬虫获取多页天涯帖子
2018/02/23 Python
python画折线图的程序
2018/07/26 Python
解决Pandas的DataFrame输出截断和省略的问题
2019/02/08 Python
python采集百度搜索结果带有特定URL的链接代码实例
2019/08/30 Python
利用python如何实现猫捉老鼠小游戏
2020/12/04 Python
python 利用百度API识别图片文字(多线程版)
2020/12/14 Python
面料业务员岗位职责
2013/12/26 职场文书
报社实习生自荐信
2014/01/24 职场文书
建议书的格式
2014/05/12 职场文书
植物生产学专业求职信
2014/08/08 职场文书
敬业奉献模范事迹材料
2014/12/24 职场文书
研究生论文答辩开场白
2015/05/27 职场文书
预备党员群众意见
2015/06/01 职场文书
培训感想范文
2015/08/07 职场文书
2016元旦晚会主持词开场白和结束语
2015/12/04 职场文书
MySQL注入基础练习
2021/05/30 MySQL