翼度科技»论坛 编程开发 python 查看内容

python模拟登陆、POST/GET请求方式

4

主题

4

帖子

12

积分

新手上路

Rank: 1

积分
12
python模拟登陆、POST/GET请求

通常我们在访问网页时,都会通过某个输入框输入数据,网页就会发出POST、GET或者其他形式向服务器发起请求,成功后并返回数据到前台展示。以下针对python的requests库做简单介绍。
前提先安装python以及requests库
安装requests:
  1. pip install requests
复制代码
请求测试url = http://www.test.com

一、GET请求

1、无请求参数:直接访问某url链接即可获取数据
  1. result = requests.get(url=url)
  2. print(result.status_code) # 请求状态
  3. print(result.url)# 请求url
  4. print(result.text) # 请求结果
复制代码
2、有请求参数:键值对形式表示参数
  1. result = requests.get(url=url, params={'keyword1':'val1','keyword2':'val2'})
  2. #或者可以直接先拼接url
  3. #new_url = url + '?keyword1=' + val1 + '&keyword1=' +val2
  4. #result = requests.get(url=new_url)

  5. print(result.status_code) # 请求状态
  6. print(result.url)# 请求url
  7. print(result.text) # 请求结果
复制代码
3、有请求头部参数:键值对形式表示参数
  1. result = requests.get(url=url, params={'keyword1':'val1','keyword2':'val2'})
  2. #或者可以直接先拼接url
  3. #new_url = url + '?keyword1=' + val1 + '&keyword1=' +val2
  4. #result = requests.get(url=new_url)

  5. print(result.status_code) # 请求状态
  6. print(result.url)# 请求url
  7. print(result.text) # 请求结果
复制代码
二、POST请求

1、请求的结果集是application/x-www-form-urlencoded
  1. result = requests.post(url=url,data={'keyword1':'val1','keyword2':'val2'},headers={'Content-Type':'application/x-www-form-urlencoded'})
  2. print(result.status_code) # 请求状态
  3. print(result.url)# 请求url
  4. print(result.text) # 请求结果
复制代码
2、请求的结果集是multipart/form-data
  1. result = requests.post(url=url,data={'keyword1':'val1','keyword2':'val2'},headers={'Content-Type':'multipart/form-data'})
  2. print(result.status_code) # 请求状态
  3. print(result.url)# 请求url
  4. print(result.text) # 请求结果
复制代码
3、请求的结果集是application/json
  1. import json
  2. data = {'keyword1':'val1','keyword2':'val2'}
  3. json_data = json.dumps(data)
  4. result = requests.post(url=url,data=json_data,headers={'Content-Type':'application/json'})
  5. print(result.status_code) # 请求状态
  6. print(result.url)# 请求url
  7. print(result.text) # 请求结果
复制代码
如下图:


下来来说一下之前自己遇到的坑,请求方式为POST,且为Request Payload形式的请求。
一开始自以为跟form-data一样,只传一个url跟data,且data没有格式化成JSON,导致请求回来的状态为415:服务器无法处理请求附带的媒体格式,经查阅后来改个格式以及请求头就顺利返回数据。
完整demo如下:
  1. import json
  2. import requests
  3. import datetime
  4. import re, urllib.request, lxml.html, http.cookiejar

  5. url = 'http://test.com/products'
  6. # payloadData数据
  7. payload_data = {'keyword1': "val1", 'keyword2': "val2"}
  8. # 请求头设置
  9. payload_header = {
  10. 'Host': 'test.com',
  11. 'Content-Type': 'application/json; charset=UTF-8',
  12. }
  13. # 下载超时
  14. timeout = 30
  15. # 代理IP
  16. # proxy_list = {"HTTP":'http://210.22.5.117"3128',"HTTP":'http://163.172.189.32:8811',"HTTP":'http://180.153.144.138:8800'}
  17. json_data = json.dumps(payload_data)
  18. # allow_redirects 是否重定向
  19. # result = requests.post(url=url, data=json_data, headers=payloadHeader, timeout=timeout, proxies=proxy_list, allow_redirects=True)

  20. result = requests.post(url, data=json_data, headers=payload_header, timeout=timeout, allow_redirects=True)
  21. # 下面这种直接填充json参数的方式也OK
  22. # result = requests.post(url, json=json_data, headers=payload_header)
  23. print("请求耗时:{0}, 状态码:{1}, 结果:{2}".format(datetime.datetime.now(),res.status_code,res.text))
复制代码
三、需要模拟登陆后再发送Post请求

有时候就想模拟页面上的某些细微的操作,例如登录后需要在前端利用ajax请求修改数据。
如果只是极个别数量修改的话,那还是前端直接操作快一点。
如果是大批量的修改那还是得借住程序遍历修改即可。
登录页面:


先打开F12进入开发者模式,然后随便在上面的表单输入框数据,点击登录,虽然是错误的登录数据,我们只是为了查看登录请求提交的数据格式,如下图:

其中的某些不是我们输入的隐藏值,我们需要到页面源码中的表单获取,右键查看页面源码,把那些非自己输入的 “__VIEWSTATE",”__VIEWSTATEGENERATOR","__EVENTVALIDATION" 的值到原页面中查找,例如:

也就是说我们得事先先访问该页面页面源码并解析获取以上属性值:
  1. import requests, string
  2. import re, urllib.request, lxml.html, http.cookiejar

  3. login_url = "http://test.com/Login.aspx"
  4. response = urllib.request.urlopen(login_url)
  5. f = response.read()
  6. doc = lxml.html.document_fromstring(f)

  7. VIEWSTATE = doc.xpath("//input[@id='__VIEWSTATE']/@value")
  8. VIEWSTATEGENERATOR = doc.xpath("//input[@id='__VIEWSTATEGENERATOR']/@value")
  9. EVENTVALIDATION = doc.xpath("//input[@id='__EVENTVALIDATION']/@value")
复制代码
获取到这些之后,得把这些值放回到Form-Data(表单数据中):
  1. from urllib.parse import quote
  2. login_data = urllib.parse.urlencode({
  3.        '__EVENTTARGET' : '',
  4.        '__EVENTARGUMENT' : '',
  5.        '__VIEWSTATE' : VIEWSTATE[0],
  6.        '__VIEWSTATEGENERATOR' : VIEWSTATEGENERATOR[0],
  7.        '__EVENTVALIDATION' : EVENTVALIDATION[0],
  8.        'TextCustomerID' : "真实商户号",
  9.        'TextAdminName' : '真实用户名',
  10.        'TextPassword' : '真实密码',
  11.        'btnLogin.x' : 40,
  12.        'btnLogin.y' : 10
  13.     }).encode('utf-8')
复制代码
登录参数的编码很重要,如果没有进行utf-8编码会报以下错误:
  1. Traceback (most recent call last):  File "c:\users\user\appdata\local\programs\python\python38\lib\http\client.py", line 965, in send    self.sock.sendall(data)  File "c:\users\user\appdata\local\programs\python\python38\lib\ssl.py", line 1201, in sendall    with memoryview(data) as view, view.cast("B") as byte_view:TypeError: memoryview: a bytes-like object is required, not 'str'
复制代码
表单数据有了,接下来就是把请求头也要获取出来:
  1. header = {
  2.    'Host': 'www.test.com',
  3.     'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0',
  4.     'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
  5.     'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
  6.     'Accept-Encoding': 'gzip, deflate',
  7.     'Content-Type': 'application/x-www-form-urlencoded',
  8.     'Origin': 'http://www.test.com',
  9.     'Connection': 'keep-alive',
  10.     'Referer': 'http://www.test.com/Login.aspx',
  11.     'Upgrade-Insecure-Requests': 1
  12. }
复制代码
模拟登陆并保存cookie:
  1. #模拟登录请求
  2. login_request = urllib.request.Request(login_url, login_data, Headers)
  3. #创建cookie,利用cookie实现持久化登录
  4. cj = http.cookiejar.CookieJar()
  5. opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))
  6. login_result = opener.open(login_request)
复制代码
最后模拟登陆后,如果是要采集某页面数据的话也可以通过urllib.request.urlopen访问页面链接读取页面源码进行数据采集。
如果有批量数据需要进行Post/Get处理,那么就可以把待处理的数据获取好,然后遍历发起Post或Get请求即可:
  1. import time, random

  2. var datas = {.....}
  3. for data in datas:
  4.     response = requests.get(url, headers = headers, data=json_data, cookies = cj)
  5.     # 或
  6.     response = requests.post(url, headers = headers, data=json_data, cookies = cj)
  7.     time.sleep(random.randint(3, 5))
复制代码
总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

来源:https://www.jb51.net/python/3162627bd.htm
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具