圖像辨識的技術,現在已經廣泛的應用在日常生活中,舉例來說,Google相簿就有使用圖像辨識的技術,來協助使用者標記景點或人物,或是Facebook使用圖片辨識來取出圖片中的文字,來找出違反政策的貼文,改善動態消息的內容等。
而要讓機器能夠辨識出圖片中的內容,就需要有大量的圖片進行機器學習,這時候就可以利用Python網頁爬蟲的技術,蒐集網路上所需的圖片,進而輸入機器中學習。
所以本文想來和讀者分享,如何利用Python網頁爬蟲來自動化下載圖片,其中的開發流程為:
- 分析圖片來源網站
- 爬取圖片來源網址
- 下載圖片至資料夾中
一、分析圖片來源網站
本文以Unsplash圖片網站為例,其中包含許多種類的高解析度圖片,如下:
假設在搜尋的地方輸入car,就可以找到汽車相關的圖片,如下:
這時候可以觀察網址的地方,最後會加上使用者所輸入的查詢關鍵字,如下圖:
接著,來看一下每張圖片的HTML原始碼結構,如下圖:
可以看到,圖片標籤(img)的樣式類別(class)為「_2VWD4 _2zEKz」,Python網頁爬蟲就能夠依據這個樣式類別(class)來進行定位,取得圖片。
二、爬取圖片來源網址
瞭解所要爬取的Unsplash圖片網站結構後,本文以Visual Studio Code,開啟Python網頁爬蟲專案資料夾,在Terminal的視窗中,利用以下的指令安裝所需的套件:
$ pip install requests
$ pip install beautifulsoup4
$ pip install lxml
其中Requests套件用來發送請求給網頁,回應的結果就是使用BeautifulSoup套件爬取內容,而lxml則是支援BeautifulSoup套件的HTML/XML解析器。
安裝完成後,建立app.py檔案,並且引用以下的模組(Module):
from bs4 import BeautifulSoup import requests import os
範例中引用的os模組(Module),提供操作檔案及目錄的方法,可以協助建立資料夾及存放下載的圖片。
為了提供一個互動的介面,讓使用者能夠輸入想要下載的圖片,可以利用Python內建的input()方法(Method),取得所輸入的文字,如下範例:
from bs4 import BeautifulSoup import requests import os input_image = input("請輸入要下載的圖片:")
接下來,就可以透過requests模組(Module)的GET方法(Method),來請求Unsplash的圖片網址,並且將使用者所輸入的文字加在網址最後面,如下範例:
from bs4 import BeautifulSoup import requests import os input_image = input("請輸入要下載的圖片:") response = requests.get(f"https://unsplash.com/s/photos/{input_image}")
取得了回應結果後,就可以利用BeautifulSoup模組(Module)來進行解析,爬取所有樣式類別(class)為「_2VWD4 _2zEKz」的圖片標籤(img),如下範例:
from bs4 import BeautifulSoup import requests import os input_image = input("請輸入要下載的圖片:") response = requests.get(f"https://unsplash.com/s/photos/{input_image}") soup = BeautifulSoup(response.text, "lxml") results = soup.find_all("img", {"class": "_2VWD4 _2zEKz"}, limit=5)
範例中的limit參數為限制Python網頁爬蟲取得的圖片數量,讀者可以依照需求自行調整。
有了所有的圖片標籤(img)元素後,就能夠利用迴圈進行讀取,並且使用get()方法(Method)取得其中的src(圖片來源網址)屬性,加入到串列(List)中,這邊使用Python Comprehension語法來完成,如下範例第12行:
from bs4 import BeautifulSoup import requests import os input_image = input("請輸入要下載的圖片:") response = requests.get(f"https://unsplash.com/s/photos/{input_image}") soup = BeautifulSoup(response.text, "lxml") results = soup.find_all("img", {"class": "_2VWD4 _2zEKz"}, limit=5) image_links = [result.get("src") for result in results] # 取得圖片來源連結
這時候我們已經擁有五張圖片的來源網址,接下來,就需要建立資料夾,進行圖片的下載。
三、下載圖片至資料夾中
首先,利用迴圈來讀取圖片的來源網址串列(List),由於在下載圖片時,想要以使用者輸入的文字(input_image)加上迴圈的索引值來命名圖檔,所以使用Python內建的enumerate()方法(Method),來產生迴圈的索引值,詳細的使用方式及觀念,可以參考[Python教學]Python Unpacking實用技巧分享文章的第三節。如下範例:
from bs4 import BeautifulSoup import requests import os input_image = input("請輸入要下載的圖片:") response = requests.get(f"https://unsplash.com/s/photos/{input_image}") soup = BeautifulSoup(response.text, "lxml") results = soup.find_all("img", {"class": "_2VWD4 _2zEKz"}, limit=5) image_links = [result.get("src") for result in results] # 取得圖片來源連結 for index, link in enumerate(image_links):
這時候,利用os模組(Module)來檢查目前的Python網頁爬蟲專案資料夾下,是否有「images」資料夾,如果沒有,則使用mkdir()方法(Method)來建立,如下範例:
from bs4 import BeautifulSoup import requests import os input_image = input("請輸入要下載的圖片:") response = requests.get(f"https://unsplash.com/s/photos/{input_image}") soup = BeautifulSoup(response.text, "lxml") results = soup.find_all("img", {"class": "_2VWD4 _2zEKz"}, limit=5) image_links = [result.get("src") for result in results] # 取得圖片來源連結 for index, link in enumerate(image_links): if not os.path.exists("images"): os.mkdir("images") # 建立資料夾
「images」資料夾建立完成後,就可以利用requests模組(Module)的get()方法(Method),傳入圖片的來源網址,來下載圖片,如下範例:
from bs4 import BeautifulSoup import requests import os input_image = input("請輸入要下載的圖片:") response = requests.get(f"https://unsplash.com/s/photos/{input_image}") soup = BeautifulSoup(response.text, "lxml") results = soup.find_all("img", {"class": "_2VWD4 _2zEKz"}, limit=5) image_links = [result.get("src") for result in results] # 取得圖片來源連結 for index, link in enumerate(image_links): if not os.path.exists("images"): os.mkdir("images") # 建立資料夾 img = requests.get(link) # 下載圖片
最後,使用with陳述式,打開「images」資料夾,並且命名圖檔,指定寫入圖片的二進位碼(wb),直到所有的圖片皆寫入完畢,就會自動關閉資料夾,釋放資源,這就是使用with陳述式的優點,如下範例:
from bs4 import BeautifulSoup import requests import os input_image = input("請輸入要下載的圖片:") response = requests.get(f"https://unsplash.com/s/photos/{input_image}") soup = BeautifulSoup(response.text, "lxml") results = soup.find_all("img", {"class": "_2VWD4 _2zEKz"}, limit=5) image_links = [result.get("src") for result in results] # 取得圖片來源連結 for index, link in enumerate(image_links): if not os.path.exists("images"): os.mkdir("images") # 建立資料夾 img = requests.get(link) # 下載圖片 with open("images\\" + input_image + str(index+1) + ".jpg", "wb") as file: # 開啟資料夾及命名圖片檔 file.write(img.content) # 寫入圖片的二進位碼
在Terminal視窗中,執行app.py檔案,輸入car關鍵字,就可以在「images」資料夾看到下載的汽車圖片:
而輸入bag關鍵字,則可以看到下載的包包圖片:
四、小結
以上就是利用Python網頁爬蟲下載圖片的方式,這樣就能夠有效的自動化蒐集所需的圖片,對於實作圖像辨識方面的機器學習相當有幫助,歡迎分享給身邊有想要使用Python網頁爬蟲技術來下載圖片的朋友,希望有所幫助 :)
我試過後發現會重複出現三張圖? 而且class好像跟以前不一樣,是unsplash開始擋爬蟲了嗎@@
回覆刪除我是重複兩張圖.....QAQ
刪除請問為什麼我執行程式碼後他不會建立目錄
回覆刪除unsplash的port為443屬於加密HTTP,一般人不能爬取
回覆刪除