目录
导语开发工具环境搭建原理简介效果展示导语
之前有很多小伙伴说想学习一下多线程图片下载器,虽然好像已经过去很久了,不过还是上来安排一波吧。至于题目为什么说是构建一个小型数据集,因为公众号之后的文章应该还会用到它来构建一些简单的图像分类数据集,换句话说,后续一段时间,公众号会主要写一些深度学习机器学习相关的文章,下期文章揭晓具体内容。
废话不多说,让我们愉快地开始近期最后一篇爬虫文章~
开发工具
Python版本:3.7.8
相关模块:
requests模块;
alive-progress模块;
pyfreeproxy模块;
user_agent模块;
beautifulsoup4模块;
lxml模块;
以及一些python自带的模块。
环境搭建
安装Python并添加到环境变量,pip安装需要的相关模块即可。
原理简介
我看了下,发现大家基本都是从百度,必应和谷歌来根据给定的关键字下载相关的图片数据的,所以我们也选用这三个数据源。具体而言,百度的图片搜索接口如下:
"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={}"
为了可以多线程地进行图片搜索,我们先根据想要下载的图片数量来构造所有请求页的链接如下:
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)
然后再多线程请求所有构造好的搜索链接:
# 多线程请求获取所有图片链接 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()
线程结束的条件为我们构造的所有请求页链接search_urls全部被用完。这里我们用的最基本的python的threading库,感觉python应该还有很多更加好用的多线程库,感兴趣的小伙伴可以自己查查资料,不必拘泥于我写的内容。threading库的话调用方便,只需要target指定目标函数,args指定目标函数输入的参数,然后start一下就行,所以我图省事就直接用它了。
类似地,我们也可以根据得到的image_urls写个多线程的图片下载器:
"""下载""" 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()
然后必应的图片搜索接口如下:
# 构建所有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)
谷歌的图片搜索接口如下:
# 构建所有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安装一下,就可以直接在终端运行了。安装命令如下:
pip install pyimagedl
使用方式如下:
Usage: imagedl [OPTIONS] Options: --version Show the version and exit. -k, --keyword TEXT 想要搜索下载的图片关键字, 若不指定, 则进入imagedl终端版 -s, --savedir TEXT 下载的图片的保存路径 -t, --target TEXT 指定图片搜索下载的平台, 例如"baidu" -l, --limits INTEGER 下载的图片数量 -n, --nthreadings INTEGER 使用的线程数量 --help Show this message and exit.
例如,在终端输入:
imagedl -k 狗狗 -s dogs -t baidu -l 1000
到此这篇关于利用Python多线程实现图片下载器的文章就介绍到这了,更多相关Python图片下载内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
X 关闭
X 关闭
- 15G资费不大降!三大运营商谁提供的5G网速最快?中国信通院给出答案
- 2联想拯救者Y70发布最新预告:售价2970元起 迄今最便宜的骁龙8+旗舰
- 3亚马逊开始大规模推广掌纹支付技术 顾客可使用“挥手付”结账
- 4现代和起亚上半年出口20万辆新能源汽车同比增长30.6%
- 5如何让居民5分钟使用到各种设施?沙特“线性城市”来了
- 6AMD实现连续8个季度的增长 季度营收首次突破60亿美元利润更是翻倍
- 7转转集团发布2022年二季度手机行情报告:二手市场“飘香”
- 8充电宝100Wh等于多少毫安?铁路旅客禁止、限制携带和托运物品目录
- 9好消息!京东与腾讯续签三年战略合作协议 加强技术创新与供应链服务
- 10名创优品拟通过香港IPO全球发售4100万股 全球发售所得款项有什么用处?