Python3 爬蟲從unsplash網站抓取高清大圖

在互聯網上訪問網站(系統)時,服務器上的反饋方式有兩種:一種是直接向用戶返回一個靜態html頁面,這個頁面及其內容在用戶訪問之前就已經完整存在於服務器某一路徑上;另一種是根據用戶的請求,先從數據庫加載相關數據,形成網頁反饋給用戶,頁面的數據還會根據用戶的訪問或者數據庫的數據更新而自動更新。

Python3 爬蟲從網站抓取圖片(一)練習了從中央政府網站抓取圖片,它的網頁內容就是前一種反饋和存儲方式,鏈接都被靜態化存儲在html頁面中,使用BeautifulSoup庫可以很好處理。

百度等搜索網站、淘寶京東等購物網站和買賣股票網站都屬於後一類。這次選擇一個免費的攝影作品網站(unsplash.com)進行抓取圖片練習。這個網站也推薦給大家,需要各種美圖的朋友可以從這裡找到自己喜歡的照片。

Python3 爬蟲從unsplash網站抓取高清大圖

在搜索框輸入一個主題,比如我們查找與中國有關的圖片。可以看到這個網站對於同一主題的圖片是放在固定的路徑之下:/s/photos/china。

Python3 爬蟲從unsplash網站抓取高清大圖

與中國有關的圖片一共搜到5700+張,每張圖片下放顯示名稱。鼠標移動到圖片右下角會有一個下載箭頭,最下邊就會顯示下載鏈接。這個鏈接很有特點,不同照片的下載鏈接只有photos和download之間的部分不一樣,這部分應該就是每一張圖片的實際ID或者存放名稱。

Python3 爬蟲從unsplash網站抓取高清大圖

接下來的任務就是找到這些ID的存儲位置。前面已經講過,這個網站屬於動態加載數據的一類網站,這就需要F12打開瀏覽器的開發人員工具查看。可是在查看了所有js腳本,都沒有發現相關數據。

Python3 爬蟲從unsplash網站抓取高清大圖

動態加載圖片的網站都有一個特點,就是繼續下拉會出現新的圖片。操作之後,果然出現了一個存儲數據內容的腳本,裡面包含圖片id,links下還有這張照片的下載鏈接。

Python3 爬蟲從unsplash網站抓取高清大圖

繼續分析這個腳本的路徑:後面的參數表明,網站加載了china主題的圖片,默認每頁加載顯示20張,當下是第2頁。可以通過修改query、per_page和page 3個參數加載我們想要現在的圖片主題和數量。

Python3 爬蟲從unsplash網站抓取高清大圖

下面開始編寫代碼,定義3個主要函數:

獲取頁面Response對象的getHtmlResponse(url)函數,這裡給headers加入兩個參數“User-Agent”和“Referer”,讓爬蟲更像是人在訪問,而且是從unsplash網站一步一步操作的。同時,處理ssl安全認證,將requests.get()函數的verify=False,這時會有警告信息,使用urllib3模塊的disable_warnings()使其不予顯示。

Python3 爬蟲從unsplash網站抓取高清大圖

下載一張圖片的getPicture(url,theme,name)函數,輸入鏈接ulr,存儲路徑path和文件名name三個參數。根據主題theme創建文件夾,將下載的圖片存放在同一主題目錄下。

Python3 爬蟲從unsplash網站抓取高清大圖

下載1頁20張圖片的getOnePage(url,path)。從links:download獲取下載鏈接,並確定下載尺寸,這裡選定寬度為1920。獲取“alt_description”的值命名文件。

Python3 爬蟲從unsplash網站抓取高清大圖

最後定義主函數,由用戶輸入需要下載的主題和數量。

Python3 爬蟲從unsplash網站抓取高清大圖

完整代碼如下:

<code># _*_ coding:utf-8 _*_

import requests
import math
import json
import os
from requests.packages import urllib3

# 獲取頁面Response
def getHtmlResponse(url):
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36 Edg/80.0.361.69',
'Referer': 'https://unsplash.com/'
}

try:
urllib3.disable_warnings()
r = requests.get(url,verify=False,headers=headers)
r.raise_for_status()
r.encoding = r.apparent_encoding
return r
except Exception as e:
return ''

# 下載一張圖片
def getPicture(url,path,name):
try:
req = getHtmlResponse(url)
if not os.path.exists(path):
os.makedirs(path)
with open(path+name,'wb') as f:
f.write(req.content)
f.flush()
except Exception as e:
return ''

# 下載一頁20張圖片
def getOnePage(url,path):
req = getHtmlResponse(url)
html = req.text
data = json.loads(html)
# getPicture(url)
count = 0
for result in data['results']:

count = count + 1
# 獲取“alt_description”命名文件
name = result['alt_description']+'.jpg'
# 獲取下載鏈接,並確定下載尺寸,這裡選定寬度為1920
pic_url = result['links']['download']+'?force=true&w=1920'
print('正在下載第%d張照片:%s……' % (count,name))
getPicture(pic_url,path,name)

# 主函數
if __name__ == '__main__':
theme = input('請輸入要下載的照片主題:')
path = theme + '/'
num = int(input('請輸入下載數量:'))
page_num = math.ceil(num/20)

for i in range(1,page_num+1):
url = 'http://unsplash.com/napi/search/photos?query='+theme+'&per_page=20&page='+str(i)
getOnePage(url,path)
print('第'+ i +'頁下載完畢')

print('%d張%s主題的照片全部下載完成!' % (num,theme))/<code>

最後運行效果:

Python3 爬蟲從unsplash網站抓取高清大圖

選擇一張圖片看看:

Python3 爬蟲從unsplash網站抓取高清大圖


分享到:


相關文章: