[英]Unable to scrape a name from a webpage using requests
我已經在python中創建了一個腳本來獲取一個名稱,該名稱在填寫網頁輸入時填充。 打開該網頁后,您將獲得該名稱->(在下面提供了網站鏈接),在CP Number
旁邊放置16803
,然后點擊搜索按鈕。
我知道如何使用selenium
來抓住它,但是我對走那條路線不感興趣。 我在這里嘗試使用requests
模塊收集名稱。 我試圖模仿腳本中有關如何將請求發送到該站點的步驟(在chrome開發工具中可以看到)。 我無法在payload
參數內自動提供的唯一東西是ScrollTop
。
這是我的嘗試:
import requests
from bs4 import BeautifulSoup
URL = "https://www.icsi.in/student/Members/MemberSearch.aspx"
with requests.Session() as s:
r = s.get(URL)
cookie_item = "; ".join([str(x)+"="+str(y) for x,y in r.cookies.items()])
soup = BeautifulSoup(r.text,"lxml")
payload = {
'StylesheetManager_TSSM':soup.select_one("#StylesheetManager_TSSM")['value'],
'ScriptManager_TSM':soup.select_one("#ScriptManager_TSM")['value'],
'__VIEWSTATE':soup.select_one("#__VIEWSTATE")['value'],
'__VIEWSTATEGENERATOR':soup.select_one("#__VIEWSTATEGENERATOR")['value'],
'__EVENTVALIDATION':soup.select_one("#__EVENTVALIDATION")['value'],
'dnn$ctlHeader$dnnSearch$Search':soup.select_one("#dnn_ctlHeader_dnnSearch_SiteRadioButton")['value'],
'dnn$ctr410$MemberSearch$ddlMemberType':0,
'dnn$ctr410$MemberSearch$txtCpNumber': 16803,
'ScrollTop': 474,
'__dnnVariable': soup.select_one("#__dnnVariable")['value'],
}
headers = {
'Content-Type':'multipart/form-data; boundary=----WebKitFormBoundaryBhsR9ScAvNQ1o5ks',
'Referer': 'https://www.icsi.in/student/Members/MemberSearch.aspx',
'Cookie':cookie_item,
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'
}
res = s.post(URL,data=payload,headers=headers)
soup_obj = BeautifulSoup(res.text,"lxml")
name = soup_obj.select_one(".name_head > span").text
print(name)
當我執行上述腳本時,出現以下錯誤:
AttributeError: 'NoneType' object has no attribute 'text'
使用請求填寫網頁中的輸入時,如何獲取填充的名稱?
您的代碼的主要問題是數據編碼。 我注意到您已將Content-Type標頭設置為“ multipart / form-data”,但這不足以創建多部分編碼的數據。 實際上,這是一個問題,因為由於您使用的是URL編碼POST數據的data
參數,所以實際的編碼是不同的。 為了創建多部分編碼的數據,應該使用files
參數。
您可以通過向files
傳遞一個額外的啞參數來實現,
res = s.post(URL, data=payload, files={'file':''})
(這將更改所有POST數據的編碼,而不僅僅是'file'
字段)
或者,您可以將payload
字典中的值轉換為元組,這是在發布帶有請求的文件時的預期結構。
payload = {k:(None, str(v)) for k,v in payload.items()}
第一個值是文件名; 在這種情況下不需要它,因此我將其設置為None
。
接下來,您的POST數據應包含__EVENTTARGET
值,該值是獲得有效響應所必需的。 (創建POST數據字典時,提交服務器期望的所有數據很重要。我們可以從瀏覽器中獲取這些數據:通過檢查HTML表單或通過檢查網絡流量。)完整的代碼,
import requests
from bs4 import BeautifulSoup
URL = "https://www.icsi.in/student/Members/MemberSearch.aspx"
with requests.Session() as s:
r = s.get(URL)
soup = BeautifulSoup(r.text,"lxml")
payload = {i['name']: i.get('value', '') for i in soup.select('input[name]')}
payload['dnn$ctr410$MemberSearch$txtCpNumber'] = 16803
payload["__EVENTTARGET"] = 'dnn$ctr410$MemberSearch$btnSearch'
payload = {k:(None, str(v)) for k,v in payload.items()}
r = s.post(URL, files=payload)
soup_obj = BeautifulSoup(r.text,"lxml")
name = soup_obj.select_one(".name_head > span").text
print(name)
經過更多測試后,我發現服務器還接受URL編碼的數據(可能是因為沒有發布文件)。 因此,只要不更改默認的Content-Type標頭,就可以使用data
或files
獲得有效的響應。
無需添加任何額外的標題。 使用Session
對象時,默認情況下會存儲和提交cookie。 Content-Type標頭是自動創建的-使用data
參數時使用“ application / x-www-form-urlencoded”,使用files
“ multipart / form-data”。 不需要更改默認的用戶代理或添加引薦來源網址。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.