同时下载多张图片
这篇文章会使用 Python 的 Requests 和 Beautiful Soup 函数库,搭配 concurrent.futures 内建函数库,实作一个可以同时且自动下载图片的网络爬虫。
本篇使用的 Python 版本为 3.7.12,所有范例可使用 Google Colab 实作,不用安装任何软件 ( 参考:使用 Google Colab )
使用“自动下载 PTT 正妹图片”范例程序
在“自动下载 PTT 正妹图片”文章中,已经介绍过如何自动下载图片,这篇教学将从这个范例延伸,将原本“一张一张依序下载”的图片,改成“同时”下载,就能大幅减少下载时间,将下方的程序复制贴上到 Colab、Jupyter 或自己的编辑器中。
import requests
from bs4 import BeautifulSoup
web = requests.get('https://www.ptt.cc/bbs/Beauty/M.1638380033.A.7C7.html', cookies={'over18':'1'})
soup = BeautifulSoup(web.text, "html.parser")
imgs = soup.find_all('img')
name = 0
for i in imgs:
print(i['src'])
jpg = requests.get(i['src'])
f = open(f'content/drive/MyDrive/Colab Notebooks/download/test_{name}.jpg', 'wb')
f.write(jpg.content)
f.close()
name = name + 1
使用 concurrent.futures
使用 concurrent.futures 内建函数库,将原本的程序,从“同步”改为“异步”执行,由于在使用“多执行绪”时如果搭配全域变数,会发生内存位置重叠的失败状况,为了避免这种状况,在取得图片网址时,先一并将名称编号设定好,最后再将编号提供给执行绪处理即可。
import requests
from bs4 import BeautifulSoup
from concurrent.futures import ThreadPoolExecutor # 加入 concurrent.futures 內建函式庫
web = requests.get('https://www.ptt.cc/bbs/Beauty/M.1638380033.A.7C7.html', cookies={'over18':'1'})
soup = BeautifulSoup(web.text, "html.parser")
imgs = soup.find_all('img')
name = 0
img_urls = [] # 根據爬取的資料,建立一個圖片名稱與網址的空串列
for i in imgs: # 修改 for 迴圈內容
img_urls.append([i['src'], name]) # 將圖片網址與編號加入串列中
name = name + 1 # 編號增加 1
def download(url): # 編輯下載函式
print(url) # 印出網址
jpg = requests.get(url[0]) # 使用 requests.get 取得圖片資訊
f = open(f'download/test_{url[1]}.jpg', 'wb') # 將圖片開啟為二進位格式 ( 請自行修改存取路徑 )
f.write(jpg.content) # 存取圖片
f.close()
executor = ThreadPoolExecutor() # 建立非同步的多執行緒的啟動器
with ThreadPoolExecutor() as executor:
executor.map(download, img_urls) # 同時下載圖片
程序执行后,就会看见图片“几乎同时”下载到电脑里。
如果使用 Colab 就会下载到云端硬盘指定的文件夹里。
小结
如果要用爬虫下载大量图片,使用“异步”( 多执行绪平行处理 ) 的方式是相当方便的做法,不仅不用一张张的等待,更能发挥闲置 CPU 最大的效益 ( 同一时间里可以做很多事情 )。
微信扫码关注
抖音扫码关注