python3-urllib_Handler_1
:Python 3.7
:http://httpbin.org
전술한
보통 링크 를 요청 하 는 python 코드 작성 방법 은:
import requests
url = "http://httpbin.org/get"
res = requests.get(url)
print(res.content)
실행 후 다음 과 같은 결 과 를 얻 을 수 있 습 니 다.
{
"args": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.22.0"
},
"origin": "x.x.x.x, x.x.x.x",
"url": "https://httpbin.org/get"
}
그러나 우 리 는 제3자 요청 라 이브 러 리
requests
을 사용 할 생각 이 없 기 때문에 urllib 라 이브 러 리 의 실현 버 전 은 다음 과 같 습 니 다. 얻 은 결 과 는 기본 적 인 User-Agent
필드 가 urllib
으로 바 뀌 었 습 니 다.import urllib.request as urlreq
url = "http://httpbin.org/get"
res = urlreq.urlopen(url)
print(res.read().decode('utf-8'))
현재 모든 OK. 만약 에 우리 가 대리 IP 를 사용 하여 요 구 를 하려 고 한다 면
urllib
의 기본 적 인 요구 방식 은 만족 할 수 없 기 때문에 opener
과 Handler
의 용법 을 도입 했다.import urllib.request as urlreq
url = "http://httpbin.org/get"
proxy = {'http':'112.87.68.202:9999'}# IP
proxyhandler = urlreq.ProxyHandler(proxies=proxy)
opener = urlreq.build_opener(proxyhandler)
res = opener.open(url)
print(res.read().decode('utf-8'))
orgin 필드 가 우리 가 사용 하 는 프 록 시 IP 의 주소 가 되 었 음 을 발견 할 수 있 습 니 다.
"origin": "112.87.68.202, 112.87.68.202",
urllib
라 이브 러 리 자체 가 Handler 를 실현 했다. 예 를 들 어 위 에서 사용 한 ProxyHandler
이다. 그러나 기능 적 인 수 요 는 사람 에 따라 다르다. 예 를 들 어 나 는 특정한 링크 를 요청 할 때 이 과정 에서 세 번 만 방향 을 바 꾸 고 이 세 번 의 방향 을 바 꾸 는 것 은 매번 user - agent 가 다르다.그러면 모듈 이 제공 한 handler 는 이러한 기능 을 만족 시 킬 수 없습니다. 사용자 정의 Handler 가 필요 합 니 다.본문
part-1
앞의 요청 예 에서 user - agent 필드 는 모듈 의 기본 필드 로 브 라 우 저 에 있 는 user - agent 처럼 보이 지 않 습 니 다. 간단 한 python 코드 는:
import requests
url = '...'
headers = {"User-Agent":"......"}
res = requests.get(url,headers=headers)
혹은
import urllib.request as urlreq
url = '...'
headers = {"User-Agent":'.....'}
req = urlreq.Request(url,headers=headers)
res = urlreq.urlopen(req)
사용자 정의 Handler 버 전이 라면:
from fake_useragent import UserAgent
import urllib.request as request
ua = UserAgent()
url = 'http://httpbin.org/get'
class HeaderHandler(request.BaseHandler):
def __init__(self,headers=None):
if headers is None:
headers = ua.random
self.headers = headers
def http_request(self,req):
req.headers['User-Agent'] = self.headers
return req
https_request = http_request
# handler *****************
proxyhandler = request.ProxyHandler(proxies={'http':'163.204.242.73:9999'})
headerhandler = HeaderHandler()
handlers = [proxyhandler,headerhandler]
opener = request.build_opener(*handlers)
req_2 = request.Request(url)
res_2 = opener.open(req_2)
print(res_2.read().decode('utf-8'))
이 예 는 분명히 앞의 두 가지 실현 방식 보다 복잡 하고 큰 인재 가 적 게 사용 되 지만 더욱 복잡 한 기능 수요 라면 그의 맞 춤 형 화 는 그 강 함 을 보 여 준다.
fake_useragent
을 도 입 했 는데 이 모듈 은 주로 user-agent
필드 를 제공 하 는 데 사용 되 고 독 자 는 user-agent
필드 를 직접 복사 할 수 있다. proxyhandler
과 headerhandler
을 중첩 하여 사용 하 였 으 며, 하 나 는 IP 프 록 시 기능 을 완성 하 였 으 며, 하 나 는 요청 헤드 필드 의 수정 을 완성 하 였 다. HTTPRedirectHandler
) 를 바탕 으로 이 루어 지 려 면 BaseHandler
BaseHandler 가 제공 하 는 몇 가지 함수 의 기능 은 Scrapy 파충류 프레임 의 중간 부품 이 이 를 바탕 으로 이 루어 졌 는 지 를 연상 할 수 밖 에 없다.하위 클래스 화 를 고려 하기 전에 Opener, 즉 Opener Director 대상 이 url 또는 Request 대상 을 처리 할 때 겪 는 세 가지 시 기 를 알 아야 합 니 다.
에 두 개 있 습 니 다) 에 따라 그들의 protocol 을 순서대로 호출 합 니 다.request () 방법, 여기 protocol 은 http 또는 https 를 말 합 니 다. 예 를 들 어 재 작성 함 수 는 http 입 니 다.request()。이 방법 은 Request 대상 을 받 아들 이 고 Request 대상 을 되 돌려 줍 니 다. 이 대상 은 다음 Handler 의 protocol 에 게 계속 전 달 됩 니 다.request 방법 가공 또는 기타 조작.다음 코드 예 는 리 셋 횟수 를 제한 하 는 기능 을 실 현 했 고 테스트 사 이 트 는 requests 라 이브 러 리 작성 자의 또 다른 오픈 소스 항목 을 사용 합 니 다.http://httpbin.org사이트 에서 테스트 방향 을 바 꾸 는 기능 을 제공 합 니 다. 여기 서 의 용법 은?
http://httpbin.org/absolute-redirect/{n}
n, , 3 ,
http://httpbin.org/absolute-redirect/3
여기 서 저 는 첫 번 째 예 처럼 기본 클래스 인 BaseHandler 를 계승 하지 않 고 하위 클래스 인 HTTP Redirect Handler 를 계승 하여 그 중의 소스 코드 를 직접 복사 하여 수정 합 니 다.그럼 왜 이렇게 고 쳐 야 되 는 지 알 았 죠?
import urllib.request as urlreq
from urllib.error import HTTPError
from urllib.parse import urlencode
class RedirectTimesOutError(Exception):
def __init__(self,expression,message):
self.expression = expression
self.message = message
class RedirectError(Exception):
def __init__(self,expression,message):
self.expression = expression
self.message = message
class MyHTTPRedirectHandler(urlreq.HTTPRedirectHandler):
def __init__(self,timeslimit=3):
self.limit = timeslimit
self.flag = 1
def redirect_request(self,req,fp,code,msg,headers,newurl):
m = req.get_method()
if (code != 302) and (m != 'GET'):
raise RedirectError('','Must 302 redirect from GET Method')
# raise HTTPError(req.full_url,code,msg,headers,fp)
print('newurl:',newurl)
print('-'*8)
newurl = newurl.replace(' ','%20')
CONTENT_HEADERS = ("content-length","content-type")
newheaders = {k:v for k,v in req.headers.items()
if k.lower() not in CONTENT_HEADERS}
if self.flag > self.limit:
self.flag = 1
raise RedirectTimesOutError(expression='32',message='Redirect times out!')
else:
self.flag +=1
return urlreq.Request(newurl,
headers=newheaders,
origin_req_host=req.origin_req_host,
unverifiable=True)
# def http_error_302(self,req,fp,code,msg,hdrs):
# print('call here')
# pass
url = 'http://httpbin.org/absolute-redirect/4' #GET
data = None
myhandler = MyHTTPRedirectHandler(4)
opener = urlreq.build_opener(myhandler)
try:
res_2 = opener.open(url,data=data)
except RedirectTimesOutError as e:
print(e.message)
else:
print(res_2.getcode())
# print(res_2.read().decode('utf-8'))
코드 는 원본 url lib 모듈 의 request. py 파일 의 HTTP Redirect Handler 류 의 redirect 를 복사 합 니 다.request 함수, 그리고 부분 수정:
self.limit
값 을 설정 함으로써 한 링크 의 방문 중간 에 몇 번 의 리 셋 이 허용 되 는 지 제한 하고 self.flag
기록 을 이용 하여 몇 번 째 리 셋 을 처리 하 며 마지막 으로 이상 을 던 지기 전에 self.flag
값 을 리 셋 해 야 한다. 그렇지 않 으 면 이 Handler 가 새로운 요청 의 리 셋 을 계속 처리 할 때 이전 요청 에 방 해 를 받는다.공식 API 에서 이 Handler 에 대한 설명 이 있 습 니 다.
HTTPRedirectHandler.redirect_request(req, fp, code, msg, hdrs, newurl)
Return a Request or None in response to a redirect.
This is called by the default implementations of the http_error_30*() methods when a redirection is received from the server.
If a redirection should take place, return a new Request to allow http_error_30*() to perform the redirect to newurl. Otherwise, raise HTTPError if no other handler should try to handle this URL, or return None if you can’t but another handler might. 이 말 에는 주로 이런 두 가지 정보 가 있다.
redirect_request
함 수 는 재 설정 을 처리 하 는 데 사 용 됩 니 다. 이 Handler 가 이 재 설정 을 처리 할 수 있다 면 Request 대상 으로 돌아 갑 니 다.만약 이 Handler 가 할 수 없다 면, None 로 돌아 가 처리 권 을 다음 Handler 로 넘 깁 니 다. http_error_30*
함 수 를 먼저 촉발 합 니 다. 이 함 수 는 redirect_request
함 수 를 촉발 하여 처리 합 니 다. http_error_30*
을 실 현 했 기 때문에 우리 위의 예 는 이 방법 을 실현 하지 못 했 지만 왜 촉발 되 었 고 시스템 의 기본 처리 방안 보다 우선 시 되 었 습 니까?http_error_30*
을 달성 했다 면 집행 순 서 는 어떻게 될 까?이 문제 들 은 다음 Handler 의 주제 에서 해석 되 는데, 여기에 소스 코드 를 결합 하여 그 행 위 를 해석 해 야 한다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Python의 None과 NULL의 차이점 상세 정보그래서 대상 = 속성 + 방법 (사실 방법도 하나의 속성, 데이터 속성과 구별되는 호출 가능한 속성 같은 속성과 방법을 가진 대상을 클래스, 즉 Classl로 분류할 수 있다.클래스는 하나의 청사진과 같아서 하나의 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.