这次打算使用urllib来着,因为作为小白并没有发现urllib与request的区别,想到requests还要安装,不如用自带的urllib.
但在使用的过程中发现设置urllib每次都要手动设置抓取内容的编码,于是继续用requests
基本逻辑为
- 爬取网站首页,获得所有类型
- 遍历爬取类型页面,获得该类型下所有页数
- 遍历页数爬取每页所有套图封面
- 遍历该列表页每个套图页,获取图片[根据规则拼接图片网址]
# -*- coding UTF-8 -*-
import requests
import re
import os
class Craw(object):
"""docstring for Craw"""
baseurl=r"http://www.mm131b.com/"
type_name=''
type_count=1
page_count=1
group_count=1
group_path=''
imgdir="mm/"
init=True
def __init__(self):
super(Craw, self).__init__()
self.main()
#处理分类页
def types(self,type_name):
print (r"读取%s类型"%(type_name))
if not os.path.exists(self.imgdir+type_name):
os.makedirs(self.imgdir+type_name)
self.type_name=type_name
typeurl=self.baseurl+type_name
type_content=requests.get(typeurl).text
# 获取该分类下的页数
max_page=re.findall(r"(?<=<strong>)(\d)",type_content)[0]
if self.init==False:
self.page_count=1
while self.page_count<=int(max_page):
self.lists()
self.type_count+=1
#处理列表页
def lists(self):
print(r"处理%s类型第%d页"%(self.type_name,self.page_count))
url=self.baseurl+self.type_name+"/list_%d_%d.html"%(self.type_count,self.page_count)
#创建列表页文件夹
self.group_path="%s%s%s%d%d"%(self.imgdir,self.type_name,"/",self.type_count,self.page_count)
if not os.path.exists(self.group_path):
os.makedirs(self.group_path)
list_page=requests.get(url)
#处理编码
list_page.encoding="gbk"
# 0 链接 2 标题 4 封面图地址
lists = re.findall(r"(?<=href=\"\/)(.+?)(\".+?pic\sshow\"\stitle=\")(.+?)(\".+?scrollLoading.+?xSrc=\")(.+?.jpg)(\")",list_page.text)
if self.init==False:
self.group_count=0
# print(lists);
# exit()
for k,v in enumerate(lists):
if k<self.group_count:
print("跳过第%d组套图,历史目标%d组"%(k,self.group_count))
continue
self.group(v)
self.page_count+=1
#处理套图页
def group(self,i):
self.group_count+=1
self.init=False
print("处理套图<%s>"%(i[2]))
img=requests.get(i[4])
if(img.status_code!=200):
print("套图<%s>加载失败,跳过"%(i[2]))
return
name="%d%d%d"%(self.type_count,self.page_count,self.group_count)
#封面图
with open(self.group_path+"/"+name+i[2]+".jpg","wb") as f:
f.write(img.content)
f.close()
imgs=requests.get(self.baseurl+i[0])
imgs.encoding="gbk"
img_count=1
#利用图片地址规则构建单张图片页 本来是用抓取的单页地址解析
#后来发现图片多的会隐藏一部分,并且select虽然全但是js添加的,无法抓到
#图片地址格式 数字_序号 如23201_2 首图无序号 即 23201
img_code=re.findall(r"^.+(?=\.html)",i[0])
while True:
#非首图
if img_count!=1:
imgs=requests.get("%s%s%s%d%s"%(self.baseurl,img_code[0],"_",img_count,".html"))
#通过返回长度判断是否跳转 (即已经没有更多图片 跳转回首页了)
if(int(imgs.headers['Content-Length'])<200):
# print("%s%s%s%d"%(self.baseurl,img_code[0],"_",img_count))
print("<%s>套图下载完成,共%d张"%(i[2],img_count))
return
#提取图片地址
img=re.findall(r"src=[\'|\"](.+?)[\'|\"]\salt=[\'|\"]",imgs.text)
if(not img):
print("套图<%s>含有无效图片,跳过"%(i[2]))
return
#保存图片
img=requests.get(img[0])
with open(self.group_path+"/%s%d%s"%(name,img_count,".jpg"),"wb") as f:
f.write(img.content)
f.close()
#记录当前执行位置
with open(self.imgdir+"log.log","w") as f:
# type,page,group
f.write("%d,%d,%d"%(self.type_count,self.page_count,self.group_count))
f.close()
img_count+=1
#主函数
def main(self):
#爬到一定数量后会报错连接过多
#解决这一问题
s = requests.session()
s.keep_alive = False
#重试次数上限
requests.adapters.DEFAULT_RETRIES = 15
main_content = re.findall(r"(?<=href\=\'\/)\w+(?=\/\'\s)",requests.get(self.baseurl).text)
#读取之前记录 从上次执行的记录继续执行
with open(self.imgdir+"log.log",'a+') as f:
f.seek(0)
log=f.read()
if log :
log=log.split(',')
self.type_count=int(log[0])
self.page_count=int(log[1])
self.group_count=int(log[2])
f.close()
#该网站的列表页规则为 list_1_1 第一个1是分类 第二个1是页码
#对于不存在的会自动跳转回首页
for k,v in enumerate(main_content):
if k+1 < self.type_count:
continue
self.types(v)
Craw()
转载于:https://blog.51cto.com/8292516/2069214