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设置Socket代理及实现远程摄像头控制的例子
Nov 13 Python
Python的时间模块datetime详解
Apr 17 Python
Python生成数字图片代码分享
Oct 31 Python
Python字符串拼接六种方法介绍
Dec 18 Python
python读取图片的方式,以及将图片以三维数组的形式输出方法
Jul 03 Python
详解python解压压缩包的五种方法
Jul 05 Python
python实现飞机大战小游戏
Nov 08 Python
Python解压 rar、zip、tar文件的方法
Nov 19 Python
Python之Matplotlib文字与注释的使用方法
Jun 18 Python
pycharm使用技巧之自动调整代码格式总结
Nov 04 Python
Python页面加载的等待方式总结
Feb 28 Python
Python中的xlrd模块使用整理
Jun 15 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连接MySQL代码的参数说明
2008/06/07 PHP
php session实现多级目录存放实现代码
2016/02/03 PHP
使用dynatrace-ajax跟踪JavaScript的性能
2010/04/12 Javascript
Nodejs中读取中文文件编码问题、发送邮件和定时任务实例
2015/01/01 NodeJs
javascript操作ul中li的方法
2015/05/14 Javascript
JavaScript去除数组里重复值的方法
2015/07/13 Javascript
Vue.js 和 MVVM 的注意事项
2016/11/07 Javascript
javascript基本数据类型及类型检测常用方法小结
2016/12/14 Javascript
Vue动态实现评分效果
2017/05/24 Javascript
详解VUE中v-bind的基本用法
2017/07/13 Javascript
vue如何根据网站路由判断页面主题色详解
2018/11/02 Javascript
对vue中的事件穿透与禁止穿透实例详解
2019/10/28 Javascript
JS原型对象操作实例分析
2020/06/06 Javascript
[08:08]DOTA2-DPC中国联赛2月28日Recap集锦
2021/03/11 DOTA
Python字符串替换实例分析
2015/05/11 Python
Python基于DES算法加密解密实例
2015/06/03 Python
python判断所输入的任意一个正整数是否为素数的两种方法
2019/06/27 Python
Python破解BiliBili滑块验证码的思路详解(完美避开人机识别)
2020/02/17 Python
python实现excel公式格式化的示例代码
2020/12/23 Python
美国轮胎网站:Priority Tire
2018/11/28 全球购物
abstract class和interface有什么区别?
2012/01/03 面试题
一组SQL面试题
2016/02/15 面试题
介绍一下Java的事务处理
2012/12/07 面试题
一套英文Java笔试题面试题
2016/04/21 面试题
开办加工厂创业计划书
2014/01/03 职场文书
电子专业毕业生自我鉴定
2014/01/22 职场文书
初中高效课堂实施方案
2014/02/26 职场文书
2014三八妇女节活动总结
2014/03/01 职场文书
《春天来了》教学反思
2014/04/07 职场文书
机房搬迁方案
2014/05/01 职场文书
健康家庭事迹材料
2014/05/02 职场文书
党员承诺书范文
2014/05/19 职场文书
物价局领导班子四风问题整改措施
2014/10/26 职场文书
九九重阳节致辞
2015/07/31 职场文书
宾馆客房管理制度
2015/08/06 职场文书
2016年法制宣传月活动总结
2016/04/01 职场文书