妹子图网站爬虫实现
具体流程
①确定所要爬取的网站的url:http://www.mzitu.com/all/。爬取妹子图网站的方便之处在于它在每日更新页面里包含了所有年份月份的链接。所以我们下一步我们只需要获取所有的链接即可。
②获取第一步中确定的url中的页面源码。从源码可以找到所有”妹子“的图片详情页的链接。
③获取所有”妹子“的图片详情页链接。
④迭代获取所有的图片详情页链接的源码。在详情页中我们可以找到所有与当前妹子相关的所有图片。细心的话我们可以发现,每张图片的页面url就差一个数字,该数字就是第几张图片。所以下一步我们需要在详情页源码中获取图片总数以及当前页面的图片的url即可。
⑤获取所有详情页源码中的图片总数,根据图片总数获取所有图片url。
⑥剩下的就是下载所有图片。
爬取流程图
注意事项
①使用图片url爬取图片时站主使用了防盗链,所以请求url时必须设置headers,headers要设置User-Agent和Referer,Referer可以设置是主页面。
②保存图片时,图片文件的访问模式是”wb“。
③在为每个妹子创建文件夹来保存她们自己的图片时,如果用中文作为文件夹的名字的话,必须给名字做编码转换,先解码,再编码成gbk格式,这样的话文件夹名字才不会乱码。
代码
# _*_ coding: utf-8 _*_
import os, sys
import urllib2, urllib
import re
import requests
class MZTU:
'妹子图图片爬虫'
def __init__(self):
self.first_url = 'http://www.mzitu.com/all/'
self.root = os.getcwd()
self.base_path = self.root+'\\'+'meizipics'
self.user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36'
self.referer = 'http://www.mzitu.com/all/'
self.headers = {'User-Agent': self.user_agent, 'Referer': self.referer}
isExist = os.path.exists(self.base_path)
if not isExist:
os.makedirs(self.base_path)
print '根目录创建成功!'.decode('utf-8').encode('gbk')
else:
print '根目录已经存在!'.decode('utf-8').encode('gbk')
def getPage(self, url):
try:
req = urllib2.Request(url)
res = urllib2.urlopen(req)
return res.read()
except URLError, e:
if hasattr(e, 'reason'):
print '网页获取失败,原因:', e.reason
return None
else:
print '网页获取失败,原因:', e
return None
def getAllLinks(self, pageCode):
if not pageCode:
return None
content_pt = re.compile(r'<p class="url.*?>(.*?)</p>', re.S)
contents = re.findall(content_pt, pageCode)
url_name_pt = re.compile(r'<a href="(.*?)".*?>(.*?)</a>', re.S)
url_name = []
for content in contents:
urlnames = re.findall(url_name_pt, content)
for urlname in urlnames:
url_name.append([urlname[0].strip(), urlname[1].strip()])
if len(url_name) == 0:
return None
else:
return url_name
def getPageNum(self, pageCode):
if not pageCode:
return None
num_pt = re.compile(r'<span class=\'dots\'.*?<span>(.*?)</span>', re.S)
num = re.search(num_pt, pageCode)
if not num:
return None
else:
return num.group(1)
def getImgUrl(self, pageCode):
if not pageCode:
return None
img_pt = re.compile(r'<div class="main-image.*?<img src="(.*?)"', re.S)
img_url = re.search(img_pt, pageCode)
if not img_url:
return None
else:
return img_url.group(1)
def getExtension(self, imgUrl):
if not imgUrl:
return None
extension = imgUrl.split('.')[-1]
return extension
def saveImg(self, url, file_path, img_name, extension='jpg'):
# r = requests.get(url, headers = self.headers)
req = urllib2.Request(url, headers=self.headers)
res = urllib2.urlopen(req)
file_path = file_path.decode('utf-8').encode('gbk')
file_name = self.base_path + '\\' + file_path + '\\' + img_name + '.' + extension
# print file_name
try:
f = open(file_name, 'wb')
f.write(res.read())
except IOError, e:
if hasattr(e, 'reason'):
print '下载图片失败,原因:', e.reason
else:
print '下载图片失败,原因:', e
finally:
f.close()
# print r.content
def createDir(self, name):
name = name.decode('utf-8').encode('gbk')
file_dir = self.base_path + '\\' + name
isExist = os.path.exists(file_dir)
if not isExist:
os.makedirs(file_dir)
print '创建 %s 目录成功!'.decode('utf-8').encode('gbk') % (name)
else:
print '%s目录已存在'.decode('utf-8').encode('gbk') % (name)
def start(self):
main_page = self.getPage(self.first_url)
if not main_page:
print '获取妹子图主页面失败!'.decode('utf-8').encode('gbk')
return
else:
print '获取妹子图主页面成功!'.decode('utf-8').encode('gbk')
alllinks = self.getAllLinks(main_page)
if not alllinks:
print '获取妹子图所有链接失败!'.decode('utf-8').encode('gbk')
return
else:
print '获取妹子图所有链接成功!'.decode('utf-8').encode('gbk')
print '\n-------------------------------------------------------------------'
for link_name in alllinks[:5]:
detail_link = link_name[0]
file_path = link_name[1]
# print file_path
# continue
detail_page = self.getPage(detail_link)
if not detail_page:
print '获取****%s****页面失败!'.decode('utf-8').encode('gbk') % (file_path.decode('utf-8').encode('gbk'))
return
else:
print '获取****%s****页面成功!'.decode('utf-8').encode('gbk') % (file_path.decode('utf-8').encode('gbk'))
self.createDir(file_path)
imgnum = self.getPageNum(detail_page)
if not imgnum:
print '获取图片总数失败!'.decode('utf-8').encode('gbk')
return
else:
print '获取图片总数成功!共%s张'.decode('utf-8').encode('gbk') % (imgnum)
for i in range(1, int(imgnum)+1):
link = detail_link + '/' + str(i)
img_page = self.getPage(link)
if not img_page:
print '获取第**%d**张图片页面失败!'.decode('utf-8').encode('gbk') % (i)
return
else:
print '获取第**%d**张图片页面成功!'.decode('utf-8').encode('gbk') % (i)
img_url = self.getImgUrl(img_page)
if not img_url:
print '获取图片url失败!'.decode('utf-8').encode('gbk')
return
else:
print '获取图片url成功!'.decode('utf-8').encode('gbk')
extension = self.getExtension(img_url)
self.saveImg(img_url, file_path, str(i), extension)
print '第**%d**张图片下载成功!\n'.decode('utf-8').encode('gbk') % (i)
print '-------------------------------------------------------------------'
if __name__ == '__main__':
mzitu = MZTU()
mzitu.start()