本篇目标
1.輸入關鍵字能夠根據關鍵字爬取百度圖檔
2.能夠将圖檔儲存到本地檔案夾
1.URL的格式
進入百度圖檔搜尋apple,這時顯示的是瀑布流版本,我們選擇傳統翻頁版本進行爬取。可以看到網址為:
https://image.baidu.com/search/flip?tn=baiduimage&ie=utf-8&word=apple&pn=0
點選下一頁發現網址變為pn=20,這裡僅pn發生了改變
2.抓取圖檔
打開開發者選項,點選圖檔,出現圖檔的代碼,如下圖
複制這裡的圖檔位址,在頁面上點選右鍵顯示源代碼,查找剛剛複制的位址,我們可以看到有thumbURL,middleURL,hoverURL,objURL
這裡objURL顯示的圖檔最清晰,我們就爬取這個,是以可以寫出正規表達式
pattern = re.compile(\'"objURL":"(.*?)",\', re.S)
items = re.findall(pattern, page)
3.建立目錄
def mkdir(self, path):
path = path.strip()
#判斷路徑是否存在
#存在為True 不存在為False
isExists = os.path.exists(path)
if not isExists:
#如果不存在則建立目錄
print u"建立了名為", path, u"的檔案夾"
#建立目錄操作函數
os.makedirs(path)
return True
else:
#如果目錄存在則不建立,并提示目錄已存在
print u"名為", path, u"的檔案夾已存在"
return False
4.儲存圖檔為.jpg格式
for item in items:
try:
u = urllib2.urlopen(item, timeout=20)
except urllib2.URLError, e:
print e.reason
continue
data = u.read()
name = path + "/" + word + str(i) + ".jpg"
f = open(name, \'wb\')
f.write(data)
print u"正在儲存圖檔為", name, u"圖檔位址為:", item
f.close()
i += 1
item是利用正規表達式查找到的圖檔網址
5.編寫測試代碼
#-*- coding:utf-8 -*-
import urllib2
import os
import re
import sys
# 設定編碼
reload(sys)
sys.setdefaultencoding(\'utf-8\')
# 獲得系統編碼格式
type = sys.getfilesystemencoding()
word = raw_input("請輸入關鍵字: ".decode(\'utf-8\').encode(\'gbk\')).decode(type)
url = \'https://image.baidu.com/search/flip?tn=baiduimage&ie=utf-8&word=\'+word+\'&pn=0\'
request = urllib2.Request(url)
response = urllib2.urlopen(request)
page = response.read()
pattern = re.compile(\'"objURL":"(.*?)",\', re.S)
items = re.findall(pattern, page)
path = word
#判斷路徑是否存在
#存在為True 不存在為False
isExists = os.path.exists(path)
if not isExists:
#如果不存在則建立目錄
print u"建立了名為", path, u"的檔案夾"
#建立目錄操作函數
os.makedirs(path)
else:
#如果目錄存在則不建立,并提示目錄已存在
print u"名為", path, u"的檔案夾已存在"
i = 1
for item in items:
# print u"第"+str(i)+u"張圖檔位址"
# print item
# i += 1
try:
u = urllib2.urlopen(item, timeout=20)
except urllib2.URLError, e:
print e.reason
continue
data = u.read()
name = path + "/" + word + str(i) + ".jpg"
f = open(name, \'wb\')
f.write(data)
print u"正在儲存圖檔為", name, u"圖檔位址為:", item
f.close()
i += 1
test
6.完善代碼并封裝
#-*- coding:utf-8 -*-
import urllib2
import re
import sys
import os
import time
import socket
class Spider:
def __init__(self, keyword):
self.siteURL = \'https://image.baidu.com/search/flip?tn=baiduimage&ie=utf-8&word=\' + keyword
self.i = 1
def getPage(self, pageIndex):
page = (pageIndex-1)*20
url = self.siteURL + "&pn=" + str(page)
headers = {\'User-agent\':\'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.89 Safari/537.36\'}
sleep_download_time = 10
try:
time.sleep(sleep_download_time)
request = urllib2.Request(url, headers=headers)
response = urllib2.urlopen(request)
except urllib2.URLError, e:
print e.reason
except socket.timeout, e:
print u"timeout"
return response.read().decode(\'utf-8\')
def getContents(self, pageIndex, keyword):
page = self.getPage(pageIndex)
pattern = re.compile(\'"objURL":"(.*?)",\', re.S)
items = re.findall(pattern, page)
self.mkdir(keyword)
for item in items:
try:
name = keyword + "/" + keyword + str(self.i) + ".jpg"
self.saveImg(item, name)
self.i += 1
except urllib2.URLError, e:
print e.reason
except socket.timeout, e:
print u"timeout"
continue
#建立新目錄
def mkdir(self, path):
path = path.strip()
#判斷路徑是否存在
#存在為True 不存在為False
isExists = os.path.exists(path)
if not isExists:
#如果不存在則建立目錄
print u"建立了名為", path, u"的檔案夾"
#建立目錄操作函數
os.makedirs(path)
return True
else:
#如果目錄存在則不建立,并提示目錄已存在
print u"名為", path, u"的檔案夾已存在"
return False
#儲存圖檔到檔案夾
def saveImg(self, imageURL, fileName):
u = urllib2.urlopen(imageURL)
data = u.read()
f = open(fileName, \'wb\')
f.write(data)
print u"正在儲存圖檔為", fileName, u"圖檔位址為:", imageURL
f.close()
#傳入起止頁碼,擷取圖檔
# def savePagesInfo(self, start, end):
# for i in range(start,end+1):
# print u"正在查找第",i,u"個地方"
# self.getContents(i, self.title)
# 設定編碼
reload(sys)
sys.setdefaultencoding(\'utf-8\')
# 獲得系統編碼格式
type = sys.getfilesystemencoding()
word = raw_input("請輸入關鍵字: ".decode(\'utf-8\').encode(\'gbk\')).decode(type)
timeout = 20
socket.setdefaulttimeout(timeout)#這裡對整個socket層設定逾時時間。後續檔案中如果再使用到socket,不必再設定
spider = Spider(word)
spider.getContents(1, word)