本篇目标
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
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)