웹 페이지에서 입력을 채울 때 채워지는 이름을 가져 오기 위해 파이썬으로 스크립트를 만들었습니다. 그 이름을 얻는 방법은 다음과 같습니다.-> 해당 웹 페이지를 연 후 (사이트 링크는 아래에 제공됨) 16803
바로 옆에 놓고 CP Number
검색 버튼을 누르십시오.
나는 그것을 사용하는 방법을 알고 selenium
있지만 그 길을 가고 싶지는 않습니다. requests
모듈을 사용하여 이름을 수집하려고 여기에 있습니다. 요청이 해당 사이트로 전송되는 방법에 대해 스크립트 내에서 단계 (크롬 개발 도구에서 볼 수있는 내용)를 모방하려고했습니다. 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"로 설정했지만 멀티 파트 인코딩 데이터를 만들기에는 충분하지 않습니다. 실제로 data
POST 데이터를 URL 인코딩하는 매개 변수를 사용하고 있기 때문에 실제 인코딩이 다르기 때문에 문제가 됩니다. 다중 부분으로 인코딩 된 데이터를 생성하려면 files
매개 변수를 사용해야합니다 .
추가 더미 매개 변수를에 전달하여 수행 할 수 있습니다 files
.
res = s.post(URL, data=payload, files={'file':''})
( 'file'
필드 뿐만 아니라 모든 POST 데이터의 인코딩을 변경합니다 )
또는 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 인코딩 데이터도 허용한다는 것을 발견했습니다 (아마도 게시 된 파일이 없기 때문일 수 있음). 당신과 하나 유효한 응답 얻을 수 있도록 data
나에 files
기본 컨텐츠 유형 헤더를 변경하지 않는 것이 제공을.
추가 헤더를 추가 할 필요는 없습니다. Session
객체를 사용할 때 쿠키는 기본적으로 저장 및 제출됩니다. Content-Type 헤더는 "application / x-www-form-urlencoded" data
매개 변수를 사용하는 경우 "multipart / form-data"를 사용하여 자동으로 생성됩니다 files
. 기본 User-Agent를 변경하거나 Referer를 추가 할 필요가 없습니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다