当前位置: 首页 > 编程笔记 >

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

颜志学
2023-03-14
本文向大家介绍python利用requests库模拟post请求时json的使用教程,包括了python利用requests库模拟post请求时json的使用教程的使用技巧和注意事项,需要的朋友参考一下

我们都见识过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):

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

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

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

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

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

由于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信息:

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

类似于字典格式,其中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看上去直观不少:

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

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

总结

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

 类似资料:
  • 本文向大家介绍python-requests POST请求,包括了python-requests POST请求的使用技巧和注意事项,需要的朋友参考一下 示例 POST请求是使用方法发出的。request.post() 如果您需要发送Web表单请求作为POST正文,请传入以键值对作为data参数的字典;requests会将它们编码为application/x-www-form-urlencoded模

  • 问题内容: 我正在做一个项目,其中我的解析器 窃取了 有关特定站点上每个视频的数据,并将其保存到我的数据库中。除了指向隐藏视频的完整链接之外,我已完成所有工作。 有一个播放器,它会自动从页面加载开始。我发现启动播放器的JavaScript代码: 通话后,因此,如果没有错误发现它开始使用播放器 的文件名 从 响应 。那就是我所需要的。 我重新检查了 Live HTTP标头中 的呼叫: 因此它使用特定

  • 通过HttpUrlConnection在服务器上注册用户数据的Post请求 在android中通过http post方法发送json对象 如何用Android通过请求发送JSON对象?

  • 本文向大家介绍PHP使用stream_context_create()模拟POST/GET请求的方法,包括了PHP使用stream_context_create()模拟POST/GET请求的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了PHP使用stream_context_create()模拟POST/GET请求的方法。分享给大家供大家参考,具体如下: 有时候,我们需要在服务器端模

  • 本文向大家介绍python 使用 requests 模块发送http请求 的方法,包括了python 使用 requests 模块发送http请求 的方法的使用技巧和注意事项,需要的朋友参考一下 Requests具有完备的中英文文档, 能完全满足当前网络的需求, 它使用了urllib3, 拥有其所有的特性! 最近在学python自动化,怎样用python发起一个http请求呢? 通过了解 requ

  • 问题内容: 我想仅使用本机Python库将JSON编码的数据发送到服务器。我喜欢请求,但我根本无法使用它,因为我无法在运行脚本的计算机上使用它。我需要没有它。 我的服务器是本地WAMP服务器。我总是得到一个 urllib.error.HTTPError:HTTP错误500:内部服务器错误 我 100%确信 这 不是 服务器问题,因为在同一台计算机上,同一台服务器上的同一数据,相同的url与请求库和