python利用requests库模拟post请求时json的使用教程


Posted in Python onDecember 07, 2018

我们都见识过requests库在静态网页的爬取上展现的威力,我们日常见得最多的为get和post请求,他们最大的区别在于安全性上:

1、GET是通过URL方式请求,可以直接看到,明文传输。

2、POST是通过请求header请求,可以开发者工具或者抓包可以看到,同样也是明文的。 3.GET请求会保存在浏览器历史纪录中,还可能会保存在Web的日志中。

两者用法上也有显著差异(援引自知乎):

1、GET用于从服务器端获取数据,包括静态资源(HTML|JS|CSS|Image等等)、动态数据展示(列表数据、详情数据等等)。

2、POST用于向服务器提交数据,比如增删改数据,提交一个表单新建一个用户、或修改一个用户等。

对于Post请求,我们可以通过浏览器开发者工具或者其他外部工具来进行抓包,得到请求的URL、请求头(request headers)以及请求的表单data信息,这三样恰恰是我们用requests模拟post请求时需要的,典型的写法如下:

response=requests.post(url=url,headers=headers,data=data_search)

由于post请求很多时候是配合Ajax(异步加载)技术一起使用的,我们抓包时,可以直接选择XHR(XmlHttpRequest)-ajax的一种对象,帮助我们滤掉其他的一些html、css、js类文件,如下图所示(截取自Chrome):

python利用requests库模拟post请求时json的使用教程

双击点开,就可以在页面右边的Headers页下看到General、Response Headers、Request Headers、Form Data几个模块,

其中General模块能看到请求的方法和请求的URL以及服务器返回的状态码(200(成功) 服务器已成功处理了请求。通常,这表示服务器提供了请求的网页。)

python利用requests库模拟post请求时json的使用教程

而Response Headers部分,可以看到缓存控制、服务器类型、返回内容格式、有效期等参数(笔者截图所示,返回的为json文件):

python利用requests库模拟post请求时json的使用教程

Request Header模块是非常重要的,可以有效地将我们的爬取行为模拟成浏览器行为,应对常规的服务器反爬机制:

其中Content-Type、Cookie以及User-Agent字段较为重要,需要我们构造出来(其他字段大多数时候,不是必须)

python利用requests库模拟post请求时json的使用教程

由于Cookie字段记录了用户的登陆信息,每次都不同,且同一个cookie存在一定有效期,当我们结合Selenium来组合爬取页面信息时,可以通过selenium完成网页的登陆校验,然后利用selenium提取出cookie,再转换为浏览器能识别的cookie格式,通常代码如下所示:

cookies = driver.get_cookies() #利用selenium原生方法得到cookies
ret=''
for cookie in cookies:
  cookie_name=cookie['name']
  cookie_value=cookie['value']
  ret=ret+cookie_name+'='+cookie_value+';' #ret即为最终的cookie,各cookie以“;”相隔开

紧接着,我们需要构造headers部分(即请求头),我们挑重点的几个字段进行构造:

headers={
  'Host':'**********.com',
  'Referer':'http://****************/check/index.do',
  'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36',
  'X-Requested-With':'XMLHttpRequest',
  'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8',
  'Cookie':ret #需要登陆后捕获cookie并调用
}

我们在网页中点击“确定”按钮,网页则会异步加载,后台发出post请求,取到json文件并渲染到网页表单中,比如我们根据需求填写了部分字段(这些就是我们post请求的data信息),然后观察后台的form data信息:

python利用requests库模拟post请求时json的使用教程

后台Form data 捕获到的data参数如图:

python利用requests库模拟post请求时json的使用教程

类似于字典格式,其中condition键对应的value较为复杂——列表中包含字典,字典中还有部分函数,其中字符串中既有单引号又有双引号交错。属于关键信息,page决定了网页的翻页在第几页,而rows则表示每次请求的数据限定的最大行数。

本例中问题的关键是,如何把想要的信息(譬如来源于excel配置文件)传递到condition字段对应的值内,确保Form data信息灵活可配置,大抵用法如下:

data_search={
  'page':1,
  'rows':15,
  'condition':
  """[\
    {"column":"BPM_DEF_NAME","exp":"like","value":""},\
    {"column":"DELETE_STATUS","exp":"=","value":0},\
    {"column":"TO_CHAR(TO_DATE(CREATE_DATE,'YYYY-MM-DD HH24:MI:SS'),'YYYY-MM-DD')","exp":">=","value":"YYYY-MM-DD"},\
    {"column":"TO_CHAR(TO_DATE(CREATE_DATE,'YYYY-MM-DD HH24:MI:SS'),'YYYY-MM-DD')","exp":"<=","value":"YYYY-MM-DD"},\
    {"column":"CHECK_TYPE","exp":"like","value":"2"},\
    {"column":"LOCKED_STATUS","exp":"=","value":0},\
    {"column":"DELETE_STATUS","orderType":"default","orderKey":"","direction":"ASC"}\
  ]""",  #考虑到该字段已经有单引号、双引号,所以只能用三引号来包住这部分代表字符串
  'additionalParams':'{}'
}
data_search_condition=json.loads(data_search['condition'])  #将字符串转为列表,方便更新列表(列表中每个元素都是一个单个字典)元素
#刷新字典
data_search_condition[0]['value']=businessName
data_search_condition[2]['value']=str(startDate)
data_search_condition[3]['value']=str(endDate)
data_search['condition']=json.dumps(data_search_condition) #将列表重新转回字符串,作为data_search字典中键“condition”对应的“value”,然后更新字典

上述代码中,data_search其实为字典对象,其键“condition”对应的值(三引号包住部分)为字符串,本质是json格式,我们如何对这部分动态传参呢?

这里需要用到python json包中常用的loads和dumps方法:

1、json.loads()是将json格式对象,转化Python可识别的字典对象。解码python json格式,可以用这个模块的json.loads()函数的解析方法。

2、json.dumps()是将一个Python数据类型列表进行json格式的编码解析,可以将一个list列表对象,进行了json格式的编码转换。

3、json.dump和json.dumps很不同,json.dump主要用来json文件读写,和json.load函数配合使用。

上面实例中,就是将data_search['condition'](json,字符串)转换为列表,然后根据列表定位到底层的每个dict字典,最后根据dict[Key]=value的方法进行更新(传参),更新完之后的列表,再通过json.dumps反向转回字符串,这样整个data_search字典中参数就可以灵活配置,通过外部引入了。

剩下的工作就很简单,交给强大的Requests包完成就好,示例代码如下:

def get_page(data_search,url): #定义页面解析的函数,返回值为json格式
  try:
    response=requests.post(url=url,headers=headers,data=data_search)
    if response.status_code==200:
      return response.json()
  except requests.ConnectionError as e:
    print('Error',e.args)

我们还可以把json格式内容存到本地(data.json)格式文件或者txt文本,并按照特定缩进(indent=4)进行规则排版,格式化内容,此时要用到json.dump()方法,示例代码如下:

for pageNum in range(1,1000):
  data_search['page']=str(pageNum)
  pageContent=get_page(data_search=data_search,url=url)
  with open('data.json','w',encoding="utf-8") as json_file:
    json.dump(pageContent,json_file,ensure_ascii = False,indent=4)
  if pageContent==None:
    print("无符合条件的单据!") 
    time.sleep(3)
    sys.exit(0)

格式化后的json看上去直观不少:

python利用requests库模拟post请求时json的使用教程

 

最后感慨一句:爬虫是门技术活,任何一个技术理解地不够透彻,碰到复杂的问题,可能就要花上很长时间去试错,譬如本文示例中的字典、json包几个功能的使用,稍微出错,就无法请求到对的数据!

PS:特别强调一点,有的时候requests.post()方法中data字段不填或者填写有误,服务器有时也会返回200状态码以及相应内容。这种情况下,我们一定要与手工操作得到的json文件进行对比,看看我们的传参(多测试几组不同的参数,看返回json内容是否不同)是否真的起到作用,以免空欢喜一场!

总结

以上所述是小编给大家介绍的python利用requests库模拟post请求时json的使用教程 ,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Python 相关文章推荐
python使用点操作符访问字典(dict)数据的方法
Mar 16 Python
Python解惑之True和False详解
Apr 24 Python
python自动化脚本安装指定版本python环境详解
Sep 14 Python
Python中enumerate函数代码解析
Oct 31 Python
Python将多个excel表格合并为一个表格
Feb 22 Python
python机器学习之贝叶斯分类
Mar 26 Python
python 用opencv调用训练好的模型进行识别的方法
Dec 07 Python
pytorch 在网络中添加可训练参数,修改预训练权重文件的方法
Aug 17 Python
python字符串格式化方式解析
Oct 19 Python
Python基于smtplib模块发送邮件代码实例
May 29 Python
Python求区间正整数内所有素数之和的方法实例
Oct 13 Python
VSCODE配置Markdown及Markdown基础语法详解
Jan 19 Python
Python 加密与解密小结
Dec 06 #Python
Python 带有参数的装饰器实例代码详解
Dec 06 #Python
DES加密解密算法之python实现版(图文并茂)
Dec 06 #Python
python获取时间及时间格式转换问题实例代码详解
Dec 06 #Python
python中ImageTk.PhotoImage()不显示图片却不报错问题解决
Dec 06 #Python
Python3非对称加密算法RSA实例详解
Dec 06 #Python
Python3对称加密算法AES、DES3实例详解
Dec 06 #Python
You might like
PHP中extract()函数的定义和用法
2012/08/17 PHP
浅谈php正则表达式中的非贪婪模式匹配的使用
2014/11/25 PHP
window.addeventjs事件驱动函数集合addEvent等
2008/02/19 Javascript
百度留言本js 大家可以参考下
2009/10/13 Javascript
ToolTips JQEURY插件之简洁小提示框效果
2011/11/19 Javascript
js控制表单操作的常用代码小结
2013/08/15 Javascript
jquery组件使用中遇到的问题整理及解决
2014/02/21 Javascript
3种Jquery限制文本框只能输入数字字母的方法
2014/12/03 Javascript
AngularJS中比较两个数组是否相同
2016/08/24 Javascript
js清除浏览器缓存的几种方法
2017/03/15 Javascript
AngularJS中的promise用法分析
2017/05/19 Javascript
react-native使用react-navigation进行页面跳转导航的示例
2017/09/07 Javascript
js 发布订阅模式的实例讲解
2017/09/10 Javascript
ES6学习教程之块级作用域详解
2017/10/09 Javascript
vue 动态绑定背景图片的方法
2018/08/10 Javascript
使用Angular material主题定义自己的组件库的配色体系
2019/09/04 Javascript
Layui弹出层 加载 做编辑页面的方法
2019/09/16 Javascript
jQuery实现可编辑的表格
2019/12/11 jQuery
微信小程序将页面按钮悬浮固定在底部的实现代码
2020/10/29 Javascript
vue解决跨域问题(推荐)
2020/11/10 Javascript
测试、预发布后用python检测网页是否有日常链接
2014/06/03 Python
Python版微信红包分配算法
2015/05/04 Python
Python实现好友全头像的拼接实例(推荐)
2017/06/24 Python
python自动登录12306并自动点击验证码完成登录的实现源代码
2018/04/25 Python
pyqt 实现QlineEdit 输入密码显示成圆点的方法
2019/06/24 Python
python实现串口自动触发工作的示例
2019/07/02 Python
python制作朋友圈九宫格图片
2019/11/03 Python
html5实现九宫格抽奖可固定抽中某项奖品
2020/06/15 HTML / CSS
Otiumberg官网:英国半精致珠宝品牌
2021/01/16 全球购物
银行职业规划书范文
2013/12/28 职场文书
简历中个人自我评价分享
2014/03/15 职场文书
养成教育经验材料
2014/05/26 职场文书
七一建党日演讲稿
2014/09/05 职场文书
机关干部三严三实心得体会
2014/10/13 职场文书
2015最新学生自我评价范文
2015/03/03 职场文书
团队拓展训练感想
2015/08/07 职场文书