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读写配置文件的方法
Jun 03 Python
Python中绑定与未绑定的类方法用法分析
Apr 29 Python
Python程序退出方式小结
Dec 09 Python
Python解决N阶台阶走法问题的方法分析
Dec 28 Python
详谈Python3 操作系统与路径 模块(os / os.path / pathlib)
Apr 26 Python
Python实现去除列表中重复元素的方法小结【4种方法】
Apr 27 Python
python 识别图片中的文字信息方法
May 10 Python
Python面向对象之接口、抽象类与多态详解
Aug 27 Python
python里dict变成list实例方法
Jun 26 Python
一行Python代码制作动态二维码的实现
Sep 09 Python
python中matplotlib实现随鼠标滑动自动标注代码
Apr 23 Python
python 基于opencv实现图像增强
Dec 23 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程序员工具
2008/05/26 PHP
修复ShopNC使用QQ 互联时提示100010 错误
2015/11/08 PHP
tp5(thinkPHP5框架)使用DB实现批量删除功能示例
2019/05/28 PHP
PHP手机号码及邮箱正则表达式实例解析
2020/07/11 PHP
一些有关检查数据的JS代码
2006/09/07 Javascript
js跟随滚动条滚动浮动代码
2009/12/31 Javascript
jQuery 自动增长的文本输入框实现代码
2010/04/02 Javascript
js处理表格对table进行修饰
2014/05/26 Javascript
JavaScript中的类与实例实现方法
2015/01/23 Javascript
JavaScript实现SHA-1加密算法的方法
2015/03/11 Javascript
JQuery实现可直接编辑的表格
2015/04/16 Javascript
jquery实现隐藏在左侧的弹性弹出菜单效果
2015/09/18 Javascript
js实现上一页下一页的效果【附代码】
2016/03/10 Javascript
js验证框架之RealyEasy验证详解
2016/06/08 Javascript
AngularJS入门教程之 XMLHttpRequest实例讲解
2016/07/27 Javascript
javascript将中国数字格式转换成欧式数字格式的简单实例
2016/08/02 Javascript
jQuery多文件异步上传带进度条实例代码
2016/08/16 Javascript
原生JS取代一些JQuery方法的简单实现
2016/09/20 Javascript
解决vuecli3.0热更新失效的问题
2018/09/19 Javascript
用npm-run实现自动化任务的方法示例
2019/01/14 Javascript
Vue发布订阅模式实现过程图解
2020/04/30 Javascript
node中短信api实现验证码登录的示例代码
2021/01/20 Javascript
python文件和目录操作函数小结
2014/07/11 Python
python数据类型_字符串常用操作(详解)
2017/05/30 Python
Python找出最小的K个数实例代码
2018/01/04 Python
Django实现登录随机验证码的示例代码
2018/06/20 Python
python爬虫之urllib3的使用示例
2018/07/09 Python
基于Python快速处理PDF表格数据
2020/06/03 Python
Django自带的用户验证系统实现
2020/12/18 Python
第一批党的群众路线教育实践活动工作总结
2014/03/03 职场文书
做一个有道德的人演讲稿
2014/05/14 职场文书
礼貌问候语大全
2015/11/10 职场文书
创业计划书之面包店
2019/09/12 职场文书
mysql连接查询中and与where的区别浅析
2021/07/01 MySQL
python自动化操作之动态验证码、滑动验证码的降噪和识别
2021/08/30 Python
实现GO语言对数组切片去重
2022/04/20 Golang