Python爬虫学习之爬美女图片
最近看机器学习挺火的,然后,想要借助业余时间,来学习Python,希望能为来年找一份比较好的工作。
首先,学习得要有动力,动力,从哪里来呢?肯定是从日常需求之中来。我学Python看网上介绍。能通过Python来编写爬虫,于是,我也的简单的看了一下Python的介绍,主要是Python的一些语法,还有正则表达式。
好了,学习使用Python之前,来给大家看一下我们需要进行爬去的网站:
看到这个网站,感谢美女很养眼的同时,网站的图片也不太过,就是比较性感而已。看到这个多的美女,你想不想要将这些爬取到的美女,保存在你的硬盘,或者保存在你的网站,增加流量呢?
好了,目标网站有了,接下来,我们直接真刀真枪的直接开干吧。
考虑到,有很多和我一样的小白,我暂时,不介绍使用Pyspider来做爬虫,我们就使用Python的一些库来做爬虫,一步一步的进阶。
接下来需要大家安装一个IDE来编写Python脚本,我给大家推荐Pycharm编辑器。
恩,接下来直接上代码了,做好准备了没?
第一步:解析美女类别:
if __name__ == "__main__": # page = 8 url = "http://www.mmjpg.com/" base_url = urlparse(url) #url = "http://cuiqingcai.com/1319.html" #menu = getallAltls(url) ##menu = getparAltls(url, page) #url = "http://www.mmjpg.com/tag/tgod" path = r"E:\image" #path = path + "\\" + "推女神" craw = Crawler() soup = craw.doc(craw.getHtml(url)) total = 0 for each in soup(soup(".subnav")('a[href^="http://www.mmjpg.com/tag"]')).items(): utils.log( "即将下载: " + each.text() + each.attr('href') ) path= r"E:\image" path = path + "\\" + each.text() utils.log( "即将存放在:" + path ) total += 1 if total<=11: # continue pass else: param={"url":each.attr('href'),"path":path} craw.downimgofsite(param )
第二步:下载站点某图集下的所有图片:
def downimgofsite(self , param): url = "" path = "" #path = str(path) if param and "url" in param: url = param["url"] utils.log( "即将下载:" + url) else: utils.log( "线程运行错误,url为空") return if param and "path" in param: path = param["path"] utils.log( "即将保存路径:" + path) else: utils.log( "线程运行错误,路径为空" ) return #获取所有图集的名称和链接 meun_list = self.getallAltls(url) total = 0 directorypath = "" #print os.getcwd() try: for meun in meun_list: try: directoryname = self.str_fomat(meun[0]) if not directoryname: utils.log("获取到的图集为空" + str(directoryname)) continue if path.strip() != "": directorypath = path + "\\" + directoryname else: directorypath = os.getcwd() + "\\" + directoryname if not os.path.exists(directorypath): os.makedirs(directorypath) utils.log( "图集 "+ meun[0]+ " 创建路径:" + directorypath ) utils.log("正在下载第 "+ str(total) + "个图集:" + meun[0] + " 链接:" + url) result = self.getSinglePic(meun[1], directorypath) total += 1 except IOError, param: utils.log("图集:"+ meun[0] +"IO读写错误,原因"+ param) continue except BaseException,param: utils.log("图集:"+ meun[0] + "产生意外错误") continue except: utils.log("图集:"+ meun[0] + "产生意外错误,原因:" + param) continue try: if result: utils.log( "图集:" + meun[0] + " 获取链接:" + meun[1] +" 成功,共下载:" + str(result) + " 张图片" ) else: os.rmdir(directorypath) utils.log( "图集:" + meun[0] + " 获取链接:" + meun[1] +" 失败,即将删除目录:" + directoryname ) #self.cleanDir(directorypath) except WindowsError,parm: utils.log( "操作目录:"+ directoryname + "失败,原因:"+ parm ,logging.ERROR) continue except BaseException,parm: utils.log( "发生错误,错误原因:"+ parm ,logging.ERROR) continue except: utils.log( "发生未知错误" ,logging.ERROR) continue except BaseException,parm: utils.log( "下载站点图片出错,错误原因:" + parm ,logging.ERROR)
获取所有图集:
#function获取所有的图集名称 def getallAltls(self,url): html =self.getHtml(url) if not html: utils.log("获取网页:"+ url +"错误,错误原因:没有获取到网页") return None soup = self.bfs(html) totalpage = int(self.getPageNum(html ,url)) meun = self.getPicNameandLink(url) album_id = re.search( r'\d+', url, re.M|re.I) if not album_id: album_id = str(int(random.random() * 10000)) albm_url = url album_create_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) album_name = soup.find("div",class_="current").find("i").string #循环遍历所有的图集页面,获取图集名称和链接 for pos in range(2,totalpage+1): currenturl = url + "/" + str(pos) #getPicNameandLink()返回的值是一个list。 #当一个list插入到另一个list中时,使用extend。 #若是插入一个值时,可以用append tmenu = self.getPicNameandLink(currenturl) if tmenu: meun.extend(tmenu) utils.log("从链接:" + url +"获取到" + str(len(tmenu)) + "链接") else: utils.log("获取链接:"+ url + "图集失败") # url = nextpage = self.getNextPage(url) # meun.extend(self.getPicNameandLink(nextpage)) return meun
获取整个图集的所有页码:
# 获取整个图集的页码 def getPageNum(self , html , url): soup = self.bfs( html) # 直接在站点首页获取所有图集的总页码 #nums=soup.find_all('a',class_='page-numbers') # 除掉“下一页”的链接,并获取到最后一页 #totlePage = int(nums[-2].text) p = r'共\d+?页' #print soup.get_text() pa = re.compile(p.encode('utf-8')) match = re.search(pa, soup.get_text().encode("utf-8")) if match: ct = re.sub(r'\D','', match.group(0)) if not ct: utils.log( " + "页,总页面查找失败" ) return 1 utils.log( "链接: "+ url + " 页面共:" + str(ct) + "页") totlePage = int(ct) print totlePage return totlePage else: utils.log( " + "页,总页面查找失败" ) return 1
获取指定图集下图集名称和链接:
#获取指定页面下图集名称和链接 def getPicNameandLink(self , url): html = self.getHtml(url) if html: soup = self.bfs( html) else: utils.log("链接:" + url + " 请求失败" + "网页:") utils.log(str(html)) return None soup = self.bfs(html) meun = [] total = 1 link_list = soup.find("div", class_="pic").find_all('a' ,target="_blank") #+ soup.find_all('img' ,target="_blank") #print type(link_count) link_count = len(link_list) #print type(link_count) utils.log("在链接:"+ url+ "下找到: "+ str(link_count) + " 链接") if(link_count > 0): for pic in link_list: link = pic["href"] self.links.append(link) picturename = "" img = pic.find("img") if img: # 保证中文字符能够正常转码。 picturename = unicode(str(img["alt"])) self.title.append(picturename) else: continue #插入图集名称和对应的url meun.append([picturename,link]) ids=self.get_url_page(url) if ids: self.ids.append(ids) else: self.ids.append(total) total += 1 utils.log( "在链接:" + url +" 下实际找到:" + str(len(meun)) + "个链接") return meun else: return None
获取下一页:
#获取下一页的链接 def getNextPage(self , url): base_url = urlparse(url) html = self.getHtml(url) if html: soup = self.bfs( html) else: utils.log("链接:" + url + " 请求失败" + "网页:") utils.log(html) return None nt = "下一页" next_url = soup.find_all('a',text=nt) ret_url= next_url[0]['href'] #print ret_url if ret_url: try: if re.match(r'^https?:/{2}\w.+$', ret_url): utils.log( "获取到正确的网址:" + ret_url) return ret_url else: ret_url = base_url.scheme +"://"+ base_url.netloc + next_url[0]['href'] utils.log("只获取到查询路径,处理之后网址为:"+ ret_url) return ret_url except BaseException, Argument: utils.log("查找下一页出错,错误为:"+Argument ,logging.ERROR) return None else: print "获取下一页地址失败!" return None
第三部:获取某一个妹子的所有图片:
#下载单个相册中的所有图片 def getSinglePic(self , url , path): title = re.split(r'\\', path) title = title[-1] try: page_url = self.getSinglePicUrl(url) if page_url: totalPageNum = self.getSinglePicTotal(url) base_url = urlparse(url) real_url =base_url.scheme+"://"+base_url.netloc #从第一页开始,下载单个图集中所有的图片 #range()第二个参数是范围值的上限,循环时不包括该值 #需要加1以保证读取到所有页面。 p = r'.+\/' pa = re.compile(p) #print title if totalPageNum: for i in range(1,totalPageNum + 1): currenturl = real_url + "/" + str(i) self.downloadpic(currenturl,path) else: next_url = self.getSinglePicUrl(url) cur_page = 1 utils.log("即将下载图集:" + title) while next_url: match = re.search(pa, next_url).group(0) if match: currenturl = real_url+ "/" + match + str(cur_page) else: currenturl = real_url+ "/" + next_url # + str(cur_page) #utils.log("正在下载: "+ str(cur_page) + " 个图片:" +" 链接:"+ url ) self.downloadpic(currenturl,path) cur_page += 1 next_url = self.getSinglePicUrl(currenturl) #判断是否还有下一页 # if cur_page > 2: # return cur_page return (cur_page-1) else: utils.log( "图集:"+ title+ "链接:" + url +" 获取图片链接失败") return None except BaseException,param: utils.log( "下载单个相册:" + title + " 链接:" + url+ "中的所有图片异常,原因:" + param ,logging.ERROR) return None except: utils.log( "下载单个相册:" + title + " 链接:" + url+ "中的所有图片异常" ,logging.ERROR) return None
#获取单个相册内图片链接 def getSinglePicUrl(self , url): html = self.getHtml(url) if html: soup = self.bfs( html) else: utils.log("链接:" + url + " 请求失败" + "网页:") utils.log(html) return None try: if soup: #print "当前页面链接:"+ url nt = "下一张" next_url = soup.find_all('a',text=nt) if next_url: ret_url= next_url[0]['href'] else: return None else: utils.log( "网页" + url + "读取失败") return None except BaseException,param: utils.log( "获取单个相册内图片链接异常,原因" + param ,logging.ERROR) return None return ret_url
获取图片数量:
#获取单个相册内图片所有图片的数量 def getSinglePicTotal(self , url): html = self.getHtml(url) if html: soup = self.bfs( html) else: utils.log("链接:" + url + " 请求失败" + "网页:") utils.log(html) return None #pagenavi还是一个对象(Tag),可以通过find_all找出指定标签出来 #print "当前页面链接:"+ url if soup: #print "获取链接:"+url +" 成功" pass else: utils.log("获取链接:"+url +" 失败") return None nt = "全部图片" try: total = soup.find_all('a',text=nt) if total: total= re.sub('\D',"",total[0]['href']) else: total = 0 except BaseException,param: utils.log( "获取单个相册内图片所有图片的数量异常,原因" + param , logging.ERROR) return None return total
第四步:下个单个相册的所有图片:
#下载单个相册中的所有图片 def getSinglePic(self , url , path): title = re.split(r'\\', path) title = title[-1] try: page_url = self.getSinglePicUrl(url) if page_url: totalPageNum = self.getSinglePicTotal(url) base_url = urlparse(url) real_url =base_url.scheme+"://"+base_url.netloc #从第一页开始,下载单个图集中所有的图片 #range()第二个参数是范围值的上限,循环时不包括该值 #需要加1以保证读取到所有页面。 p = r'.+\/' pa = re.compile(p) #print title if totalPageNum: for i in range(1,totalPageNum + 1): currenturl = real_url + "/" + str(i) self.downloadpic(currenturl,path) else: next_url = self.getSinglePicUrl(url) cur_page = 1 utils.log("即将下载图集:" + title) while next_url: match = re.search(pa, next_url).group(0) if match: currenturl = real_url+ "/" + match + str(cur_page) else: currenturl = real_url+ "/" + next_url # + str(cur_page) #utils.log("正在下载: "+ str(cur_page) + " 个图片:" +" 链接:"+ url ) self.downloadpic(currenturl,path) cur_page += 1 next_url = self.getSinglePicUrl(currenturl) #判断是否还有下一页 # if cur_page > 2: # return cur_page return (cur_page-1) else: utils.log( "图集:"+ title+ "链接:" + url +" 获取图片链接失败") return None except BaseException,param: utils.log( "下载单个相册:" + title + " 链接:" + url+ "中的所有图片异常,原因:" + param ,logging.ERROR) return None except: utils.log( "下载单个相册:" + title + " 链接:" + url+ "中的所有图片异常" ,logging.ERROR) return None
下载图片的重点来了:
#下载单个相册中的所有图片 def getSinglePic(self , url , path): title = re.split(r'\\', path) title = title[-1] try: page_url = self.getSinglePicUrl(url) if page_url: totalPageNum = self.getSinglePicTotal(url) base_url = urlparse(url) real_url =base_url.scheme+"://"+base_url.netloc #从第一页开始,下载单个图集中所有的图片 #range()第二个参数是范围值的上限,循环时不包括该值 #需要加1以保证读取到所有页面。 p = r'.+\/' pa = re.compile(p) #print title if totalPageNum: for i in range(1,totalPageNum + 1): currenturl = real_url + "/" + str(i) self.downloadpic(currenturl,path) else: next_url = self.getSinglePicUrl(url) cur_page = 1 utils.log("即将下载图集:" + title) while next_url: match = re.search(pa, next_url).group(0) if match: currenturl = real_url+ "/" + match + str(cur_page) else: currenturl = real_url+ "/" + next_url # + str(cur_page) #utils.log("正在下载: "+ str(cur_page) + " 个图片:" +" 链接:"+ url ) self.downloadpic(currenturl,path) cur_page += 1 next_url = self.getSinglePicUrl(currenturl) #判断是否还有下一页 # if cur_page > 2: # return cur_page return (cur_page-1) else: utils.log( "图集:"+ title+ "链接:" + url +" 获取图片链接失败") return None except BaseException,param: utils.log( "下载单个相册:" + title + " 链接:" + url+ "中的所有图片异常,原因:" + param ,logging.ERROR) return None except: utils.log( "下载单个相册:" + title + " 链接:" + url+ "中的所有图片异常" ,logging.ERROR) return None
第五步:下载图片:
def Schedule(a,b,c): ''''' a:已经下载的数据块 b:数据块的大小 c:远程文件的大小 ''' per = 100.0 * a * b / c if per > 100 : per = 100 print '%.2f%%' % per def auto_down(self, url , filename): file_dir = os.path.split(filename )[0] if os.path.isdir(file_dir): pass else: utils.log("目录:" + file_dir +"不存在,将重新创建该目录,用于下载文件:"+ filename) os.makedirs(file_dir) urllib.urlretrieve(url,filename ,Schedule)
接下来需要判断,图片是否存在,以及删除文件为空的文件夹:
#判断文件是否存在 def file_exists(self,filename): try: with open(filename) as f: return True except IOError: return False #删除空目录 def cleanDir( dir ): try: if os.path.isdir( dir ): files = os.listdir(dir) # 获取路径下的子文件(夹)列表 if files: utils.log( "找到:" +dir+"下共:" + str(len(files)) +" 文件或文件夹") else: dir= dir+"\\" files = os.listdir(dir) # 获取路径下的子文件(夹)列表 utils.log( "找到:" + dir +"下" +str(len(files)) +"文件或文件夹") for file in files: print '扫描路径:'+ file.decode('GBK') if os.path.isdir(file): # 如果是文件夹 if not os.listdir(file): # 如果子文件为空 os.rmdir(file) # 删除这个空文件夹 utils.log( file.decode('GBK') + " 文件夹为空,即将删除" ) elif os.path.isfile(file): # 如果是文件 if os.path.getsize(file) == 0: # 文件大小为0 os.remove(file) # 删除这个文件 utils.log( file.decode('GBK')+"文件为空,即将删除" ) except BaseException,param: utils.log( "扫描路径"+ dir + "异常,原因:" + str(param) ,logging.ERROR ) utils.log( "扫描路径"+ dir + " 结束")
好了,大工告成,让我们取旁边喝一杯,稍微等一会,就有大大的惊喜。
好了,这次的分享,到这里结束了,完整的源代码大家可以加入QQ群: 98556420,获取。
下一期,我也将会和大家分享使用人脸识别,来识别这些妹子。。。
Python爬虫学习之爬美女图片的更多相关文章
- python爬虫学习(7) —— 爬取你的AC代码
上一篇文章中,我们介绍了python爬虫利器--requests,并且拿HDU做了小测试. 这篇文章,我们来爬取一下自己AC的代码. 1 确定ac代码对应的页面 如下图所示,我们一般情况可以通过该顺序 ...
- Python爬虫学习 - day1 - 爬取图片
利用Python完成简单的图片爬取 最近学习到了爬虫,瞬时觉得很高大上,想取什么就取什么,感觉要上天.这里分享一个简单的爬取汽车之家文章列表的图片教程,供大家学习. 需要的知识点储备 本次爬虫脚本依赖 ...
- python爬虫学习(2) —— 爬一下ZOL壁纸
我喜欢去ZOL找一些动漫壁纸当作桌面,而一张一张保存显然是太慢了. 那怎么办呢,我们尝试使用简单的爬虫来解决这个问题. 0. 本爬虫目标 抓取给定分类「或子分类」网址的内容 分析并得到每个分类下的所有 ...
- Python爬虫学习(二) ——————爬取前程无忧招聘信息并写入excel
作为一名Pythoner,相信大家对Python的就业前景或多或少会有一些关注.索性我们就写一个爬虫去获取一些我们需要的信息,今天我们要爬取的是前程无忧!说干就干!进入到前程无忧的官网,输入关键字&q ...
- python爬虫学习之爬取全国各省市县级城市邮政编码
实例需求:运用python语言在http://www.ip138.com/post/网站爬取全国各个省市县级城市的邮政编码,并且保存在excel文件中 实例环境:python3.7 requests库 ...
- python爬虫学习01--电子书爬取
python爬虫学习01--电子书爬取 1.获取网页信息 import requests #导入requests库 ''' 获取网页信息 ''' if __name__ == '__main__': ...
- python爬虫学习(1) —— 从urllib说起
0. 前言 如果你从来没有接触过爬虫,刚开始的时候可能会有些许吃力 因为我不会从头到尾把所有知识点都说一遍,很多文章主要是记录我自己写的一些爬虫 所以建议先学习一下cuiqingcai大神的 Pyth ...
- python爬虫学习视频资料免费送,用起来非常666
当我们浏览网页的时候,经常会看到像下面这些好看的图片,你是否想把这些图片保存下载下来. 我们最常规的做法就是通过鼠标右键,选择另存为.但有些图片点击鼠标右键的时候并没有另存为选项,或者你可以通过截图工 ...
- python爬虫学习05-爬取图片
python爬虫学习05-爬取图片 确定要爬取的网址:https://shenan.tuchong.com/20903415/#image309854686 要爬取的内容:使用浏览器插件xpath对图 ...
随机推荐
- JEESZ-kafka集群安装
1. 在根目录创建kafka文件夹(service1.service2.service3都创建) [root@localhost /]# mkdir kafka 2.通过Xshell上传文件到s ...
- Configure Red Hat Enterprise Linux shared disk cluster for SQL Server——RHEL上的“类”SQL Server Cluster功能
下面一步一步介绍一下如何在Red Hat Enterprise Linux系统上为SQL Server配置共享磁盘集群(Shared Disk Cluster)及其相关使用(仅供测试学习之用,基础篇) ...
- C#特性:从自定义一个特性开始,谈谈什么是特性
作为C#新手中的一员,我刚开始接触特性时,那真是一脸冏逼啊,怎么想怎么查资料都没弄明白它到底是个什么东西,有的入门教程甚至都没讲特性和反射这些概念!相信很多人第一次接触到特性就是关于系列化的知识了. ...
- TCP协议随笔
传输控制协议TCP是面向连接.保证高可靠性(数据无丢失.数据无失序.数据无错误.数据无重复到达)传输层协议.TCP/IP结构对应OSITCP/IP ...
- 009一对一 主键关联映射_单向(one-to-one)
009一对一 主键关联映射_单向(one-to-one) ² 两个对象之间是一对一的关系,如Person-IdCard(人—身份证号) ² 有两种策略可以实现一对一的关联映射 主键关联:即让两个 ...
- 修改node来增加自定义工具命令
如何通过node创建自定义cmd命令 一.命令功能的实现 1.将自己的自定义工具的文件夹放到当前使用的 node 的安装目录下的 node_modules 文件夹下面: 2.回到node安装目录下复制 ...
- 移动端车牌识别——可以嵌入智能手机系统里的新OCR识别技术
移动端车牌识别技术,是在OCR光学字符识别技术的基础上研发的用来识别汽车号牌特征信息的图像识别技术.在国内,该项技术由北京易泊时代携手清华大学成功地将"国家863计划"项目成果-- ...
- Thinkphp5使用阿里大于短信验证
现在各种平台登录验证很多时候会使用短信验证,快捷安全,有很多平台提供短信验证服务,相比较而言阿里大于价格比较便宜,快捷,所以在在千锋日常的php教学中多以此为例来说明短信验证的使用.下面我们在tp5中 ...
- div的替代品
人们在标签使用中最常见到的错误之一就是随意将HTML5的<section>等价于<div>--具体地说,就是直接用作替代品(用于样式).在XHTML或者HTML4中,我们常看到 ...
- jsp中怎么调用java类中的方法
在jsp页面中先要,引入java类 例如: <%@page import="javabean.DbConn"%><!-- 引入包中的"类" - ...