基于Python下載網(wǎng)絡(luò)圖片方法匯總代碼實(shí)例
本文介紹下載python下載網(wǎng)絡(luò)圖片的方法,包括通過(guò)圖片url直接下載、通過(guò)re/beautifulSoup解析html下載以及對(duì)動(dòng)態(tài)網(wǎng)頁(yè)的處理等。
通過(guò)pic_url單個(gè)/批量下載
已知圖片url,例如http://xyz.com/series-*(1,2..N).jpg,共N張圖片,其鏈接形式較為固定,這樣經(jīng)簡(jiǎn)單循環(huán),直接通過(guò)`f.write(requests.get(url).content)'即可以二進(jìn)制形式將圖片寫(xiě)入。
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-' # 同一類(lèi)目下的圖片url前綴
n = 6 # 該類(lèi)目下的圖片總數(shù)
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后下載
在實(shí)際操作中,圖片url按序排列情況較少,多數(shù)情況下用戶(hù)僅知道網(wǎng)頁(yè)url,需要對(duì)當(dāng)前網(wǎng)頁(yè)htnl內(nèi)容進(jìn)行解析,獲取源碼中包含的圖片url,常用方法有正則表達(dá)式匹配或BeautifulSoup等庫(kù)解析的方法。
正則re解析的思路是:首先通過(guò) requests.get(url).text 獲得當(dāng)前頁(yè)面html源碼;然后通過(guò)正則表達(dá)式匹配圖片url,如 re.compile(r'[a-zA-z]+://[^\s]*\.jpg') 正則式一般會(huì)得到.jpg結(jié)尾的url,但其他網(wǎng)站圖片url可能會(huì)以.png或.webp等結(jié)尾,甚至需要其他的正則匹配,為此,讀者需要對(duì)正則表達(dá)式有所了解,強(qiáng)烈推薦 正則表達(dá)式30分鐘入門(mén)教程 ;將前一步得到的圖片url加入列表,進(jìn)行下載。
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結(jié)尾的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, like Gecko) Chrome/83.0.4103.97 Safari/537.36 ",
}
r = requests.get(pic_url, headers=headers)
with open(file_path, 'wb') as f:
f.write(r.content)
def main():
# 使用時(shí)修改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()
通過(guò)bs4獲取pic_url
與正則匹配思路類(lèi)似,只不過(guò)通過(guò)Beautiful Soup解析html獲得圖片url列表,然后依次下載圖片。由于各網(wǎng)站html結(jié)構(gòu)有差異,用戶(hù)需要自行進(jìn)行適當(dāng)修改。以下代碼是對(duì)豆瓣圖片的下載。
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',
}
html = requests.get(url, 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, pic_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 ",
}
r = requests.get(pic_url, headers=headers)
with open(file_path, 'wb') as f:
f.write(r.content)
def main():
'從豆瓣下載石原里美圖片,觀察發(fā)現(xiàn)每頁(yè)包含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頁(yè)'%(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()
在下載圖片時(shí),發(fā)現(xiàn)可以直接訪問(wèn)圖片的縮略圖url進(jìn)行下載,但由于豆瓣的反爬策略,直接訪問(wèn)原圖url會(huì)被服務(wù)器拒絕,見(jiàn)下圖。解決方法見(jiàn)下一部分。

可能遇到的問(wèn)題
網(wǎng)站反爬蟲(chóng)機(jī)制
- User-Agent:模擬瀏覽器訪問(wèn),添加后,服務(wù)器會(huì)認(rèn)為是瀏覽器正常的請(qǐng)求。一般與網(wǎng)頁(yè)操作相關(guān)訪問(wèn)都予以添加。
- Referer:瀏覽器以此來(lái)判斷你從哪一個(gè)網(wǎng)頁(yè)跳轉(zhuǎn)過(guò)來(lái)。例如在上述豆瓣圖片的下載示例中,直接輸入網(wǎng)址會(huì)被拒絕,但你在網(wǎng)站一步步點(diǎn)擊卻會(huì)在同一地址中得到內(nèi)容,這就是因?yàn)槟阍谝徊讲皆L問(wèn)時(shí)是有一個(gè)前序跳轉(zhuǎn)地址的,這個(gè)地址可以通過(guò)“F12”在header中得到,如果找不到的話試一試根目錄地址“ movie.douban.com/”,或是前幾步的地址”… GitHub倉(cāng)庫(kù)'adv_bs4_url.py‘文件 。
- ip偽裝:構(gòu)建ip池。
- Cookie偽裝:cookie是服務(wù)器用來(lái)辨別你此時(shí)的狀態(tài)的,每一次向服務(wù)器請(qǐng)求cookie都會(huì)隨之更新。
- 常用正則式匹配
網(wǎng)頁(yè)的數(shù)據(jù)采用異步加載,如js渲染的頁(yè)面或ajax加載的數(shù)據(jù)通過(guò)get不到完整頁(yè)面源碼。
一種方案是常說(shuō)的動(dòng)態(tài)爬蟲(chóng),即采用一些第三方的工具,模擬瀏覽器的行為加載數(shù)據(jù),如Selenium、PhantomJs等。網(wǎng)絡(luò)上有較多介紹文章,有點(diǎn)麻煩就沒(méi)有自己寫(xiě)了,后續(xù)有需求的話在做吧,不過(guò)其他方法已經(jīng)夠用了。
另外可以通過(guò)分析頁(yè)面,找到請(qǐng)求借口,加載頁(yè)面。其核心就是跟蹤頁(yè)面的交互行為 JS 觸發(fā)調(diào)度,分析出有價(jià)值、有意義的核心調(diào)用(一般都是通過(guò) JS 發(fā)起一個(gè) HTTP 請(qǐng)求),然后我們使用 Python 直接訪問(wèn)逆向到的鏈接獲取價(jià)值數(shù)據(jù)。通過(guò)"F12”進(jìn)行分析,例如對(duì)于花瓣網(wǎng),可以獲得其鏈接為" huaban.com/search/?q=石… request.urlopen(url).read() 讀取網(wǎng)頁(yè)。

Pyautogui,鼠標(biāo)模擬點(diǎn)擊的“傻瓜式”流程
本方法僅適用于重復(fù)性的工作,而且效率較低,但完全沒(méi)有被反爬蟲(chóng)策略屏蔽的風(fēng)險(xiǎn)。其核心思想與word中的“宏”類(lèi)似,就是你告訴計(jì)算機(jī)一次循環(huán)中鼠標(biāo)分別如何操作,然后讓其自動(dòng)循環(huán)。代碼簡(jiǎn)單明了。
import pyautogui
import time
pyautogui.FAILSAFE = True
def get_mouse_positon():
time.sleep(3) # 此間將鼠標(biāo)移動(dòng)到初始位置
x1, y1 = pyautogui.position()
print(x1, y1)
pyautogui.click(x=x1, y=y1, button='right') # 模擬鼠標(biāo)右鍵點(diǎn)擊,呼出菜單
time.sleep(5) # 此間將鼠標(biāo)移動(dòng)到“save image as...”選項(xiàng)中央
x2, y2 = pyautogui.position()
print(x2, y2)
pyautogui.click(x=x2, y=y2) # 模擬鼠標(biāo)左鍵點(diǎn)擊,點(diǎn)中“save image as...”
time.sleep(10) # 此間彈出保存文件彈窗,自行選擇保存位置,并將鼠標(biāo)移至“保存(S)”按鈕中央
x3, y3 = pyautogui.position()
pyautogui.click(x=x3, y=y3)
print(x3, y3)
def click_download(N):
for i in range(N): # 擬下載圖片數(shù)量
pyautogui.click(x=517, y=557, duration=0.25, button='right') # 呼出菜單,自行將x/y設(shè)置為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, y=557, duration=0.25) # 進(jìn)入下一張圖片
time.sleep(2) # 取決于網(wǎng)絡(luò)加載速度,自行設(shè)置
if __name__ == "__main__":
# get_mouse_positon() # 一開(kāi)始只運(yùn)行此命令,獲取屏幕坐標(biāo),后續(xù)注釋掉該句
click_download(10)
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Python Flask請(qǐng)求擴(kuò)展與中間件相關(guān)知識(shí)總結(jié)
今天帶大家學(xué)習(xí)的是關(guān)于Python Flask的相關(guān)知識(shí),文章圍繞著Flask請(qǐng)求擴(kuò)展與中間件的知識(shí)展開(kāi),文中有非常詳細(xì)的介紹,需要的朋友可以參考下2021-06-06
pytorch fine-tune 預(yù)訓(xùn)練的模型操作
這篇文章主要介紹了pytorch fine-tune 預(yù)訓(xùn)練的模型操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06
批量將ppt轉(zhuǎn)換為pdf的Python代碼 只要27行!
這篇文章主要為大家詳細(xì)介紹了批量將ppt轉(zhuǎn)換為pdf的Python代碼,只要27行,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-02-02
解決json.decoder.JSONDecodeError: Expecting value:&n
這篇文章主要介紹了解決json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)錯(cuò)誤,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-04-04
Python項(xiàng)目 基于Scapy實(shí)現(xiàn)SYN泛洪攻擊的方法
今天小編就為大家分享一篇Python項(xiàng)目 基于Scapy實(shí)現(xiàn)SYN泛洪攻擊的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-07-07
Python發(fā)送郵件實(shí)現(xiàn)基礎(chǔ)解析
這篇文章主要介紹了Python發(fā)送郵件實(shí)現(xiàn)基礎(chǔ)解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08
在Python的Django框架中編寫(xiě)編譯函數(shù)
這篇文章主要介紹了在Python的Django框架中編寫(xiě)編譯函數(shù),配合模版標(biāo)簽在模版中進(jìn)行使用<需要的朋友可以參考下2015-07-07
讓代碼變得更易維護(hù)的7個(gè)Python庫(kù)
今天小編就為大家分享一篇關(guān)于讓代碼變得更易維護(hù)的7個(gè)Python庫(kù),小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2018-10-10

