python模擬登陸、POST/GET請(qǐng)求方式
python模擬登陸、POST/GET請(qǐng)求
通常我們?cè)谠L問(wèn)網(wǎng)頁(yè)時(shí),都會(huì)通過(guò)某個(gè)輸入框輸入數(shù)據(jù),網(wǎng)頁(yè)就會(huì)發(fā)出POST、GET或者其他形式向服務(wù)器發(fā)起請(qǐng)求,成功后并返回?cái)?shù)據(jù)到前臺(tái)展示。以下針對(duì)python的requests庫(kù)做簡(jiǎn)單介紹。
前提先安裝python以及requests庫(kù)
安裝requests:
pip install requests
請(qǐng)求測(cè)試url = http://www.test.com
一、GET請(qǐng)求
1、無(wú)請(qǐng)求參數(shù):直接訪問(wèn)某url鏈接即可獲取數(shù)據(jù)
result = requests.get(url=url) print(result.status_code) # 請(qǐng)求狀態(tài) print(result.url)# 請(qǐng)求url print(result.text) # 請(qǐng)求結(jié)果
2、有請(qǐng)求參數(shù):鍵值對(duì)形式表示參數(shù)
result = requests.get(url=url, params={'keyword1':'val1','keyword2':'val2'}) #或者可以直接先拼接url #new_url = url + '?keyword1=' + val1 + '&keyword1=' +val2 #result = requests.get(url=new_url) print(result.status_code) # 請(qǐng)求狀態(tài) print(result.url)# 請(qǐng)求url print(result.text) # 請(qǐng)求結(jié)果
3、有請(qǐng)求頭部參數(shù):鍵值對(duì)形式表示參數(shù)
result = requests.get(url=url, params={'keyword1':'val1','keyword2':'val2'}) #或者可以直接先拼接url #new_url = url + '?keyword1=' + val1 + '&keyword1=' +val2 #result = requests.get(url=new_url) print(result.status_code) # 請(qǐng)求狀態(tài) print(result.url)# 請(qǐng)求url print(result.text) # 請(qǐng)求結(jié)果
二、POST請(qǐng)求
1、請(qǐng)求的結(jié)果集是application/x-www-form-urlencoded
result = requests.post(url=url,data={'keyword1':'val1','keyword2':'val2'},headers={'Content-Type':'application/x-www-form-urlencoded'}) print(result.status_code) # 請(qǐng)求狀態(tài) print(result.url)# 請(qǐng)求url print(result.text) # 請(qǐng)求結(jié)果
2、請(qǐng)求的結(jié)果集是multipart/form-data
result = requests.post(url=url,data={'keyword1':'val1','keyword2':'val2'},headers={'Content-Type':'multipart/form-data'}) print(result.status_code) # 請(qǐng)求狀態(tài) print(result.url)# 請(qǐng)求url print(result.text) # 請(qǐng)求結(jié)果
3、請(qǐng)求的結(jié)果集是application/json
import json data = {'keyword1':'val1','keyword2':'val2'} json_data = json.dumps(data) result = requests.post(url=url,data=json_data,headers={'Content-Type':'application/json'}) print(result.status_code) # 請(qǐng)求狀態(tài) print(result.url)# 請(qǐng)求url print(result.text) # 請(qǐng)求結(jié)果
如下圖:
下來(lái)來(lái)說(shuō)一下之前自己遇到的坑,請(qǐng)求方式為POST,且為Request Payload形式的請(qǐng)求。
一開(kāi)始自以為跟form-data一樣,只傳一個(gè)url跟data,且data沒(méi)有格式化成JSON,導(dǎo)致請(qǐng)求回來(lái)的狀態(tài)為415:服務(wù)器無(wú)法處理請(qǐng)求附帶的媒體格式,經(jīng)查閱后來(lái)改個(gè)格式以及請(qǐng)求頭就順利返回?cái)?shù)據(jù)。
完整demo如下:
import json import requests import datetime import re, urllib.request, lxml.html, http.cookiejar url = 'http://test.com/products' # payloadData數(shù)據(jù) payload_data = {'keyword1': "val1", 'keyword2': "val2"} # 請(qǐng)求頭設(shè)置 payload_header = { 'Host': 'test.com', 'Content-Type': 'application/json; charset=UTF-8', } # 下載超時(shí) timeout = 30 # 代理IP # proxy_list = {"HTTP":'http://210.22.5.117"3128',"HTTP":'http://163.172.189.32:8811',"HTTP":'http://180.153.144.138:8800'} json_data = json.dumps(payload_data) # allow_redirects 是否重定向 # result = requests.post(url=url, data=json_data, headers=payloadHeader, timeout=timeout, proxies=proxy_list, allow_redirects=True) result = requests.post(url, data=json_data, headers=payload_header, timeout=timeout, allow_redirects=True) # 下面這種直接填充json參數(shù)的方式也OK # result = requests.post(url, json=json_data, headers=payload_header) print("請(qǐng)求耗時(shí):{0}, 狀態(tài)碼:{1}, 結(jié)果:{2}".format(datetime.datetime.now(),res.status_code,res.text))
三、需要模擬登陸后再發(fā)送Post請(qǐng)求
有時(shí)候就想模擬頁(yè)面上的某些細(xì)微的操作,例如登錄后需要在前端利用ajax請(qǐng)求修改數(shù)據(jù)。
如果只是極個(gè)別數(shù)量修改的話,那還是前端直接操作快一點(diǎn)。
如果是大批量的修改那還是得借住程序遍歷修改即可。
登錄頁(yè)面:
先打開(kāi)F12進(jìn)入開(kāi)發(fā)者模式,然后隨便在上面的表單輸入框數(shù)據(jù),點(diǎn)擊登錄,雖然是錯(cuò)誤的登錄數(shù)據(jù),我們只是為了查看登錄請(qǐng)求提交的數(shù)據(jù)格式,如下圖:
其中的某些不是我們輸入的隱藏值,我們需要到頁(yè)面源碼中的表單獲取,右鍵查看頁(yè)面源碼,把那些非自己輸入的 “__VIEWSTATE",”__VIEWSTATEGENERATOR","__EVENTVALIDATION" 的值到原頁(yè)面中查找,例如:
也就是說(shuō)我們得事先先訪問(wèn)該頁(yè)面頁(yè)面源碼并解析獲取以上屬性值:
import requests, string import re, urllib.request, lxml.html, http.cookiejar login_url = "http://test.com/Login.aspx" response = urllib.request.urlopen(login_url) f = response.read() doc = lxml.html.document_fromstring(f) VIEWSTATE = doc.xpath("http://input[@id='__VIEWSTATE']/@value") VIEWSTATEGENERATOR = doc.xpath("http://input[@id='__VIEWSTATEGENERATOR']/@value") EVENTVALIDATION = doc.xpath("http://input[@id='__EVENTVALIDATION']/@value")
獲取到這些之后,得把這些值放回到Form-Data(表單數(shù)據(jù)中):
from urllib.parse import quote login_data = urllib.parse.urlencode({ '__EVENTTARGET' : '', '__EVENTARGUMENT' : '', '__VIEWSTATE' : VIEWSTATE[0], '__VIEWSTATEGENERATOR' : VIEWSTATEGENERATOR[0], '__EVENTVALIDATION' : EVENTVALIDATION[0], 'TextCustomerID' : "真實(shí)商戶號(hào)", 'TextAdminName' : '真實(shí)用戶名', 'TextPassword' : '真實(shí)密碼', 'btnLogin.x' : 40, 'btnLogin.y' : 10 }).encode('utf-8')
登錄參數(shù)的編碼很重要,如果沒(méi)有進(jìn)行utf-8編碼會(huì)報(bào)以下錯(cuò)誤:
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'
表單數(shù)據(jù)有了,接下來(lái)就是把請(qǐng)求頭也要獲取出來(lái):
header = { 'Host': 'www.test.com', 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', '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', 'Accept-Encoding': 'gzip, deflate', 'Content-Type': 'application/x-www-form-urlencoded', 'Origin': 'http://www.test.com', 'Connection': 'keep-alive', 'Referer': 'http://www.test.com/Login.aspx', 'Upgrade-Insecure-Requests': 1 }
模擬登陸并保存cookie:
#模擬登錄請(qǐng)求 login_request = urllib.request.Request(login_url, login_data, Headers) #創(chuàng)建cookie,利用cookie實(shí)現(xiàn)持久化登錄 cj = http.cookiejar.CookieJar() opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj)) login_result = opener.open(login_request)
最后模擬登陸后,如果是要采集某頁(yè)面數(shù)據(jù)的話也可以通過(guò)urllib.request.urlopen訪問(wèn)頁(yè)面鏈接讀取頁(yè)面源碼進(jìn)行數(shù)據(jù)采集。
如果有批量數(shù)據(jù)需要進(jìn)行Post/Get處理,那么就可以把待處理的數(shù)據(jù)獲取好,然后遍歷發(fā)起Post或Get請(qǐng)求即可:
import time, random var datas = {.....} for data in datas: response = requests.get(url, headers = headers, data=json_data, cookies = cj) # 或 response = requests.post(url, headers = headers, data=json_data, cookies = cj) time.sleep(random.randint(3, 5))
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
pyenv虛擬環(huán)境管理python多版本和軟件庫(kù)的方法
這篇文章主要介紹了pyenv虛擬環(huán)境管理python多版本和軟件庫(kù),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12基于Python的Post請(qǐng)求數(shù)據(jù)爬取的方法詳解
這篇文章主要介紹了基于Python的Post請(qǐng)求數(shù)據(jù)爬取的方法,需要的朋友可以參考下2019-06-06python實(shí)現(xiàn)百度語(yǔ)音識(shí)別api
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)百度語(yǔ)音識(shí)別api,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-04-04JupyterLab遠(yuǎn)程密碼訪問(wèn)實(shí)現(xiàn)
本文主要介紹了JupyterLab遠(yuǎn)程密碼訪問(wèn)實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-02-02jupyter 實(shí)現(xiàn)notebook中顯示完整的行和列
這篇文章主要介紹了jupyter 實(shí)現(xiàn)notebook中顯示完整的行和列,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-04-04詳解JavaScript編程中的window與window.screen對(duì)象
這篇文章主要介紹了JavaScript編程中的window與window.screen對(duì)象,是JS在瀏覽器中視圖編程的基礎(chǔ),需要的朋友可以參考下2015-10-10詳解python string類型 bytes類型 bytearray類型
這篇文章主要介紹了python string類型 bytes類型 bytearray類型,需要的朋友可以參考下2017-12-12python爬蟲(chóng)實(shí)戰(zhàn)steam加密逆向RSA登錄解析
今天帶來(lái)爬蟲(chóng)實(shí)戰(zhàn)的文章。在挑選游戲的過(guò)程中感受學(xué)習(xí),讓你突飛猛進(jìn)。本文主要實(shí)現(xiàn)用Python逆向登錄世界上最大的游戲平臺(tái)源碼分享,了解steam加密手段有多高明2021-10-10python3獲取當(dāng)前文件的上一級(jí)目錄實(shí)例
下面小編就為大家分享一篇python3獲取當(dāng)前文件的上一級(jí)目錄實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-04-04Python中函數(shù)的創(chuàng)建及調(diào)用
這篇文章主要介紹了Python中函數(shù)的創(chuàng)建及調(diào)用,創(chuàng)建函數(shù)也稱為定義一個(gè)函數(shù),可以理解為創(chuàng)建一個(gè)具有某種用途的工具。調(diào)用函數(shù)也就是執(zhí)行函數(shù)。如果把創(chuàng)建的函數(shù)理解為創(chuàng)建一個(gè)具體有某種用途的工具,那么調(diào)用函數(shù)就相當(dāng)于使用該工具2022-06-06