摘要:異步下載國旗圖片和國家名數據用來捕獲異常保存圖片文件負責下載的主函數,由傳遞國家名是數據。異步獲取圖片異步獲取國家名中的子句在沒有異常時會運行這里獲取循環是為了在保存圖片時不阻塞函數內部維護了一個對象注。
異步下載國旗圖片和國家名數據
import aiohttp import asyncio import os import time import sys POP20_CC = ("CN IN US ID BR PK NG BD RU JP MX PH VN ET EG DE IR CD FR").split() BASE_URL = "http://flupy.org/data/flags" DEST_DIR = "downloads/" class FetchError(Exception): #用來捕獲異常 def __init__(self, country_code): self.country_code = country_code def save_flag(img, filename): #保存圖片文件 path = os.path.join(DEST_DIR, filename) with open(path, "wb") as fp: fp.write(img) async def http_get(session, url): #負責下載的主函數,session由download_many傳遞 async with session.get(url) as resp: if resp.status == 200: ctype = resp.headers.get("Content-type", "").lower() if "json" in ctype or url.endswith(".json"): #國家名是json數據。如果內容類型是json data = await resp.json() #那么就用json()方法獲取內容 else: data = await resp.read() #否則直接獲取元數據 return data elif resp.status == 404: #捕獲異常 raise web.HTTPNotFound() else: raise aiohttp.errors.HttpProcessingError(code=res.sstatus, message=res.reason, headers=res.headers) async def get_flag(session, cc): #獲取圖片 url = "{}/{cc}/{cc}.gif".format(BASE_URL, cc=cc.lower()) image = await http_get(session, url) #這里是Io請求需要異步操作 return image async def get_country(session, cc): #獲取國家名 url = "{}/{cc}/metadata.json".format(BASE_URL, cc=cc.lower()) metadata = await http_get(session, url) #這里是Io請求需要異步操作 return metadata["country"] def show(text): print(text + "[OK] ", end="") sys.stdout.flush() #挨個輸出國家名,沒有這個刷新緩沖區方法就會最后一下子輸出所有國家名。 async def download_one(session, cc): try: image = await get_flag(session, cc) #異步獲取圖片 country = await get_country(session, cc) #異步獲取國家名 except web.HTTPNotFound: msg = "not found" except Exception as exc: raise FetchError(cc) from exc else: #try中的else子句在沒有except異常時會運行 country = country.replace(" ", "_") filename = "{}-{}.gif".format(cc, country) loop = asyncio.get_event_loop() #這里獲取循環是為了在保存圖片時不阻塞 loop.run_in_executor(None, save_flag, image, filename) #run_in_excutor函數內部維護了一個TheardPollExecutor對象[注1]。第一個參數默認為concurrent.futures.Executor實例。 show(cc) return cc async def download_many(cc_list): async with aiohttp.ClientSession() as session: #獲取ClientSession對象 res = await asyncio.gather(*[asyncio.ensure_future(download_one(session, cc)) for cc in sorted(cc_list)]) #gather函數如果參數為協程對象它會自動排定為一個task,這里我們直接用的ensure_future方法生成了task對象。然后并發的運行他們,返回一個結果聚合值列表。 return len(res) def main(): t0 = time.time() loop = asyncio.get_event_loop() count = loop.run_until_complete(download_many(POP20_CC)) loop.close() elapsed = time.time() - t0 msg = " {} flags download in {:.2f}s" print(msg.format(count, elapsed)) if __name__ == "__main__": main() #def a(*x): #print(x) #a([1,2]) --> ([1,2],) #a(*[1,2]) --> (1,2) #*號可以將列表或元組里的元素解包,每個元素作為多帶帶的參數傳入
其實,異步庫依賴于低層線程(直至內核級線程),但是這些庫的用戶無需創建線程,也無需知道用到了基礎設施中的低層線程。在應用中,我們只需確保沒有阻塞的代碼,事件循環會在背后處理并發。異步系統能避免用戶線程級的開銷,這是它能比多線程系統管理更多并發連接的原因。
【注1】The loop.run_in_executor() method can be used with a concurrent.futures.ThreadPoolExecutor to execute blocking code in a different OS thread without blocking the OS thread that the event loop runs in.
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/43818.html
摘要:介紹本篇博客將繼續上一篇博客爬蟲之使用的模塊爬取各國國旗的內容,將用來實現這個爬蟲,下載全世界國家的國旗圖片。 介紹 ??本篇博客將繼續上一篇博客:Python爬蟲之使用Fiddler+Postman+Python的requests模塊爬取各國國旗 的內容,將用Java來實現這個爬蟲,下載全世界國家的國旗圖片。項目不再過多介紹,具體可以參考上一篇博客。??我們將全世界國家的名稱放在一個...
摘要:流程作為上述過程的一個演示,我們使用的網址為頁面如下在表單中輸入德國,跳轉后的頁面如下我們可以發現,在搜索的結果中,會出現德國這個搜索結果。點擊該搜索結果,跳轉后的頁面如下在這個頁面中有我們需要的德國的國旗。 介紹 ??本篇博客將會介紹一個Python爬蟲,用來爬取各個國家的國旗,主要的目標是為了展示如何在Python的requests模塊中使用POST方法來爬取網頁內容。??為了知道...
摘要:標準庫中所有阻塞型函數都會釋放,允許其他線程運行。如果調用引發異常,那么當從迭代器檢索其值時,將引發異常??偨Y自版就支持線程了,只不過是使用線程的最新方式。類封裝了模塊的組件,使使用線程變得更加方便。下一篇筆記應該是使用處理并發。 作為Python程序員,平時很少使用并發編程,偶爾使用也只需要派生出一批獨立的線程,然后放到隊列中,批量執行。所以,不夸張的說,雖然我知道線程、進程、并行、...
摘要:是之后引入的標準庫的,這個包使用事件循環驅動的協程實現并發。沒有能從外部終止線程,因為線程隨時可能被中斷。上一篇并發使用處理并發我們介紹過的,在中,只是調度執行某物的結果。 asyncio asyncio 是Python3.4 之后引入的標準庫的,這個包使用事件循環驅動的協程實現并發。asyncio 包在引入標準庫之前代號 Tulip(郁金香),所以在網上搜索資料時,會經??吹竭@種花的...
摘要:本文重點掌握異步編程的相關概念了解期物的概念意義和使用方法了解中的阻塞型函數釋放的特點。一異步編程相關概念阻塞程序未得到所需計算資源時被掛起的狀態。 導語:本文章記錄了本人在學習Python基礎之控制流程篇的重點知識及個人心得,打算入門Python的朋友們可以來一起學習并交流。 本文重點: 1、掌握異步編程的相關概念;2、了解期物future的概念、意義和使用方法;3、了解Python...
閱讀 1820·2021-11-23 09:51
閱讀 927·2021-10-08 10:05
閱讀 3421·2021-09-26 09:55
閱讀 1030·2021-09-22 15:21
閱讀 1626·2021-09-09 09:33
閱讀 1236·2019-08-30 15:56
閱讀 1275·2019-08-30 15:55
閱讀 958·2019-08-30 13:19