Skip to content

Webスクレイピング을 위한 최고의 Python HTTP 클라이언트. 기능, 성능 및 사용 사례를 비교하여 스크레イピング 요구에 적합한 올바른 도구를 찾으시기 바랍니다.

Notifications You must be signed in to change notification settings

bright-kr/best-python-http-clients

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 

Repository files navigation

Web스크레이핑을 위한 최고의 Python HTTP 클라이언트

Promo

다음은 2025년에 Web스크레이핑을 위해 사용할 수 있는 상위 Python HTTP 클라이언트, 해당 기능, 그리고 최적의 사용 사례에 대한 개요입니다:

Requests

Requests는 가장 널리 사용되는 Python HTTP 클라이언트로, 주당 3,000만 회라는 인상적인 다운로드 수를 자랑합니다.

다음은 다양한 HTTP 메서드를 테스트할 수 있도록 샘플 응답을 제공하는 httpbin.org를 사용하여, Requests로 HTTP 요청/응답를 처리하는 방법의 예시입니다:

import requests

print("Testing `requests` library...")
resp = requests.get('https://httpbin.org/get', params={"foo": "bar"})
if resp.status_code == 200:     # success
    print(f"Response Text: {resp.text} (HTTP-{resp.status_code})")
else:   # error
    print(f"Error: HTTP-{resp.status_code}")

requests.get(...) 메서드를 사용하면 쿼리 문자열을 수동으로 추가하지 않고도 params 인자를 통해 URL 파라미터를 손쉽게 전달할 수 있습니다.

Requests는 쿼리 문자열 인코딩, JSON 데이터 처리, HTTP 리다이렉트를 자동으로 처리합니다. 또한 내장 SSL 지원을 제공합니다. 내부적으로는 저수준 HTTP 작업을 위해 urllib3를 활용하면서도, 더 직관적인 인터페이스를 제공합니다.

세션 관리 또한 강력한 기능으로, 여러 리クエスト에 걸쳐 Cookie, 헤ッダー, 인증 정보를 유지할 수 있어 Web스크레이핑 중 보호된 콘텐츠에 접근하는 데 필수적입니다.

대용량 응답를 효율적으로 처리하기 위해 Requests는 스트리밍 기능을 제공합니다:

import requests

print("Testing `requests` library with streaming...")
resp = requests.get('https://httpbin.org/stream/10', stream=True)
for chunk in resp.iter_content(chunk_size=1024):
    print(chunk.decode('utf-8'))

Requests에는 몇 가지 제한 사항이 있습니다. 네이티브 비동기 기능과 HTTP/2 지원이 없으며, 이 논의에 따르면 후자(HTTP/2)를 추가할 계획도 없습니다. 내장 캐시 기능은 없지만 requests-cache 같은 확장 기능을 사용할 수 있습니다.

Note: HTTP/2는 멀티플렉싱과 같은 기능을 통해 HTTP/1.1을 개선하며, 단일 TCP 연결에서 여러 요청를 처리하여 페이지 로딩을 더 빠르게 합니다.

Requests는 간단한 문법, 자동 커넥션 풀링, JSON 처리, 그리고 포괄적인 문서 덕분에 여전히 인기가 높습니다.

urllib3

urllib3는 HTTP 요청를 위한 견고한 기반으로, 많은 다른 HTTP 클라이언트에 동력을 제공하면서 저수준 HTTP 기능에 대한 직접 접근을 제공합니다.

다음은 urllib3를 사용하는 기본 예시입니다:

import urllib3

print("Testing `urllib3` library...")
http = urllib3.PoolManager()    # PoolManager for connection pooling
resp = http.request('GET', 'https://httpbin.org/get', fields={"foo": "bar"})

if resp.status == 200:     # success
    print(f"Response: {resp.data.decode('utf-8')} (HTTP-{resp.status})")
else:    # error
    print(f"Error: HTTP-{resp.status}")

urllib3.PoolManager()는 재사용 가능한 커넥션 풀을 생성하여, 각 요청마다 새 연결을 설정하는 오버헤드를 제거함으로써 성능을 향상시킵니다.

urllib3는 스트리밍 응답 처리에 뛰어나며, 메모리 과부하 없이 대규모 데이터셋을 처리하는 데 이상적입니다. 또한 자동 리다이렉트와 SSL 연결을 지원합니다.

하지만 urllib3에는 내장 비동기 기능, 캐싱, 세션 관리, HTTP/2 지원이 없습니다.

urllib3의 커넥션 풀링 구현은 Requests보다 더 복잡하지만, 스크립팅 문법은 여전히 간단하며 잘 유지관리되는 문서를 제공합니다.

세션 관리 없이도 강력함이 필요한 기본적인 Web스크레이핑 작업에는 urllib3를 고려하시는 것이 좋습니다.

Uplink

Uplink는 클래스 기반 인터페이스를 통해 HTTP 요청에 접근하는 독특한 방식을 제공하며, 특히 API 중심 Web스크레이핑에 유용합니다.

다음은 Uplink로 API와 상호작용하는 방법입니다:

import uplink

@uplink.json
class JSONPlaceholderAPI(uplink.Consumer):
    @uplink.get("/posts/{post_id}")
    def get_post(self, post_id):
        pass


def demo_uplink():
    print("Testing `uplink` library...")
    api = JSONPlaceholderAPI(base_url="https://jsonplaceholder.typicode.com")
    resp = api.get_post(post_id=1)
    if resp.status_code == 200:     # success
        print(f"Response: {resp.json()} (HTTP-{resp.status_code})")
    else:   # error
        print(f"Error:HTTP-{resp.status_code}")

이 예시는 uplink.Consumer를 상속하는 JSONPlaceholderAPI 클래스를 정의합니다. @uplink.get 데코레이터는 엔드포인트 경로에 동적인 post_id 파라미터를 포함한 HTTP GET 요청를 생성합니다.

Uplink는 SSL 연결과 자동 리다이렉트를 처리합니다. 또한 고유한 Bring Your Own HTTP Library 기능을 지원합니다.

이 라이브러리는 스트리밍 응답, 비동기 요청, 캐싱(단, requests-cache 사용 가능), HTTP/2에 대한 내장 지원이 없습니다.

Uplink는 좋은 문서를 제공하지만, 활발히 유지관리되지는 않습니다(마지막 릴리스는 2022년 3월의 0.9.7). 클래스 기반 접근은 객체지향 개발자에게 매력적이지만, Python의 스크립팅 스타일을 선호하는 분들에게는 덜 직관적으로 느껴질 수 있습니다.

HTML 페이지보다 REST API 엔드포인트 중심으로 스크레이핑을 수행할 때 Uplink를 선택하시는 것이 좋습니다.

GRequests

GRequests는 인기 있는 Requests 라이브러리를 비동기 기능으로 확장하여, 여러 소스에서 동시에 데이터를 가져올 수 있게 합니다.

다음은 GRequests 동작 예시입니다:

import grequests

print("Testing `grequests` library...")
# Fetching data from multiple URLs
urls = [
    'https://www.python.org/',
    'http://httpbin.org/get',
    'http://httpbin.org/ip',
]

responses = grequests.map((grequests.get(url) for url in urls))
for resp in responses:
    print(f"Response for: {resp.url} ==> HTTP-{resp.status_code}")

이 코드는 grequests.map(...)를 사용해 3개의 동시 GET 요청를 전송하고 응답를 수집합니다. GRequests는 복잡한 동시성 관리 없이 비동기 작업을 처리하기 위해 gevent를 활용합니다.

GRequests는 자동 리다이렉트, SSL 연결, 스트리밍 응답를 지원합니다. 내장 HTTP/2 지원은 없고, 캐싱도 내장되어 있지 않지만(requests-cache 사용 가능) 대체할 수 있습니다.

이 라이브러리는 Requests와 유사한 직관적인 API로 비동기 요청를 단순화하여, 복잡한 async/await 패턴이 필요하지 않습니다. 그러나 코드베이스가 작고(0.7.0 버전에서 213라인) 개발 활동이 제한적이어서 문서는 최소한으로 제공됩니다.

최소한의 복잡성으로 여러 소스에서 동시에 데이터를 수집해야 할 때 GRequests를 고려하시는 것이 좋습니다.

HTTPX

HTTPX는 Python HTTP 클라이언트의 현대적 진화로, 비동기 지원과 향상된 성능이 추가된 Requests 대체제로 설계되었습니다.

다음은 HTTPX의 비동기 기능 예시입니다:

import httpx
import asyncio

async def fetch_posts():
    async with httpx.AsyncClient() as client:
        response = await client.get('https://jsonplaceholder.typicode.com/posts')
        return response.json()

async def httpx_demo():
    print("Testing `httpx` library...")
    posts = await fetch_posts()
    for idx, post in enumerate(posts):
        print(f"Post #{idx+1}: {post['title']}")

# async entry point to execute the code
asyncio.run(httpx_demo())

이 코드는 httpx.AsyncClient()로 API에서 데이터를 가져오는 비동기 함수 fetch_posts()를 정의합니다. httpx_demo() 함수는 결과를 await로 받아 처리합니다.

HTTPX는 내장 HTTP/2 지원이 돋보이며, 단일 연결에서 여러 리소스를 더 빠르게 로드할 수 있게 하고 Web스크레이핑 중 브라우저 핑거프린트를 더 어렵게 만듭니다.

HTTPX에서 HTTP/2를 사용하려면 다음과 같이 합니다:

import httpx

client = httpx.Client(http2=True)
response = client.get("https://http2.github.io/")
print(response)

HTTP/2 지원에는 추가 설치가 필요합니다:

pip install httpx[http2]

HTTPX는 대용량 응답를 효율적으로 처리하기 위한 뛰어난 스트리밍 지원도 제공합니다:

with httpx.stream("GET", "https://httpbin.org/stream/10") as resp:
   for text in resp.iter_text():
       print(text)

HTTPX에는 내장 캐싱이 없지만 Hishel을 통합할 수 있습니다.

Requests와 달리 HTTPX는 기본적으로 리다이렉트를 따르지 않지만, 설정을 통해 활성화할 수 있습니다:

import httpx

# test http --> https redirect
response = httpx.get('http://github.com/', follow_redirects=True)

비동기 기능으로 인해 약간의 복잡성이 추가되기는 하지만, HTTPX는 동기/비동기 요청 모두에 대해 간단한 메서드를 제공합니다. 또한 포괄적인 문서와 활발한 커뮤니티에 힘입어 인기가 계속 증가하고 있습니다.

비동기 기능을 갖춘 기능 풍부한 HTTP 클라이언트가 필요한 프로젝트에 HTTPX가 이상적입니다.

aiohttp

aiohttp는 비동기 프로그래밍에만 집중하며, 동시적이고 논블로킹 리クエスト가 필요한 고성능 Web스크레이핑 시나리오에서 뛰어납니다.

다음은 aiohttp로 동시 스크레이핑을 수행하는 방법입니다:

import asyncio
import aiohttp

async def fetch_data(url):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            return await response.text()    

async def demo_aiohttp():
    print("Testing `aiohttp` library...")
    urls = [
        'https://www.python.org/',
        'http://httpbin.org/get',
        'http://httpbin.org/ip',
    ]
    tasks = [fetch_data(url) for url in urls]
    responses = await asyncio.gather(*tasks)
    for resp_text in responses:
        print(f"Response: {resp_text}")

# async entry point to execute the code      
asyncio.run(demo_aiohttp())

이 코드는 세션을 생성하고 GET 요청를 전송하는 비동기 함수 fetch_data()를 만듭니다. demo_aiohttp() 함수는 여러 URL에 대한 작업을 생성하고 asyncio.gather()로 동시 실행합니다.

aiohttp는 HTTP 리다이렉트를 자동으로 처리하며, 대용량 파일 처리 시 효율적인 메모리 관리를 위한 스트리밍 응답도 지원합니다. 또한 다양한 서드파티 미들웨어와 확장 기능을 제공합니다.

또한 aiohttp는 개발 서버로도 동작할 수 있지만, 이 글은 클라이언트 기능에 초점을 맞춥니다.

이 라이브러리는 HTTP/2 지원과 내장 캐싱이 없지만, aiohttp-client-cache 같은 라이브러리를 통해 캐싱을 추가할 수 있습니다.

aiohttp의 비동기 특성은 Requests 같은 더 단순한 클라이언트보다 복잡하여 비동기 프로그래밍에 대한 탄탄한 이해가 필요합니다. 그러나 GitHub 별 14.7K와 수많은 서드파티 확장으로 매우 인기가 많습니다. 또한 포괄적인 문서도 제공합니다.

주가 모니터링이나 라이브 이벤트 추적과 같은 실시간 데이터 스크레이핑 작업에는 aiohttp를 선택하시는 것이 좋습니다.

다음 표에서 상위 Python HTTP 클라이언트에 대한 빠른 개요를 확인해 보시기 바랍니다:

Requests urllib3 Uplink GRequests HTTPX aiohttp
Ease of Use 쉬움 쉬움-보통 보통 쉬움 보통 보통
Automatic Redirects 활성화 필요
SSL Support
Asynchronous Capability 아니요 아니요 아니요
Streaming Responses 아니요
HTTP/2 Support 아니요 아니요 아니요 아니요 아니요
Caching Support Via: requests-cache 아니요 Via:requests-cache Via:requests-cache Via: Hishel Via: aiohttp-client-cache

Conclusion

이 리뷰에서 다룬 각 HTTP 클라이언트는 고유한 장점을 제공합니다. Requests, Uplink, GRequests는 단순함을 제공하며, 그중에서도 Requests가 가장 높은 인기를 유지하고 있습니다. 한편 aiohttp와 HTTPX는 비동기 기능 덕분에 계속해서 주목을 받고 있습니다. 프로젝트에 가장 적합한 옵션은 사용자의 구체적인 요구 사항에 따라 달라집니다.

효과적인 Web스크레이핑은 HTTP 클라이언트를 선택하는 것만으로 끝나지 않습니다. 안티봇 조치를 우회하고 프록시를 관리하기 위한 전략이 필요합니다. Bright Data는 Web Scraper IDE와 같은 도구를 통해 Web스크레이핑을 단순화하며, 즉시 사용 가능한 JavaScript 함수와 템플릿을 제공하고, Web Unlocker를 통해 CAPTCHA 및 안티봇 조치를 우회할 수 있습니다.

지금 무료 체험을 시작하고 Bright Data가 제공하는 모든 것을 경험해 보시기 바랍니다.

About

Webスクレイピング을 위한 최고의 Python HTTP 클라이언트. 기능, 성능 및 사용 사례를 비교하여 스크레イピング 요구에 적합한 올바른 도구를 찾으시기 바랍니다.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published