基於Python下載網路圖片方法彙總程式碼例項
本文介紹下載python下載網路圖片的方法,包括通過圖片url直接下載、通過re/beautifulSoup解析html下載以及對動態網頁的處理等。
通過pic_url單個/批量下載
已知圖片url,例如http://xyz.com/series-*(1,2..N).jpg,共N張圖片,其連結形式較為固定,這樣經簡單迴圈,直接通過`f.write(requests.get(url).content)'即可以二進位制形式將圖片寫入。
import os import requests def download(file_path,picture_url): headers = { "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/63.0.3239.132 Safari/537.36 QIHU 360SE",} r = requests.get(picture_url,headers=headers) with open(file_path,'wb') as f: f.write(r.content) def main(): os.makedirs('./pic/',exist_ok=True) # 輸出目錄 prefix_url = 'http://xyz.com/series-' # 同一類目下的圖片url字首 n = 6 # 該類目下的圖片總數 tmp = prefix_url.split('/')[-1] for i in range(1,n + 1): file_path = './pic/' + tmp + str(i) + '.jpg' picture_url = prefix_url + str(i) + '.jpg' download(file_path,picture_url) if __name__ == '__main__': main()
正則re解析html獲取pic_url後下載
在實際操作中,圖片url按序排列情況較少,多數情況下使用者僅知道網頁url,需要對當前網頁htnl內容進行解析,獲取原始碼中包含的圖片url,常用方法有正則表示式匹配或BeautifulSoup等庫解析的方法。
正則re解析的思路是:首先通過 requests.get(url).text 獲得當前頁面html原始碼;然後通過正則表示式匹配圖片url,如 re.compile(r'[a-zA-z]+://[^\s]*\.jpg') 正則式一般會得到.jpg結尾的url,但其他網站圖片url可能會以.png或.webp等結尾,甚至需要其他的正則匹配,為此,讀者需要對正則表示式有所瞭解,強烈推薦 正則表示式30分鐘入門教程 ;將前一步得到的圖片url加入列表,進行下載。
import os import re import requests def get_html(url): headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/83.0.4103.97 Safari/537.36 ",} html = requests.get(url,headers=headers).text return html def parse_html(html_text): picre = re.compile(r'[a-zA-z]+://[^\s]*\.jpg') # 本正則式得到.jpg結尾的url pic_list = re.findall(picre,html_text) return pic_list def download(file_path,pic_url): headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML,} r = requests.get(pic_url,headers=headers) with open(file_path,'wb') as f: f.write(r.content) def main(): # 使用時修改url即可 url = 'http://xyz.com/series' html_text = get_html(url) pic_list = parse_html(html_text) os.makedirs('./pic/',exist_ok=True) # 輸出目錄 for pic_url in pic_list: file_name = pic_url.split('/')[-1] file_path = './pic/' + file_name download(file_path,pic_url) if __name__ == '__main__': main()
通過bs4獲取pic_url
與正則匹配思路類似,只不過通過Beautiful Soup解析html獲得圖片url列表,然後依次下載圖片。由於各網站html結構有差異,使用者需要自行進行適當修改。以下程式碼是對豆瓣圖片的下載。
import os import time import requests from bs4 import BeautifulSoup def get_html(url): headers = { 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/68.0.3440.106 Safari/537.36',headers=headers).text return html def parse_html(html_text): soup = BeautifulSoup(html_text,'html.parser') li = soup.find_all('div',attrs={'class':'cover'}) pic_list = [] for link in li: pic_url = link.find('img').get('src') pic_url = pic_url.replace('/m/','/l/') pic_list.append(pic_url) return pic_list def download(file_path,'wb') as f: f.write(r.content) def main(): '從豆瓣下載石原里美圖片,觀察發現每頁包含30張圖片,其url按30遞增,如下所示' pic_list = [] for i in range(10): url = 'https://movie.douban.com/celebrity/1016930/photos/?type=C&start=' + str(30*i) + '&sortby=like&size=a&subtype=a' html_text = get_html(url) pic_list += parse_html(html_text) os.makedirs('./pic/',exist_ok=True) # 輸出目錄 for i,pic_url in enumerate(pic_list): if i%30 == 0: print('正在下載第%s頁'%(i/30+1)) file_name = pic_url.split('/')[-1].split('.')[0] + '.jpg' file_path = './pic/' + file_name download(file_path,pic_url) if __name__ == '__main__': main()
在下載圖片時,發現可以直接訪問圖片的縮圖url進行下載,但由於豆瓣的反爬策略,直接訪問原圖url會被伺服器拒絕,見下圖。解決方法見下一部分。
可能遇到的問題
網站反爬蟲機制
- User-Agent:模擬瀏覽器訪問,新增後,伺服器會認為是瀏覽器正常的請求。一般與網頁操作相關訪問都予以新增。
- Referer:瀏覽器以此來判斷你從哪一個網頁跳轉過來。例如在上述豆瓣圖片的下載示例中,直接輸入網址會被拒絕,但你在網站一步步點選卻會在同一地址中得到內容,這就是因為你在一步步訪問時是有一個前序跳轉地址的,這個地址可以通過“F12”在header中得到,如果找不到的話試一試根目錄地址“ movie.douban.com/”,或是前幾步的地址”… GitHub倉庫'adv_bs4_url.py‘檔案 。
- ip偽裝:構建ip池。
- Cookie偽裝:cookie是伺服器用來辨別你此時的狀態的,每一次向伺服器請求cookie都會隨之更新。
- 常用正則式匹配
網頁的資料採用非同步載入,如js渲染的頁面或ajax載入的資料通過get不到完整頁面原始碼。
一種方案是常說的動態爬蟲,即採用一些第三方的工具,模擬瀏覽器的行為載入資料,如Selenium、PhantomJs等。網路上有較多介紹文章,有點麻煩就沒有自己寫了,後續有需求的話在做吧,不過其他方法已經夠用了。
另外可以通過分析頁面,找到請求借口,載入頁面。其核心就是跟蹤頁面的互動行為 JS 觸發排程,分析出有價值、有意義的核心呼叫(一般都是通過 JS 發起一個 HTTP 請求),然後我們使用 Python 直接訪問逆向到的連結獲取價值資料。通過"F12”進行分析,例如對於花瓣網,可以獲得其連結為" huaban.com/search/?q=石… request.urlopen(url).read() 讀取網頁。
Pyautogui,滑鼠模擬點選的“傻瓜式”流程
本方法僅適用於重複性的工作,而且效率較低,但完全沒有被反爬蟲策略遮蔽的風險。其核心思想與word中的“巨集”類似,就是你告訴計算機一次迴圈中滑鼠分別如何操作,然後讓其自動迴圈。程式碼簡單明瞭。
import pyautogui import time pyautogui.FAILSAFE = True def get_mouse_positon(): time.sleep(3) # 此間將滑鼠移動到初始位置 x1,y1 = pyautogui.position() print(x1,y1) pyautogui.click(x=x1,y=y1,button='right') # 模擬滑鼠右鍵點選,撥出選單 time.sleep(5) # 此間將滑鼠移動到“save image as...”選項中央 x2,y2 = pyautogui.position() print(x2,y2) pyautogui.click(x=x2,y=y2) # 模擬滑鼠左鍵點選,點中“save image as...” time.sleep(10) # 此間彈出儲存檔案彈窗,自行選擇儲存位置,並將滑鼠移至“儲存(S)”按鈕中央 x3,y3 = pyautogui.position() pyautogui.click(x=x3,y=y3) print(x3,y3) def click_download(N): for i in range(N): # 擬下載圖片數量 pyautogui.click(x=517,y=557,duration=0.25,button='right') # 撥出選單,自行將x/y設定為x1/y1 time.sleep(1) pyautogui.click(x=664,y=773,duration=0.25) # 下載,x/y為x2/y2 time.sleep(1) pyautogui.click(x=745,y=559,duration=0.25) # 儲存,x/y為x3/y3 time.sleep(1) pyautogui.click(x=517,duration=0.25) # 進入下一張圖片 time.sleep(2) # 取決於網路載入速度,自行設定 if __name__ == "__main__": # get_mouse_positon() # 一開始只執行此命令,獲取螢幕座標,後續註釋掉該句 click_download(10)
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。