728x90
grequest 모듈을 이용하여 비동기 HTTP 요청을 처리하는 방법입니다.
grequests.get() 으로 요청 리스트를 생성하고, grequests.map()으로 실제 요청을 실해합니다.
import grequests
urls= ["http://abc.com/", "http://def.com/", ...,"http://zzz.com/",
req_tasks = [grequests.get(url, headers=headers) for url in urls]
res_list = grequests.map(req_tasks)
for res in res_list:
print(res.text)
grequest vs. request Code
# Import
import grequests
import requests
import time
# pip install grequests
## Target url
urls = [
"https://finviz.com/screener.ashx?v=152&ft=4"
, "https://finviz.com/screener.ashx?v=152&ft=4&r=21"
, "https://finviz.com/screener.ashx?v=152&ft=4&r=41"
, "https://finviz.com/screener.ashx?v=152&ft=4&r=61"
, "https://finviz.com/screener.ashx?v=152&ft=4&r=81"
, "https://finviz.com/screener.ashx?v=152&ft=4&r=101"
]
headers = {
'Referer': 'https://freemidi.org/download-20225',
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36"
}
## 동기(sync request) 함수
def req_normal(urls, headers):
res_list=[]
for url in urls:
res = requests.get(url=url, headers=headers)
res_list.append(res)
return res_list
def req_async_exception(e):
print(e)
## 비동기(async request) 함수
def req_async(urls, headers):
req_tasks = [grequests.get(url, headers=headers) for url in urls]
#print(len(req_tasks))
return grequests.map(req_tasks, exception_handler=req_async_exception, size=2, gtimeout=1)
# 파일 저장 함수
def response2file(tag, response_list):
page=0
for res in response_list:
page = page + 1
with open(f"./data/{tag}_{page}.html", "w", encoding='utf8') as f:
f.write(res.text)
728x90
동기 함수 실행 코드
s = time.time()
r = req_normal(urls, headers)
response2file(tag="req_normal_", response_list=r)
e = time.time()
print(f"req_normal() Durations : {round(e-s, 10)} s")
# Output
# req_normal() Durations : 1.9974486828 s
비동기 함수 실행 코드
s = time.time()
r = req_async(urls, headers)
response2file(tag="req_async_", response_list=r)
e = time.time()
print(f"req_async() Durations : {round(e-s, 10)} s")
# Output
# req_async() Durations : 0.9877688885 s
위 예제에서 비동기 방식이 약 2배 이상 빠른 것을 확인할 수 있습니다.
grequest 코루틴 기반의 gevent 로 작성된 비동기식 HTTP 요청 모듈입니다.
더보기
gevent 란?
gevent는 libev / libuv 이벤트 루프 위에 고수준 동기 API를 제공하기 위해 greenlet 을 사용하는 코루틴 기반 Python 네트워킹 라이브러리입니다 .
다음과 같은 특징이 있습니다
* libev 또는 libuv 기반의 빠른 이벤트 루프 .
* greenlet을 기반으로 하는 경량 실행 단위.
* Python 표준 라이브러리의 개념을 재사용하는 API(예: 이벤트 및 대기열 있음).
* SSL을 지원하는 협력 소켓
* 스레드 풀, dnspython 또는 c-ares를 통해 수행되는 협력 DNS 쿼리 .
* 타사 모듈이 협력하도록 하는 Monkey 패치 유틸리티
* TCP/UDP/HTTP 서버
* 하위 프로세스 지원( gevent.subprocess 통해 )
* 스레드 풀
Reference
* grequest : https://pypi.org/project/grequests/
* gevent : http://www.gevent.org/intro.html#example
728x90
'Data Science > Python' 카테고리의 다른 글
[python] Dask Parallel Computing Example (0) | 2023.01.28 |
---|---|
[python] About Dask (0) | 2023.01.28 |
[Python] 디렉토리 및 파일 변경 감시 모듈 : WatchDog (0) | 2022.09.29 |
[Python] Dataframe에서 Zip파일 읽기 (0) | 2022.09.27 |
[Python] pandas : Adding Multiple Columns from DatatFrame.apply() (0) | 2022.09.17 |
최근댓글