利用Python多線程實(shí)現(xiàn)圖片下載器
導(dǎo)語
之前有很多小伙伴說想學(xué)習(xí)一下多線程圖片下載器,雖然好像已經(jīng)過去很久了,不過還是上來安排一波吧。至于題目為什么說是構(gòu)建一個(gè)小型數(shù)據(jù)集,因?yàn)楣娞?hào)之后的文章應(yīng)該還會(huì)用到它來構(gòu)建一些簡單的圖像分類數(shù)據(jù)集,換句話說,后續(xù)一段時(shí)間,公眾號(hào)會(huì)主要寫一些深度學(xué)習(xí)機(jī)器學(xué)習(xí)相關(guān)的文章,下期文章揭曉具體內(nèi)容。
廢話不多說,讓我們愉快地開始近期最后一篇爬蟲文章~
開發(fā)工具
Python版本:3.7.8
相關(guān)模塊:
requests模塊;
alive-progress模塊;
pyfreeproxy模塊;
user_agent模塊;
beautifulsoup4模塊;
lxml模塊;
以及一些python自帶的模塊。
環(huán)境搭建
安裝Python并添加到環(huán)境變量,pip安裝需要的相關(guān)模塊即可。
原理簡介
我看了下,發(fā)現(xiàn)大家基本都是從百度,必應(yīng)和谷歌來根據(jù)給定的關(guān)鍵字下載相關(guān)的圖片數(shù)據(jù)的,所以我們也選用這三個(gè)數(shù)據(jù)源。具體而言,百度的圖片搜索接口如下:
'https://image.baidu.com/search/acjson?tn=resultjson_com&ipn=rj&ct=201326592&lm=7&fp=result&ie=utf-8&oe=utf-8&st=-1&word={}&queryWord={}&face=0&pn={}&rn={}'
為了可以多線程地進(jìn)行圖片搜索,我們先根據(jù)想要下載的圖片數(shù)量來構(gòu)造所有請求頁的鏈接如下:
search_urls, pagesize = [], 30 for pn in range(math.ceil(search_limits * 1.2 / pagesize)): search_url = base_url.format(quote(keyword), quote(keyword), pn * pagesize, pagesize) search_urls.append(search_url)
然后再多線程請求所有構(gòu)造好的搜索鏈接:
# 多線程請求獲取所有圖片鏈接 def searchapi(self, search_urls, image_urls, bar): while len(search_urls) > 0: search_url = search_urls.pop(0) response = self.get(search_url) if response is None: bar() continue response.encoding = 'utf-8' response_json = json.loads(response.text.replace(r"\'", ""), encoding='utf-8', strict=False) for item in response_json['data']: if 'objURL' in item.keys(): image_urls.add(self.parseurl(item['objURL'])) elif 'replaceUrl' in item.keys() and len(item['replaceUrl']) == 2: image_urls.add(item['replaceUrl'][1]['ObjURL']) bar() task_pool, image_urls = [], set() with alive_bar(min(len(search_urls), search_limits)) as bar: for idx in range(num_threadings): task = threading.Thread( target=searchapi, args=(self, search_urls, image_urls, bar) ) task_pool.append(task) task.start() for task in task_pool: task.join()
線程結(jié)束的條件為我們構(gòu)造的所有請求頁鏈接search_urls全部被用完。這里我們用的最基本的python的threading庫,感覺python應(yīng)該還有很多更加好用的多線程庫,感興趣的小伙伴可以自己查查資料,不必拘泥于我寫的內(nèi)容。threading庫的話調(diào)用方便,只需要target指定目標(biāo)函數(shù),args指定目標(biāo)函數(shù)輸入的參數(shù),然后start一下就行,所以我圖省事就直接用它了。
類似地,我們也可以根據(jù)得到的image_urls寫個(gè)多線程的圖片下載器:
'''下載''' def download(self, keyword, search_limits=1000, num_threadings=5, savedir='outputs'): touchdir(savedir) # 獲得image_urls self.logging(f'Start to search images from {self.source_name}') image_urls = self.search(keyword, search_limits, num_threadings) # 多線程下載圖片 self.logging(f'Start to download images from {self.source_name}') def downloadapi(self, savepaths, image_urls, bar): assert len(savepaths) == len(image_urls) while len(image_urls) > 0: savepath, image_url = savepaths.pop(0), image_urls.pop(0) response = self.get(image_url) if response is None: bar() continue with open(savepath, 'wb') as fp: fp.write(response.content) filetype = imghdr.what(savepath) if filetype in ['jpg', 'jpeg', 'png', 'bmp', 'gif']: savepath_correct = f'{savepath}.{filetype}' shutil.move(savepath, savepath_correct) else: os.remove(savepath) bar() task_pool, savepaths = [], [] for idx in range(len(image_urls)): savename = f'image_{str(idx).zfill(8)}' savepaths.append(os.path.join(savedir, savename)) with alive_bar(len(image_urls)) as bar: for idx in range(num_threadings): task = threading.Thread( target=downloadapi, args=(self, savepaths, image_urls, bar) ) task_pool.append(task) task.start() for task in task_pool: task.join()
然后必應(yīng)的圖片搜索接口如下:
# 構(gòu)建所有urls base_url = 'https://cn.bing.com/images/async?q={}&first={}&count={}&cw=1536&ch=240&relp={}&tsc=ImageBasicHover&datsrc=I&layout=RowBased&mmasync=1&dgState=x*1063_y*768_h*186_c*5_i*71_r*10&IG=D6A4AD486F3A49F1BE164BC50750D641&SFX=3&iid=images.5555' search_urls, pagesize = [], 35 for pn in range(math.ceil(search_limits * 1.2 / pagesize)): search_url = base_url.format(quote(keyword), pn * pagesize, pagesize, pagesize) search_urls.append(search_url)
谷歌的圖片搜索接口如下:
# 構(gòu)建所有urls base_url = 'https://www.google.com/search?' search_urls, pagesize = [], 20 for pn in range(math.ceil(search_limits * 1.2 / pagesize)): params = { 'q': keyword, 'ijn': pn, 'start': pn * pagesize, 'tbs': '', 'tbm': 'isch', } search_urls.append(base_url + urlencode(params))
具體的多線程搜索和下載圖片的寫法和百度的類似,大功告成啦。
效果展示
你只需要pip安裝一下,就可以直接在終端運(yùn)行了。安裝命令如下:
pip install pyimagedl
使用方式如下:
Usage: imagedl [OPTIONS] Options: --version Show the version and exit. -k, --keyword TEXT 想要搜索下載的圖片關(guān)鍵字, 若不指定, 則進(jìn)入imagedl終端版 -s, --savedir TEXT 下載的圖片的保存路徑 -t, --target TEXT 指定圖片搜索下載的平臺(tái), 例如"baidu" -l, --limits INTEGER 下載的圖片數(shù)量 -n, --nthreadings INTEGER 使用的線程數(shù)量 --help Show this message and exit.
例如,在終端輸入:
imagedl -k 狗狗 -s dogs -t baidu -l 1000
到此這篇關(guān)于利用Python多線程實(shí)現(xiàn)圖片下載器的文章就介紹到這了,更多相關(guān)Python圖片下載內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python minidom模塊用法示例【DOM寫入和解析XML】
這篇文章主要介紹了Python minidom模塊用法,結(jié)合實(shí)例形式分析了Python DOM創(chuàng)建、寫入和解析XML文件相關(guān)操作技巧,需要的朋友可以參考下2019-03-03Python正則表達(dá)式高效處理文本數(shù)據(jù)的秘訣輕松掌握
當(dāng)談到文本處理和搜索時(shí),正則表達(dá)式是Python中一個(gè)強(qiáng)大且不可或缺的工具,正則表達(dá)式是一種用于搜索、匹配和處理文本的模式描述語言,可以在大量文本數(shù)據(jù)中快速而靈活地查找、識(shí)別和提取所需的信息,2023-11-11python中pandas.DataFrame的簡單操作方法(創(chuàng)建、索引、增添與刪除)
這篇文章主要介紹了python中pandas.DataFrame的簡單操作方法,其中包括創(chuàng)建、索引、增添與刪除等的相關(guān)資料,文中介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來一起看看吧。2017-03-03python實(shí)現(xiàn)通訊錄管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)通訊錄管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05Pycharm Terminal 與Project interpreter 安裝
本文主要介紹了Pycharm Terminal 與Project interpreter 安裝包不同步問題解決,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-02-02Selenium 安裝和簡單使用的實(shí)現(xiàn)
這篇文章主要介紹了Selenium 安裝和簡單使用的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12Python調(diào)用系統(tǒng)底層API播放wav文件的方法
這篇文章主要介紹了Python調(diào)用系統(tǒng)底層API播放wav文件的方法,涉及Python使用pywin32調(diào)用系統(tǒng)底層API讀取與播放wav文件的相關(guān)操作技巧,需要的朋友可以參考下2017-08-08Python3基礎(chǔ)之基本數(shù)據(jù)類型概述
這篇文章主要介紹了Python3的基本數(shù)據(jù)類型,需要的朋友可以參考下2014-08-08用實(shí)例解釋Python中的繼承和多態(tài)的概念
這篇文章主要介紹了用實(shí)例解釋Python中的繼承和多態(tài)的概念,繼承和多臺(tái)是學(xué)習(xí)每一門面對(duì)對(duì)象的編程語言時(shí)都必須掌握的重要知識(shí),需要的朋友可以參考下2015-04-04使用Python一鍵提取PDF中的表格到Excel的方法詳解
從PDF文件獲取表格中的數(shù)據(jù),也是日常辦公容易涉及到的一項(xiàng)工作,一個(gè)一個(gè)復(fù)制吧,效率確實(shí)太低了,用Python從PDF文檔中提取表格數(shù)據(jù),并寫入Excel文件,灰常灰常高效,本文就給大家介紹一下如何使用Python一鍵提取PDF中的表格到Excel,需要的朋友可以參考下2023-08-08