自学Python十 爬虫实战三(美女福利续)
我又来送福利啦!!!不同于上篇文章,这次我们的爬虫采用了多线程,一直以来被所谓的分布式 多线程 爬虫 给唬的怕怕的。今天就来一发多线程爬虫吧,还能看妹子图,想想就觉得很激动!!!
依然是流程解释:
1.分析要爬取的网址,发现页面分两级,第一级是多个图片集的入口,第二集是图片的入口。我们新建两个类,一个类是爬取所有图片集的url,一个类是根据得到的图片集的url爬取图片下载下来。第二个类的功能就跟我们上篇爬取煎蛋的功能一样。
2.我们考虑用多线程去实现爬虫,为此我们引入了Queue模块,主线程爬取第一级得到多个图片集url放入到queue中,新建多个线程,从queue中取出数据,然后下载图片!
3.遇到的困难呢 万恶的编码坑,要注意规避可能出现的错误 因为出现问题 线程就会死掉。
这篇正则啥的就不搞了,其实都很简单的,对于html分析python有一些库是比较不错的,比如Beautiful Soup 有机会再学习学习!还有爬虫框架Scrapy。。。要学习的东西还非常非常多啊。务必脚踏实地!!!
1 # -*- coding: utf-8 -*- 2 from __future__ import unicode_literals 3 from HttpClient import HttpClient 4 import sys,re,os 5 from threading import Thread 6 from Queue import Queue 7 from time import sleep 8 9 q = Queue()#图片集url队列 10 imgCount = 0 11 class getRosiUrl(HttpClient):#一级url爬取类 12 def __init__(self): 13 self.__pageIndex = 1 14 self.__Url = "http://www.5442.com/tag/rosi/" 15 self.__refer = 'http://www.5442.com/tag/rosi.html' 16 #将爬取的图片集url放入队列 17 def __getAllPicUrl(self,pageIndex): 18 realurl = self.__Url + str(pageIndex) + ".html" 19 print realurl 20 pageCode = self.Get(realurl,self.__refer) 21 type = sys.getfilesystemencoding() 22 #print pageCode[0:1666].decode("gb2312",'ignore').encode(type) 23 pattern = re.compile('<div.*?title">.*?<span><a href="(.*?)".*?</a>',re.S) 24 items = re.findall(pattern,pageCode.decode("gb2312",'ignore').encode(type)) 25 for item in items: 26 #print item 27 global q 28 q.put(item) 29 #print "放入队列" 30 #得到最新页码 31 def __getNewPage(self): 32 pageCode = self.Get("http://www.5442.com/tag/rosi.html",self.__refer) 33 type = sys.getfilesystemencoding() 34 pattern = re.compile(r'<ul.*?<li .*?pageinfo">(.*?)</li>',re.S) 35 newPage = re.search(pattern,pageCode.decode("gb2312",'ignore').encode(type)) 36 num = re.search("[0-9]+",newPage.group(1).decode("gb2312",'ignore').split("/")[0]).group() 37 if newPage != None: 38 return int(num) 39 return 0 40 41 def start(self): 42 page = self.__getNewPage() 43 for i in range(1,page): 44 self.__getAllPicUrl(i) 45 46 #图片下载类 47 class downloadImg(HttpClient): 48 def __init__(self): 49 self.__pageIndex = 1 50 self.__floder = "rosi" 51 self.__Url = "http://www.5442.com/meinv/20150904/27058.html" 52 self.__refer = 'http://www.5442.com/tag/rosi.html' 53 def __getNewPage(self): 54 pageCode = self.Get(self.__Url,self.__refer) 55 type = sys.getfilesystemencoding() 56 pattern = re.compile(r'<ul.*?<li>.*?<a>(.*?)</a></li>',re.S) 57 newPage = re.search(pattern,pageCode.decode("gb2312",'ignore').encode(type)) 58 if newPage !=None: 59 num = re.search("[0-9]+",newPage.group(1).decode("gb2312",'ignore').split("/")[0]).group() 60 return int(num) 61 return 0 62 #得到图片集名称 63 def __getBookName(self): 64 pageCode = self.Get(self.__Url,self.__refer) 65 type = sys.getfilesystemencoding() 66 pattern = re.compile(r'<h1><a.*?>(.*?)</a>',re.S) 67 title = re.findall(pattern,pageCode.decode("gb2312",'ignore').encode(type)) 68 if title != None: 69 return title[0] 70 return "未命名" 71 #得到每页图片url 72 def __getAllPicUrl(self,pageIndex): 73 realurl = self.__Url[:-5] + "_" + str(pageIndex) + ".html" 74 pageCode = self.Get(realurl) 75 type = sys.getfilesystemencoding() 76 pattern = re.compile('<p align="center" id="contents">.*?<a.*?<img src=(.*?) alt=.*?>',re.S) 77 items = re.findall(pattern,pageCode.decode("gb2312",'ignore').encode(type)) 78 self.__savePics(items,self.__floder) 79 #下载保存图片 80 def __savePics(self,img_addr,folder): 81 for item in img_addr: 82 filename = self.__floder + "\\" +item.split('/')[-1][:-1] 83 print "正在保存图片:" + filename 84 print item[1:-1] 85 with open(filename,'wb') as file: 86 img = self.Get(item[1:-1]) 87 file.write(img) 88 global imgCount 89 imgCount = imgCount + 1 90 def start(self): 91 while True: 92 global q 93 self.__Url = q.get()#从队列中取出一条图片集url 94 title = self.__getBookName() 95 self.__floder = os.getcwd() + "\\rosi\\" + title.decode("gb2312",'ignore') 96 isExists=os.path.exists(self.__floder) 97 if not isExists: 98 type = sys.getfilesystemencoding() 99 os.mkdir(self.__floder) 100 101 page = self.__getNewPage() + 1 102 for i in range(self.__pageIndex,page): 103 self.__getAllPicUrl(i) 104 105 q.task_done()#完成一项任务 106 107 108 109 110 if __name__ == '__main__': 111 isExists=os.path.exists("rosi")#创建保存目录 112 if not isExists: 113 os.mkdir("rosi") 114 for i in range(5):#新建5个线程 等待队列 115 print i 116 downImg = downloadImg() 117 t = Thread(target=downImg.start) 118 t.setDaemon(True) 119 t.start() 120 rosi = getRosiUrl() 121 rosi.start() 122 123 q.join
其中HttpClient.py就参考前面文章的吧,不过这个网站不需要代理了。。。下面看看成果吧,一波妹子图正在袭来: