HTTPX에서 프록시 사용 방법

인증되지 않은 프록시, 인증된 프록시, 회전 프록시, 대체 프록시 예제를 통해 HTTPX 프록시 설정을 학습하세요.
2 분 읽기
How To Use Proxies With HTTPX blog image

오늘은 HTTPX를 사용한 프록시 활용법을 배워보겠습니다. 프록시는 스크레이퍼와 스크레이핑 대상 사이트 사이에 위치합니다. 스크레이퍼가 대상 사이트에 대한 요청을 프록시 서버에 보내면, 프록시가 해당 사이트를 가져와 스크레이퍼에 반환합니다.

인증되지 않은 프록시 사용 방법

요약하자면, 모든 요청은 proxy_url로 전송됩니다. 아래는 인증되지 않은 프록시를 사용하는 예시입니다. 즉, 사용자 이름이나 비밀번호를 사용하지 않습니다. 이 예시는 해당 문서에서 영감을 받았습니다.

import httpx

proxy_url = "http://localhost:8030"


with httpx.Client(proxy=proxy_url) as client:
    ip_info = client.get("https://geo.brdtest.com/mygeo.json")
    print(ip_info.text)

인증된 프록시 사용 방법

사용자 이름과 비밀번호가 필요한 프록시는 “인증된” 프록시라고 합니다. 이러한 자격 증명은 계정 인증을 수행하고 프록시 연결을 제공하는 데 사용됩니다.

인증이 필요한 경우 proxy_url은 다음과 같은 형식이 됩니다: http://<사용자명>:<비밀번호>@<프록시_URL>:<포트_번호>. 아래 예시에서는 인증 문자열의 사용자 부분 생성에 존과 사용자명을 모두 사용합니다.

기본 연결에는 데이터센터 프록시를 사용합니다.

import httpx

username = "your-username"
zone = "your-zone-name"
password = "your-password"

proxy_url = f"http://brd-customer-{username}-zone-{zone}:{password}@brd.superproxy.io:33335"

ip_info = httpx.get("https://geo.brdtest.com/mygeo.json", proxy=proxy_url)

print(ip_info.text)

위의 코드는 매우 간단합니다. 이는 설정하려는 모든 종류의 프록시의 기본이 됩니다.

  • 먼저, 사용자명(username), 영역(zone ), 비밀번호(password)라는 구성 변수를 생성합니다.
  • 이 변수들을 사용하여 proxy_url을 생성합니다: f"http://brd-customer-{username}-zone-{zone}:{password}@brd.superproxy.io:33335".
  • API에 요청을 보내 프록시 연결에 대한 일반 정보를 가져옵니다.

응답은 다음과 유사하게 표시됩니다.

{"country":"US","asn":{"asnum":20473,"org_name":"AS-VULTR"},"geo":{"city":"","region":"","region_name":"","postal_code":"","latitude":37.751,"longitude":-97.822,"tz":"America/Chicago"}}

회전 프록시 사용 방법

회전 프록시를 사용할 때는 프록시 목록을 생성하고 그중에서 무작위로 선택합니다. 아래 코드에서는 국가 목록을 생성합니다. 요청을 할 때 random.choice()를 사용하여 목록에서 무작위로 국가를 선택합니다. proxy_url은 선택된 국가에 맞게 형식이 지정됩니다.

아래 예시는 소규모 회전프록시 목록을 생성합니다.

import httpx
import asyncio
import random


countries = ["us", "gb", "au", "ca"]
username = "your-username"
proxy_url = "brd.superproxy.io:33335"

datacenter_zone = "your-zone"
datacenter_pass = "your-password"


for random_proxy in countries:
    print("----------connection info-------------")
    datacenter_proxy = f"http://brd-customer-{username}-zone-{datacenter_zone}-country-{random.choice(countries)}:{datacenter_pass}@{proxy_url}"

    ip_info = httpx.get("https://geo.brdtest.com/mygeo.json", proxy=datacenter_proxy)

    print(ip_info.text)

이 예제는 첫 번째 예제와 크게 다르지 않습니다. 주요 차이점은 다음과 같습니다.

  • 국가 배열을 생성합니다: ["us", "gb", "au", "ca"].
  • 단일 요청 대신 여러 요청을 수행합니다. 각 요청 생성 시 random.choice(countries)를 사용하여 proxy_url을 생성할 때마다 무작위 국가를 선택합니다.

대체 프록시 연결 생성 방법

위 예제에서는 데이터센터 프록시와 무료 프록시만 사용했습니다. 무료 프록시는 신뢰성이 낮습니다. 데이터센터 프록시는 접근이 어려운 사이트에서 차단되기 쉽습니다.

이 예제에서는 safe_get()이라는 함수를 생성합니다. 이 함수를 호출하면 먼저 데이터센터 연결을 사용하여 URL을 가져오려 시도합니다. 실패할 경우 주거용 연결로 대체합니다.

import httpx
from bs4 import BeautifulSoup
import asyncio


country = "us"
username = "your-username"
proxy_url = "brd.superproxy.io:33335"

datacenter_zone = "datacenter_proxy1"
datacenter_pass = "datacenter-password"

residential_zone = "residential_proxy1"
residential_pass = "residential-password"

cert_path = "/home/path/to/brightdata_proxy_ca/New SSL certifcate - MUST BE USED WITH PORT 33335/BrightData SSL certificate (port 33335).crt"


datacenter_proxy = f"http://brd-customer-{username}-zone-{datacenter_zone}-country-{country}:{datacenter_pass}@{proxy_url}"

residential_proxy = f"http://brd-customer-{username}-zone-{residential_zone}-country-{country}:{residential_pass}@{proxy_url}"

async def safe_get(url: str):
    async with httpx.AsyncClient(proxy=datacenter_proxy) as client:
        print("데이터센터로 시도 중")
        response = await client.get(url)
        if response.status_code == 200:
            soup = BeautifulSoup(response.text, "html.parser")
            if not soup.select_one("form[action='/errors/validateCaptcha']"):
                print("응답 성공")
                return response
    print("응답 실패")
    async with httpx.AsyncClient(proxy=residential_proxy, verify=cert_path) as client:
        print("주거용 프록시로 시도 중")
        response = await client.get(url)
        print("응답 성공")
        return response

async def main():
    url = "https://www.amazon.com"
    response = await safe_get(url)
    with open("out.html", "w") as file:
        file.write(response.text)

asyncio.run(main())

이 예제는 본 문서에서 다룬 다른 예제들보다 조금 더 복잡합니다.

  • 이제 데이터센터 연결용과 가정용 연결용, 두 세트의 구성 변수가 있습니다.
  • 이번에는 AsyncClient() 세션을 사용하여 HTTPX의 고급 기능 일부를 도입합니다.
  • 먼저 datacenter_proxy로 요청을 시도합니다.
  • 적절한 응답을 얻지 못하면 residential_proxy를 사용하여 요청을 재시도합니다. 코드의 verify 플래그도 주목하세요. 주거용 프록시를 사용할 때는 SSL 인증서를 다운로드하여 사용해야 합니다.
  • 확실한 응답을 받으면 해당 페이지를 HTML 파일로 작성합니다. 이 파일을 브라우저에서 열어 프록시가 실제로 접근하고 반환한 내용을 확인할 수 있습니다.

위 코드를 실행하면 출력 결과와 생성된 HTML 파일이 다음과 유사하게 표시됩니다.

데이터센터로 시도 중
응답 실패
주거용으로 시도 중
응답 성공
Screenshot of the Amazon homepage

Bright Data 제품의 도움

이 글에서 확인하셨듯이, 당사 데이터센터 프록시는 매우 저렴하며 주거용 프록시는 데이터센터 프록시가 작동하지 않을 때 탁월한 대체 수단을 제공합니다. 또한 데이터 수집 요구를 지원하기 위한 다양한 도구를 제공합니다.

  • 웹 언락커: 가장 까다로운 안티봇도 우회합니다. 웹 언락커는 페이지상의 모든 CAPTCHA를 자동으로 인식하고 해결합니다. 안티봇을 통과하면 해당 웹 페이지를 다시 전송해 줍니다.
  • 스크래핑 브라우저: 이 제품은 더 많은 기능을 제공합니다. 스크래핑 브라우저는 프록시 통합자동 CAPTCHA 해결 기능을 통해 원격 브라우저를 제어할 수 있게 합니다.
  • 웹 스크레이퍼 API: 이 API를 사용하면 스크레이핑 작업을 대신 수행해 드립니다. API를 호출하고 응답으로 받은 JSON 데이터를 파싱하기만 하면 됩니다.
  • 데이터셋: 수백 개의 사전 수집된 데이터셋을 찾아보거나 맞춤형 데이터셋을 요청/구축할 수 있는 데이터셋 마켓플레이스를 탐색하세요. 갱신 주기를 선택하고 필요한 데이터 포인트만 필터링할 수 있습니다.

결론

HTTPX와 당사 프록시를 결합하면 프라이빗하고 효율적이며 안정적인 웹 스크래핑 방식을 구현할 수 있습니다. 프록시 로테이션을 원한다면 Python 내장 random 라이브러리 사용만큼 간단합니다. 데이터센터 프록시와 주거용 프록시를 조합하면 대부분의 차단 시스템을 우회하는 중복 연결을 구축할 수 있습니다.

지금까지 살펴본 바와 같이, Bright Data는 웹 스크래핑 프로젝트를 위한 완벽한 솔루션을 제공합니다. Bright Data 프록시의 무료 체험을 지금 시작하세요!