當我們需要在網站上大量下載某種圖片類型的時候,使用手動點擊圖片進行保存的形式既費時又費力,選擇用爬蟲來獲取海量圖片會極大的方便我們獲取圖片數據這一過程。
一.選擇有反爬蟲機制的網站進行爬取
我們最常見的圖片下載地址就是百度圖片了,但是百度擁有反爬蟲機制,網上很多爬蟲程序在一頁上只能爬取30張圖片,而且百度頁面沒有分頁,網址沒有頁數可以讓我們改,還好代碼裏面留了翻頁流的網址,所以,現在來分享給大家。
import re
import requests
from urllib import error
from bs4 import BeautifulSoup
import os
num = 0
numPicture = 0
file = ''
List = []
def Find(url):
global List
print('正在檢測圖片總數,請稍等.....')
t = 0
i = 1
s = 0
while t < 2000:
Url = url + str(t)
try:
Result = requests.get(Url, timeout=7)
except BaseException:
t = t + 60
continue
else:
result = Result.text
pic_url = re.findall('"objURL":"(.*?)",', result, re.S) # 先利用正則表達式找到圖片url
s += len(pic_url)
if len(pic_url) == 0:
break
else:
List.append(pic_url)
t = t + 60
return s
def recommend(url):
Re = []
try:
html = requests.get(url)
except error.HTTPError as e:
return
else:
html.encoding = 'utf-8'
bsObj = BeautifulSoup(html.text, 'html.parser')
div = bsObj.find('div', id='topRS')
if div is not None:
listA = div.findAll('a')
for i in listA:
if i is not None:
Re.append(i.get_text())
return Re
def dowmloadPicture(html, keyword):
global num
# t =0
pic_url = re.findall('"objURL":"(.*?)",', html, re.S) # 先利用正則表達式找到圖片url
print('找到關鍵詞:' + keyword + '的圖片,即將開始下載圖片...')
for each in pic_url:
print('正在下載第' + str(num + 1) + '張圖片,圖片地址:' + str(each))
try:
if each is not None:
pic = requests.get(each, timeout=7)
else:
continue
except BaseException:
print('錯誤,當前圖片無法下載')
continue
else:
string = file + r'\\' + keyword + '_' + str(num) + '.jpg'
fp = open(string, 'wb')
fp.write(pic.content)
fp.close()
num += 1
if num >= numPicture:
return
if __name__ == '__main__': # 主函數入口
word = input("請輸入搜索關鍵詞(可以是人名,地名等): ")
url = 'http://image.baidu.com/search/flip?tn=baiduimage&ie=utf-8&word=' + word + '&pn='#翻頁流的網址
tot = Find(url)
Recommend = recommend(url) # 記錄相關推薦
print('經過檢測%s類圖片共有%d張' % (word, tot))
numPicture = int(input('請輸入想要下載的圖片數量 '))
file = input('請建立一個存儲圖片的文件夾,輸入文件夾名稱即可')
y = os.path.exists(file)
if y == 1:
print('該文件已存在,請重新輸入')
file = input('請建立一個存儲圖片的文件夾,輸入文件夾名稱即可')
os.mkdir(file)
else:
os.mkdir(file)
t = 0
tmp = url
while t < numPicture:
try:
url = tmp + str(t)
result = requests.get(url, timeout=10)
print(url)
except error.HTTPError as e:
print('網絡錯誤,請調整網絡後重試')
t = t + 60
else:
dowmloadPicture(result.text, word)
t = t + 60
print('當前搜索結束,感謝使用')
print('猜你喜歡')
for re in Recommend:
print(re, end=' ')
整個運行臺的顯示如下(關鍵詞,下載數量,存儲文件夾由我們自己在運行臺中輸入設置):
選擇批量爬取關鍵詞爲“王凱”的圖片,選取了其中的兩張來展示。
二.選擇無反爬蟲機制的網站進行爬取
除了百度圖片以外,還可以從其它的網站上進行圖片爬取,比如:美桌,該網站並沒有robots協議,因此可以任意爬取。
我們可以對爬取的內容進行任意更改,比如說從美桌上爬取名爲“靳東”的圖片。爬取過程中用到的第三方庫主要是requests和pypinyin(將漢字轉換成拼音),代碼如下
import requests
import re
import os
from pypinyin import lazy_pinyin
class starImage():
def __init__(self):
# self.name = input("請輸入你喜歡的明星的名字:") # 放開這個地方可以下載網站內其他明星劇照
self.name = '靳東'
self.nameUrl = "http://www.win4000.com/mt/" + ''.join(lazy_pinyin(self.name)) + ".html"
self.path = r'./明星'+'/'+self.name
def getHTMLText(self,url):
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36',
'referer': 'http://www.win4000.com/mt/star.html'
}
re = requests.get(url, headers=headers, timeout=10) # 設置超時時間
if re.status_code == 200:
re.encoding = re.apparent_encoding # 以網站編碼爲準
return re.text
# 獲取詳情頁網址
def getPageUrls(self,Text):
re_pageUrl = re.findall('<a target="_blank" href="(.*?)">',Text)
# print(re_pageUrl)
return re_pageUrl
# 下載圖片
def downloadPic(self,pageUrls):
for i in range(len(pageUrls)):
pageHtmlTxet=self.getHTMLText(pageUrls[i])
photoName = re.findall('<div class="ptitle"><h1>(.*?)</h1>', pageHtmlTxet)[0] # 圖集名
photoList = re.findall('data-original="(.*?)" alt="%s"'%photoName,pageHtmlTxet) # 圖片URL
for index, jpg in enumerate(photoList):
jpg = jpg.replace('_130_170','')
path = self.path+'//'+photoName+'//' # 創建存放路徑
if not os.path.exists(path):
os.makedirs(path) # 遞歸創建文件夾
img = requests.get(jpg)
with open(path + '%s.jpg' % (index), 'wb') as f:
f.write(img.content)
print('下載 %s的%d圖片成功' % (photoName, index))
# 邏輯業務
def fun(self):
try:
Text = self.getHTMLText(self.nameUrl) # 第一頁
self.downloadPic(self.getPageUrls(Text)) # 下載第一分頁所有圖片
nextPage = re.findall(r'next" href="(.+)"', Text)[0] # 第二頁
self.downloadPic(self.getPageUrls(self.getHTMLText(nextPage))) # 下載第二分頁所有圖片
try:
while (nextPage):
nextText = self.getHTMLText(nextPage) # 其他分頁
nextPage = re.findall(r'next" href="(.+)"', nextText)[0]
self.downloadPic(self.getPageUrls(self.getHTMLText(nextPage))) # 下載第三頁至結束的所有圖片
except IndexError:
print("已全部下載完畢")
except TypeError:
print("不好意思,沒有{}的照片".format(self.name))
if __name__=='__main__':
a = starImage()
a.fun()
附上三張圖片
還是蠻帥氣的,哈哈