Python3 크롤러에서는 프록시 사용이 IP 차단을 방지하거나 크롤링 속도를 높이는 일반적인 방법이며, 주로 여러 IP 주소로 접근하는 상황을 시뮬레이션하는 데 사용됩니다. 프록시는 무료 프록시와 유료 프록시로 나눌 수 있는데, 무료 프록시는 불안정하고 유료 프록시는 상대적으로 더 안정적이고 신뢰할 수 있습니다.

다음은 Python3 크롤러 프록시의 사용 시나리오와 활용 예시입니다:

IP 차단 방지: 일부 웹사이트는 IP 접근 빈도 제한을 두고 있으며, 방문 횟수가 제한을 넘으면 해당 IP의 웹사이트 접근을 금지합니다. 프록시를 사용하면 이러한 상황을 피할 수 있습니다.

크롤링 속도 향상: 프록시를 사용하면 동시에 여러 연결을 만들 수 있어 목표 데이터를 빠르게 수집할 수 있습니다.

지역 제한 우회: 일부 웹사이트는 지역에 따라 제공하는 서비스가 다릅니다. 특정 지역에만 공개된 웹사이트에 접근해야 한다면 프록시를 사용해 이러한 제한을 우회하고 필요한 데이터를 얻을 수 있습니다.

요약하면, 프록시 IP는 Python3 크롤러에서 매우 중요한 역할을 합니다. 다만 프록시 사용은 일부 보안 문제를 동반할 수 있으므로, 사용할 때는 적절한 프록시 서비스 제공업체를 선택하고 네트워크 보안 규정을 엄격히 준수해야 합니다.

준비 작업

먼저 사용 가능한 프록시를 하나 확보해야 합니다. 프록시는 IP 주소와 포트의 조합으로, 즉 ip:포트 형식입니다. 프록시에 인증이 필요하다면 사용자 이름과 비밀번호 정보 두 가지를 추가로 입력해야 합니다.

여기서는 제 로컬 컴퓨터에 프록시 소프트웨어가 설치되어 있으며, 이 소프트웨어는 로컬 7890 포트에 HTTP 프록시 서비스, 즉 127.0.0.1:7890 프록시를 생성합니다. 또한 이 소프트웨어는 7891 포트에 SOCKS 프록시 서비스, 즉 127.0.0.1:7891 프록시도 생성합니다. 따라서 이 프록시를 설정하기만 하면 로컬 IP를 프록시 소프트웨어가 연결한 서버의 IP로 성공적으로 전환할 수 있습니다.

이 장의 아래 예제에서는 위에서 언급한 프록시를 사용해 설정 방법을 시연하겠습니다. 물론 자신의 사용 가능한 프록시로 바꿔서 사용해도 됩니다.

프록시를 설정한 뒤 테스트할 URL은 http://httpbin.org/get 입니다. 이 링크에 접속하면 요청 관련 정보를 확인할 수 있으며, 반환 결과의 origin 필드가 바로 클라이언트의 IP입니다. 이를 기준으로 프록시가 성공적으로 설정되었는지, 즉 IP가 제대로 위장되었는지 판단할 수 있습니다.

좋습니다. 이제 각 요청 라이브러리의 프록시 설정 방법을 살펴보겠습니다.

Python3 크롤러 프록시 구하기

일부 웹사이트는 자사 데이터에 대한 빈번한 접근을 감지하고 이를 차단하는 조치를 취합니다. 프록시 서버를 사용하면 접속 출처를 분산시켜 탐지 가능성을 줄이고, 그에 따라 크롤링 성공률을 높일 수 있습니다.

최고의 미국 정적 프록시 IP

IPRoyal은 중국 지역에 매우 친화적인 프록시 서비스 제공업체이며, 그 주거용 프록시 솔루션은 매우 매력적입니다.

IPRoyal 보기
가장 저렴한 고정 프록시

Proxy-seller는 많은 소규모 인터넷 마케터들에게 인기가 있는 데이터센터 프록시 제공업체입니다.

Proxy-seller 보기
가장 가성비 좋은 고정 프록시

Shifter.io는 사용자에게 개인정보 보호와 더 나은 인터넷 경험을 제공하는 것을 목표로 하는 잘 알려진 프록시 서비스 제공업체입니다.

Shifter.io 보기

2. urllib

먼저 가장 기본적인 urllib를 예로 들어 프록시 설정 방법을 살펴보겠습니다. 코드는 다음과 같습니다:

 from urllib.error import URLError
 from urllib.request import ProxyHandler, build_opener

 proxy = '127.0.0.1:7890'
 proxy_handler = ProxyHandler({
    'http': 'http://' + proxy,
    'https': 'http://' + proxy
 })
 opener = build_opener(proxy_handler)
 try:
    response = opener.open('https://httpbin.org/get')
    print(response.read().decode('utf-8'))
 except URLError as e:
    print(e.reason)
 

실행 결과는 다음과 같습니다:

 {
  "args": {},
  "headers": {
    "Accept-Encoding": "identity",
    "Host": "httpbin.org",
    "User-Agent": "Python-urllib/3.7",
    "X-Amzn-Trace-Id": "Root=1-60e9a1b6-0a20b8a678844a0b2ab4e889"
  },
  "origin": "210.173.1.204",
  "url": "https://httpbin.org/get"
 }
 

여기서는 ProxyHandler를 사용해 프록시를 설정해야 하며, 파라미터는 딕셔너리 타입입니다. 키 이름은 프로토콜 종류이고 값은 프록시입니다. 주의할 점은 프록시 앞에 프로토콜을 붙여야 한다는 것으로, 즉 http:// 또는 https://입니다. 요청한 링크가 HTTP 프로토콜일 때는 http 키에 해당하는 프록시를 사용하고, 요청한 링크가 HTTPS 프로토콜일 때는 https 키에 해당하는 프록시를 사용합니다. 하지만 여기서는 프록시 자체를 HTTP 프로토콜로 설정했으므로 접두사는 모두 http://입니다. 따라서 HTTP든 HTTPS든 어떤 링크에 접근하더라도 우리가 구성한 HTTP 프로토콜 프록시를 사용해 요청하게 됩니다.

ProxyHandler 객체를 만든 뒤에는 build_opener 메서드에 해당 객체를 전달해 Opener를 생성해야 합니다. 이렇게 하면 해당 Opener에 이미 프록시가 설정된 셈입니다. 이어서 Opener 객체의 open 메서드를 직접 호출하면 원하는 링크에 접근할 수 있습니다.

실행 결과는 JSON이며 origin 필드가 클라이언트의 IP를 보여줍니다. 확인해 보면 여기의 IP는 실제 IP가 아니라 프록시의 IP입니다. 이렇게 해서 프록시 설정이 완료되었고 실제 IP도 숨길 수 있습니다.

인증이 필요한 프록시를 만나면 다음과 같은 방법으로 설정할 수 있습니다:

 from urllib.error import URLError
 from urllib.request import ProxyHandler, build_opener

 proxy = 'username:password@127.0.0.1:7890'
 proxy_handler = ProxyHandler({
    'http': 'http://' + proxy,
    'https': 'http://' + proxy
 })
 opener = build_opener(proxy_handler)
 try:
    response = opener.open('https://httpbin.org/get')
    print(response.read().decode('utf-8'))
 except URLError as e:
    print(e.reason)
 

여기서 바뀌는 것은 proxy 변수뿐이며, 프록시 앞에 인증용 사용자 이름과 비밀번호를 추가하면 됩니다. 여기서 username은 사용자 이름, password는 비밀번호입니다. 예를 들어 사용자 이름이 foo이고 비밀번호가 bar라면 프록시는 다음과 같습니다: foo:bar@127.0.0.1:7890

프록시가 SOCKS5 유형이라면 다음과 같이 프록시를 설정할 수 있습니다:

 import socks
 import socket
 from urllib import request
 from urllib.error import URLError

 socks.set_default_proxy(socks.SOCKS5, '127.0.0.1', 7891)
 socket.socket = socks.socksocket
 try:
    response = request.urlopen('https://httpbin.org/get')
    print(response.read().decode('utf-8'))
 except URLError as e:
    print(e.reason)
 

여기에는 socks 모듈이 필요하며, 다음 명령으로 설치할 수 있습니다:

 pip3 install PySocks