- 原文地址:30-minute Python Web Scraper
- 原文做者:Angelos Chalaris
- 譯文出自:掘金翻譯計劃
- 本文永久連接:github.com/xitu/gold-m…
- 譯者:kezhenxu94
- 校對者:luochen1992 leviding
一直想用 Python 和 Selenium 寫一個網頁爬蟲,但一直都沒去實現。直到幾天前我才決定動手實現它。寫代碼從 Unsplash 網站上抓取一些漂亮的圖片,這看起來好像是很是艱鉅的事情,但實際上倒是極其簡單。css
圖片來源:Blake Connally 發佈於 Unsplash.comhtml
以上的全部都安裝好了?棒!在咱們繼續開始寫代碼前,我先來解釋一下以上這些原料都是用來幹什麼的。前端
咱們首先要作的是利用 Selenium webdriver 和 geckodriver 來爲咱們打開一個瀏覽器窗口。首先,在 Pycharm 中新建一個項目,根據你的操做系統下載最新版的 geckodriver,將其解壓並把 geckodriver 文件拖到項目文件夾中。Geckodriver 本質上就是一個能讓 Selenium 控制 Firefox 的工具,所以咱們的項目須要它來讓瀏覽器幫咱們作一些事。python
接下來咱們要作的事就是從 Selenium 中導入 webdriver 到咱們的代碼中,而後鏈接到咱們想爬取的 URL 地址。說作就作:android
from selenium import webdriver
# 咱們想要瀏覽的 URL 連接
url = "https://unsplash.com"
# 使用 Selenium 的 webdriver 來打開這個頁面
driver = webdriver.Firefox(executable_path=r'geckodriver.exe')
driver.get(url)
複製代碼
打開瀏覽器窗口到指定的 URL。ios
一個遠程控制的 Firefox 窗口。git
至關容易對吧?若是以上所說你都正確完成了,你已經攻克了最難的那部分了,此時你應該看到一個相似於以上圖片所示的瀏覽器窗口。github
接下來咱們就應該向下滾動以便更多的圖片能夠加載出來,而後咱們纔可以將它們下載下來。咱們還想再等幾秒鐘,以便萬一網絡鏈接太慢了致使圖片沒有徹底加載出來。因爲 Unsplash 網站是使用 React 構建的,等個 5 秒鐘彷佛已經足夠」慷慨」了,那就使用 Python 的 time
包等個 5 秒吧,咱們還要使用一些 Javascript 代碼來滾動網頁——咱們將會用到 [window.scrollTo()](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo)
函數來實現這個功能。將以上所說的合併起來,最終你的代碼應該像這樣:web
import time
from selenium import webdriver
url = "https://unsplash.com"
driver = webdriver.Firefox(executable_path=r'geckodriver.exe')
driver.get(url)
# 向下滾動頁面而且等待 5 秒鐘
driver.execute_script("window.scrollTo(0,1000);")
time.sleep(5)
複製代碼
滾動頁面並等待 5 秒鐘。網頁爬蟲
測試完以上代碼後,你應該會看到瀏覽器的頁面稍微往下滾動了一些。下一步咱們要作的就是找到咱們要下載的那些圖片。在探索了一番 React 生成的代碼以後,我發現了咱們可使用一個 CSS 選擇器來定位到網頁上畫廊的圖片。網頁上的佈局和代碼在之後可能會發生改變,但目前咱們可使用 #gridMulti img
選擇器來得到屏幕上可見的全部 <img>
元素。
咱們能夠經過 [find_elements_by_css_selector()](http://selenium-python.readthedocs.io/api.html#selenium.webdriver.remote.webdriver.WebDriver.find_element_by_css_selector)
獲得這些元素的一個列表,但咱們想要的是這些元素的 src
屬性。咱們能夠遍歷這個列表並一一抽取出 src
來:
import time
from selenium import webdriver
url = "https://unsplash.com"
driver = webdriver.Firefox(executable_path=r'geckodriver.exe')
driver.get(url)
driver.execute_script("window.scrollTo(0,1000);")
time.sleep(5)
# 選擇圖片元素並打印出他們的 URL
image_elements = driver.find_elements_by_css_selector("#gridMulti img")
for image_element in image_elements:
image_url = image_element.get_attribute("src")
print(image_url)
複製代碼
選擇圖片元素並得到圖片 URL。
如今爲了真正得到咱們找到的圖片,咱們會使用 requests
庫和 PIL
的部分功能,也就是 Image
。咱們還會用到 io
庫裏面的 BytesIO
來將圖片寫到文件夾 ./images/
中(在項目文件夾中建立)。如今把這些都一塊兒作了,咱們要先往每張圖片的 URL 連接發送一個 HTTP GET 請求,而後使用 Image
和 BytesIO
來將返回的圖片存儲起來。如下是實現這個功能的其中一種方式:
import requests
import time
from selenium import webdriver
from PIL import Image
from io import BytesIO
url = "https://unsplash.com"
driver = webdriver.Firefox(executable_path=r'geckodriver.exe')
driver.get(url)
driver.execute_script("window.scrollTo(0,1000);")
time.sleep(5)
image_elements = driver.find_elements_by_css_selector("#gridMulti img")
i = 0
for image_element in image_elements:
image_url = image_element.get_attribute("src")
# 發送一個 HTTP GET 請求,從響應內容中得到圖片並將其存儲
image_object = requests.get(image_url)
image = Image.open(BytesIO(image_object.content))
image.save("./images/image" + str(i) + "." + image.format, image.format)
i += 1
複製代碼
下載圖片。
這就是爬取一堆圖片所須要作的全部了。很顯然的是,除非你想隨便找些圖片素材來作個設計原型,不然這個小小的爬蟲用處可能不是很大。因此我花了點時間來優化它,加了些功能:
你能夠(你也應該)嘗試本身實現這些功能。全功能版本的爬蟲能夠在這裏下載。記得要先按照文章開頭所說的,下載 geckodriver 而後鏈接到你的項目中。
整個項目是一個簡單的「驗證概念」,以弄清楚網頁爬蟲是如何作的,這也就意味着有不少東西能夠作,來優化這個小工具:
PATH
系統變量中。掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 Android、iOS、前端、後端、區塊鏈、產品、設計、人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。