簡體   English   中英

無法使用請求從網頁中抓取名稱

[英]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標頭,就可以使用datafiles獲得有效的響應。

無需添加任何額外的標題。 使用Session對象時,默認情況下會存儲和提交cookie。 Content-Type標頭是自動創建的-使用data參數時使用“ application / x-www-form-urlencoded”,使用files “ multipart / form-data”。 不需要更改默認的用戶代理或添加引薦來源網址。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM