福利图片

Python爬虫小实践:下载妹子图www.mzitu.com网站上所有的妹子图

字号+ 作者:蜘蛛侠 来源:网络整理 2018-04-01 16:11 我要评论( )

Python爬虫小实践:下载妹子图www.mzitu.com网站上所有的妹子图

Python爬虫小实践:下载妹子图www.mzitu.com网站上所有的妹子图

当初学Python进一个Python学习群,不久之后群主大大就发了自己写的一个爬虫,就是爬取网站上的妹纸图片,看完之后,惊为天人,一脸懵逼,觉得群主大大好厉害,当初自己进群的初衷以及学Python的初衷就是为了做爬虫,然后慢慢的开始。所以说这次,就是为了实践一下,爬取这个网站上的所有的图片,别邪恶哦,虽然是隐藏福利,我只是为了写爬虫实践,我只是为了写爬虫实践,我只是为了写爬虫实践!!!


网络爬虫会给网站服务器造成巨大负荷,所以,本次实践的源码仅供参考交流,不宜用于商业应用,由此造成的任何法律责任本人不予承担。


为了得到这个网站上所有的妹子图片,就得分析网站的架构,通过分析发现这个网址下有2013-2017年网站上所有的相册的链接,所以准备通过以下步骤爬取网站上的所有图片。


第1步:在下获取所有的相册的链接以及相册的名字

第2步:根据每个相册的链接得到每个相册每一个图片页面的链接

第3步:根据每一个图片的链接得到每一张图片的名字以及图片链接


第一步:下获取所有的相册的链接以及相册的名字

分析网站源码,查看每一个相册链接以及名字的所处标签

Python爬虫小实践:下载妹子图www.mzitu.com网站上所有的妹子图

Python爬虫小实践:下载妹子图www.mzitu.com网站上所有的妹子图


由图上可以看出,每一个相册的链接以及名称都位于<a >标签下


第二步:根据每个相册的链接得到每个相册每一个图片页面的链接

通过分析网站源码,分析每一个相册下每一个图片页面的链接

Python爬虫小实践:下载妹子图www.mzitu.com网站上所有的妹子图

Python爬虫小实践:下载妹子图www.mzitu.com网站上所有的妹子图



通过分析,发现每一个图片页面链接都处于<div>的<a herf>下,但是只有几个图片的页面的链接,如上图所示,分别只有2,3,4.......65,但是图片页面的规律是相册链接+"/"+页面编号,在这里我们得到最大的页面编号65,就可以通过循环得到每一个图片页面的链接,所以在这里通过字符选取将编号压入进一个list,然后通过max方法得到最大编号,得到每一个相册图片页面的链接。


第三步:根据每一个图片的链接得到每一张图片的名字以及图片链接

根据以上得到的图片页面链接,在每个页面内爬取图片的下载链接以及图片的名称

Python爬虫小实践:下载妹子图www.mzitu.com网站上所有的妹子图

Python爬虫小实践:下载妹子图www.mzitu.com网站上所有的妹子图


通过分析,图片链接以及名称都位于<img>标签内


通过以上的分析,将整个流程写为Python代码,在其中使用了第三方包Beautifulsoup,现附上全部代码,如有错误,请指教


#得到妹子图网站所有图片,输入网址为 #__author__ = 'Administrat #coding=utf-8 import io import os import sys import math import urllib from urllib.request import urlopen from urllib.request import urlretrieve from urllib import request from bs4 import BeautifulSoup import re import requests import time import socket from collections import OrderedDict socket.setdefaulttimeout(5000)#设置全局超时函数 sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='gb18030') #设置不同的headers,伪装为不同的浏览器 headers1={'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20100101 Firefox/23.0'} headers2={'User-Agent':'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36'} headers3={'User-Agent':'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11'} #在指定路径创建文件夹 def CreateDirectory(DirectoryName): DirectoryNameNew=[]#创建新的存储列表 if DirectoryName=="":#如果传进来的文件夹名为空 DirectoryNameNew="新建文件夹" for l in DirectoryName:#如果文件夹名不为空,剔除其中的“/” if l!="/" and l !="\\": DirectoryNameNew.append(l) root="E:\\Python\\Python妹子图\\" path=root+"".join(DirectoryNameNew)#join将列表转为为字符串 print("创建相册"+root+"".join(DirectoryNameNew)) try: os.makedirs(path) except Exception as e: print(root+"".join(DirectoryNameNew)+"已经存在") return path #得到这个网址所有的相册的链接 #site为站点网址,默认为 def GetXiangceUrl(siteUrl): #设置代理IP访问 #代理IP可以上获取 proxy_handler=urllib.request.ProxyHandler({'post':'210.136.17.78:8080'}) proxy_auth_handler=urllib.request.ProxyBasicAuthHandler() opener = urllib.request.build_opener(urllib.request.HTTPHandler, proxy_handler) urllib.request.install_opener(opener) #抓捕解析网站过程中的错误 try: #time.sleep(1) req=request.Request(siteUrl,headers=headers1 or headers2 or headers3) #req=request.Request(siteUrl,headers=headers.items(1)) html=urlopen(req) bsObj=BeautifulSoup(html.read(),"html.parser") html.close() except UnicodeDecodeError as e: print("-----UnicodeDecodeError url",siteUrl) except urllib.error.URLError as e: print("-----urlError url:",siteUrl) except socket.timeout as e: print("-----socket timout:",siteUrl) i=0 XiangceZidian=OrderedDict()#声明字典,并排序 print("正在连接到网站"+siteUrl) for templist in bsObj.findAll("a",href=re.compile("http://www.mzitu.com/([0-9]+)")):#正则匹配相册链接标签 i=i+1 xiangceUrl = templist.attrs['href'] xiangceName =str(i)+" "+templist.get_text() #print(str(i)+" "+xiangceName+" "+xiangceUrl) #XiangceUrl=str(i)+" "+xiangceName+" "+xiangceUrl XiangceZidian[xiangceName]=xiangceUrl #XiangceZidianNew=OrderedDict(XiangceZidian) return XiangceZidian #返回相册名称:相册链接字典 #获取当前相册内所有的图片页面链接 #xiangceurl为相册链接 def GetXiangcePageUrl(xiangceurl): #抓捕解析网站中的错误 #设置代理IP访问 proxy_handler=urllib.request.ProxyHandler({'post':'223.18.181.240:8380'}) proxy_auth_handler=urllib.request.ProxyBasicAuthHandler() opener = urllib.request.build_opener(urllib.request.HTTPHandler, proxy_handler) urllib.request.install_opener(opener) try: #time.sleep(1) req=request.Request(xiangceurl,headers=headers1 or headers2 or headers3) #req=request.Request(xiangceurl,headers=headers.items(2)) html=urlopen(req) bsObj=BeautifulSoup(html.read(),"html.parser") html.close() except UnicodeDecodeError as e: print("-----UnicodeDecodeError url",xiangceurl) except urllib.error.URLError as e: print("-----urlError url:",xiangceurl) except socket.timeout as e: print("-----socket timout:",xiangceurl) bianhaolist=[]#声明页面编号list,为的是找出这个页面中最大的页面编号 XiangCePageUrlList=[]#存储该网页下所有的相册链接 print("正在连接到"+xiangceurl+",并解析该链接的页面链接") if bsObj !="": for pagelist in bsObj.findAll("div",{"class":"pagenavi"}): for link in pagelist.findAll("a",href=re.compile("http://www.mzitu.com/([0-9]+)/([0-9]+)*$")):#正则匹配相册链接 lianjie=link.attrs['href'] #print(link.attrs['href']) bianhao=lianjie.replace(xiangceurl+"/", "")#得到编号 #print(bianhao) bianhaolist.append(int(bianhao))#添加到编号列表 bianhaoMax=max(bianhaolist)#找到图片链接最大编号 for i in range(1,bianhaoMax+1): XiangCePageUrl=xiangceurl+"/"+str(i)#得到每个相册的图片的链接 #print(XiangCePageUrl) XiangCePageUrlList.append(XiangCePageUrl) return XiangCePageUrlList#返回图片链接列表 #得到当前页面的图片链接 #XiangCePageUrl为当前相册某个页面的链接,path为文件夹路径,replaceurl为相册的链接 def GetPageImageUrl(XiangCePageUrl,path,replaceurl): #设置代理IP访问 proxy_handler=urllib.request.ProxyHandler({'https':'111.76.129.200:808'}) proxy_auth_handler=urllib.request.ProxyBasicAuthHandler() opener = urllib.request.build_opener(urllib.request.HTTPHandler, proxy_handler) urllib.request.install_opener(opener) try: #time.sleep(1) req=request.Request(XiangCePageUrl,headers=headers1 or headers2 or headers3) #req=request.Request(XiangCePageUrl,headers=) html=urlopen(req) bsObj=BeautifulSoup(html.read(),"html.parser") html.close() bianhao=XiangCePageUrl.replace(replaceurl+"/", "")#这里的编号每个相册图片的编号,例如XXXX1.jpg print("path:"+path) for templist in bsObj.findAll("div",{"class":"main-image"}):#寻找图片链接以及名称 for ImageUrllist in templist.findAll("img"): #print(ImageUrllist.attrs['src']) Imageurl=ImageUrllist.attrs['src']#图片链接 print(XiangCePageUrl+"的图片链接为"+Imageurl) #print(ImageUrllist.attrs['alt']) ImageName=ImageUrllist.attrs['alt']#图片名称 ImageNameNew=[]#新的图片名称列表,为了剔除原有名称中包含的"/"符号 for l in ImageName: if l!="/" and l!=" " and l !="\\" and l !=".": ImageNameNew.append(l) if len(ImageNameNew) !=0: print("正在下载文件:"+str(path)+"\\"+"".join(ImageNameNew)+str(bianhao)+".jpg")#join将列表转为字符串 try: urlretrieve(Imageurl,str(path)+"\\"+"".join(ImageNameNew)+str(bianhao)+".jpg",jindu)#下载图片,并调用回调函数jindu()显示下载进度 print("myper="+str(myper)) while(True==jindu):#判断是否下载完成 print("下载完成!") print('') #time.sleep(1)#下载完成后sleep3秒,防止反爬虫机制 break; #else: #time.sleep(10)#如果失败,先休眠10秒 #urlretrieve(Imageurl,str(path)+"\\"+"".jion(ImageNameNew)+str(bianhao)+".jpg",jindu)#再下载,直到下载完成 #time.sleep(3) except Exception as e: time.sleep(10)#如果失败,先休眠10秒 #urlretrieve(Imageurl,str(path)+"\\"+"".jion(ImageNameNew)+str(bianhao)+".jpg",jindu)#再下载,直到下载完成 #print("下载链接"+Imageurl+"出错,重新下载") #time.sleep(3) except UnicodeDecodeError as e: print("-----UnicodeDecodeError url",XiangCePageUrl) except urllib.error.URLError as e: print("-----urlError url:",XiangCePageUrl) except socket.timeout as e: print("-----socket timout:",XiangCePageUrl) print("正在获取"+XiangCePageUrl+"的图片链接") #urlretrieve()的回调函数,显示当前的下载进度 #a为已经下载的数据块 #b为数据块大小 #c为远程文件的大小 global myper def jindu(a,b,c): if not a: print("连接打开") if c<0: print("要下载的文件大小为0") else: global myper per=100*a*b/c if per>100: per=100 myper=per print("myper0="+str(myper)) print("当前下载进度为:"+'%.2f%%'% per) if per==100: return True #GetXiangceUrl("http://www.mzitu.com/all") #GetXiangcePageUrl("http://www.mzitu.com/85695") #GetPageImageUrl("http://www.mzitu.com/85695/2","E:\Python\Python妹子图","http://www.mzitu.com/85695") if __name__ == '__main__': XiangCe=GetXiangceUrl("http://www.mzitu.com/all")#返回字典,并将返回字典排序 for xiangceurllist in XiangCe.keys(): print("相册名字"+xiangceurllist)#相册名字 #print(XiangCe.get(xiangceurllist))#相册链接 mypath=CreateDirectory(xiangceurllist) #print(mypath) XiangCePageUrl=GetXiangcePageUrl(XiangCe.get(xiangceurllist)) #time.sleep(1) #print(XiangCePageUrl) for xiangcepageurllist in XiangCePageUrl: #print(xiangcepageurllist) #print(XiangCePageUrl.index(xiangcepageurllist)) GetPageImageUrl(xiangcepageurllist,mypath,XiangCe.get(xiangceurllist)) time.sleep(1)




刚刚开始写的时候,会遇到服务器断开链接,以及主机在一定时间内无法连接的错误,在百度上,谷歌上看了半天,可能是由于网站的反爬虫机制,我自己的解决办法如下,不知道你们可不可行:

1、关闭windows防火墙,爬完再开

2、采用多headers,伪装不同的浏览器

3、每下载完,sleep一下,减缓访问网站的频率,如果过快,网站服务器会认为你是爬虫

4、设置全局超时时间,有时候因为网速的问题会出现这种情况

5、设置代理IP


刚刚开始不知道为什么这个网站不能用代理IP访问,一访问,网站服务器就强制断开连接,后来又可以了,尽量用代理IP,免得被封IP,代理ip网站可上查询


在这个代码中,没有采用多线程机制,所以爬起来比较慢,勿喷。

最好在晚上爬,网速快。


爬取结果(隐藏福利):

Python爬虫小实践:下载妹子图www.mzitu.com网站上所有的妹子图


转载请注明出处。

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • 用图片反映“实践勤政清廉精神”

    用图片反映“实践勤政清廉精神”

    2018-07-03 23:12

  • 福利来了!烟台131处场馆免费向中小学生开放

    福利来了!烟台131处场馆免费向中小学生开放

    2018-04-30 01:47

  • 运用 Redis 构建分布式爬虫,抓妹子图

    运用 Redis 构建分布式爬虫,抓妹子图

    2018-04-20 13:41

  • 妹子图网爬虫实战

    妹子图网爬虫实战

    2018-04-14 05:37

网友点评