>  기사  >  백엔드 개발  >  정말 유물이네요! 요청보다 사용하기 쉬운 효율적인 Python 크롤러 프레임워크!

정말 유물이네요! 요청보다 사용하기 쉬운 효율적인 Python 크롤러 프레임워크!

WBOY
WBOY앞으로
2023-04-13 14:25:031391검색

정말 유물이네요! 요청보다 사용하기 쉬운 효율적인 Python 크롤러 프레임워크!

최근 회사의 Python 백엔드 프로젝트가 재구성되었으며 전체 백엔드 로직이 기본적으로 "비동기" 코루틴을 사용하도록 변경되었습니다. 비동기 대기(Python의 코루틴 구현)로 장식된 코드로 가득 찬 화면을 보면서 나는 갑자기 혼란스럽고 당황스러웠습니다.

"코루틴"이 무엇인지는 이전에 배웠지만 깊이 있게 살펴보지는 않아서 이번 기회에 배워보았습니다.

가자

정말 유물이네요! 요청보다 사용하기 쉬운 효율적인 Python 크롤러 프레임워크!

코루틴이 무엇인가요?

간단히 말해서 코루틴은 스레드를 기반으로 하지만 스레드보다 가볍습니다. 시스템 커널의 경우 코루틴은 눈에 보이지 않는 특성을 가지므로 프로그램을 작성하는 프로그래머가 관리하는 이런 종류의 경량 스레드를 흔히 '사용자 공간 스레드'라고 합니다.

코루틴이 멀티스레딩보다 나은 점은 무엇인가요?

1. 스레드 제어는 운영 체제의 손에 있지만 코루틴의 제어는 전적으로 사용자의 손에 있습니다. 따라서 코루틴을 사용하면 프로그램 실행 중 컨텍스트 전환을 줄이고 프로그램 실행 효율성을 효과적으로 향상시킬 수 있습니다.

2. 스레드를 생성할 때 시스템이 스레드에 할당하는 기본 스택 크기는 1M인 반면, 코루틴은 1K에 가까워 더 가볍기 때문에 동일한 메모리에서 더 많은 코루틴을 열 수 있습니다.

3. 코루틴의 특성은 멀티 스레드가 아니라 단일 스레드이므로 멀티 스레드 잠금 메커니즘이 필요하지 않습니다. 스레드가 하나뿐이므로 동시에 변수를 작성해도 충돌이 발생하지 않습니다. 코루틴에서 공유 리소스를 제어하려면 잠금이 필요하지 않으며 상태만 확인하면 됩니다. 따라서 코루틴의 실행 효율성은 멀티 스레드보다 훨씬 높으며 멀티 스레드에서의 경쟁을 효과적으로 방지합니다.

코루틴의 적용 가능 및 적용 불가능 시나리오

적용 가능한 시나리오: 코루틴은 차단되고 많은 양의 동시성이 필요한 시나리오에 적합합니다.

적용할 수 없는 시나리오: 코루틴은 계산량이 많은 시나리오에는 적합하지 않습니다. (코루틴의 본질은 단일 스레드에서 앞뒤로 전환하는 것이기 때문입니다.) 이러한 상황이 발생하더라도 다른 방법을 사용하여 문제를 해결해야 합니다. .

비동기 http 프레임워크 httpx의 초기 탐색

이 시점에서 우리는 "코루틴"에 대한 일반적인 이해를 가져야 하지만 이야기의 이 시점에서 일부 친구들은 여전히 ​​질문으로 가득 차 있다고 생각합니다. "코루틴"이 어떻게 도움이 됩니까? 인터페이스 테스트? 걱정하지 마세요. 답은 아래에 있습니다.

Python을 인터페이스 테스트에 사용해 본 친구들은 요청 라이브러리에 익숙하다고 생각합니다. 요청에 구현된 http 요청은 동기 요청이지만 실제로는 http 요청의 IO 차단 특성을 기반으로 코루틴을 사용하여 "비동기" http 요청을 구현하여 테스트 효율성을 높이는 것이 매우 적합합니다.

누군가가 오래 전에 이 사실을 알아차렸다고 생각합니다. 예상대로 Github를 탐색한 후 마침내 http: httpx를 "비동기적으로" 호출하는 코루틴을 지원하는 오픈 소스 라이브러리를 발견했습니다.

httpx란 무엇입니까

httpx는 요청의 거의 모든 기능을 상속하고 "비동기" http 요청을 지원하는 오픈 소스 라이브러리입니다. 간단히 말해서 httpx는 요청의 향상된 버전으로 간주될 수 있습니다.

이제 나를 따라가면 httpx의 힘을 볼 수 있습니다.

Installation

httpx 설치는 매우 간단하며 Python 3.6 이상의 환경에서 실행 가능합니다.

pip install httpx

모범 사례

속담처럼 효율성이 성공 또는 실패를 결정합니다. 일괄 http 요청의 시간 소모를 비교하기 위해 httpx 비동기 방식과 동기 방식을 사용했습니다~

먼저 동기 http 요청의 시간 소모 성능을 살펴보겠습니다.

import asyncio
import httpx
import threading
import time
def sync_main(url, sign):
 response = httpx.get(url).status_code
 print(f'sync_main: {threading.current_thread()}: {sign}2 + 1{response}')
sync_start = time.time()
[sync_main(url='http://www.baidu.com', sign=i) for i in range(200)]
sync_end = time.time()
print(sync_end - sync_start)

코드는 다음과 같습니다. 비교적 간단하게, sync_main에서 Baidu에 대한 동기 http 액세스가 200번 구현되었음을 알 수 있습니다.

실행 후 출력은 다음과 같습니다(키 출력의 일부가 가로채기...):

sync_main: <_MainThread(MainThread, started 4471512512)>: 192: 200
sync_main: <_MainThread(MainThread, started 4471512512)>: 193: 200
sync_main: <_MainThread(MainThread, started 4471512512)>: 194: 200
sync_main: <_MainThread(MainThread, started 4471512512)>: 195: 200
sync_main: <_MainThread(MainThread, started 4471512512)>: 196: 200
sync_main: <_MainThread(MainThread, started 4471512512)>: 197: 200
sync_main: <_MainThread(MainThread, started 4471512512)>: 198: 200
sync_main: <_MainThread(MainThread, started 4471512512)>: 199: 200
16.56578803062439

위 출력에서 ​​메인 스레드가 전환되지 않은 것을 볼 수 있습니다(단일 스레드이기 때문입니다!). 요청은 순서대로 실행됩니다(동기 요청이기 때문).

프로그램 실행에는 총 16.6초가 걸렸습니다.

아래에서 "비동기" http 요청을 시도해 보겠습니다.

import asyncio
import httpx
import threading
import time
client = httpx.AsyncClient()
async def async_main(url, sign):
 response = await client.get(url)
 status_code = response.status_code
 print(f'async_main: {threading.current_thread()}: {sign}:{status_code}')
loop = asyncio.get_event_loop()
tasks = [async_main(url='http://www.baidu.com', sign=i) for i in range(200)]
async_start = time.time()
loop.run_until_complete(asyncio.wait(tasks))
async_end = time.time()
loop.close()
print(async_end - async_start)

위 코드는 async_main의 async wait 키워드를 사용하여 asyncio를 통해 "비동기" http를 구현합니다(비동기 io 라이브러리는 Baidu 홈페이지를 200번 요청하고 시간을 인쇄합니다) 소비) .

코드를 실행한 후 다음 출력을 볼 수 있습니다(키 출력의 일부가 차단되었습니다...).

async_main: <_MainThread(MainThread, started 4471512512)>: 56: 200
async_main: <_MainThread(MainThread, started 4471512512)>: 99: 200
async_main: <_MainThread(MainThread, started 4471512512)>: 67: 200
async_main: <_MainThread(MainThread, started 4471512512)>: 93: 200
async_main: <_MainThread(MainThread, started 4471512512)>: 125: 200
async_main: <_MainThread(MainThread, started 4471512512)>: 193: 200
async_main: <_MainThread(MainThread, started 4471512512)>: 100: 200
4.518340110778809

순서가 엉망이더라도(56, 99, 67...)(프로그램이 코루틴 간을 계속 전환하기 때문입니다) 메인 스레드는 전환되지 않는 것을 볼 수 있습니다(코루틴은 기본적으로 여전히 단일 스레드입니다) ).

이 과정은 총 4.5초가 소요됩니다.

동기 요청에 소요되는 16.6초와 비교하면 약 73% 단축됩니다!

한 걸음은 빠르고, 모든 걸음은 빠르다는 말처럼. 시간 소모 측면에서 "비동기" httpx는 실제로 동기 http보다 훨씬 빠릅니다. 물론 "코루틴"은 요청 효율성 측면에서 인터페이스 테스트를 가능하게 할 뿐만 아니라 "코루틴"을 마스터한 후에는 친구의 기술 수준도 더 높은 수준으로 향상되어 더 나은 테스트 프레임워크를 설계할 수 있다고 믿습니다.

자 오늘 공유한 내용은 여기까지입니다. 마음에 드셨다면 좋아요 부탁드려요~

위 내용은 정말 유물이네요! 요청보다 사용하기 쉬운 효율적인 Python 크롤러 프레임워크!의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 51cto.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제