[Python]网络爬虫(八):糗事百科的网络爬虫(v0.2)源码及解析(转)
源码下载:
http://download.csdn.net/detail/wxg694175346/6925583
项目内容:
用Python写的糗事百科的网络爬虫。
使用方法:
新建一个Bug.py文件,然后将代码复制到里面后,双击运行。
程序功能:
在命令提示行中浏览糗事百科。
原理解释:
首先,先浏览一下糗事百科的主页:http://www.qiushibaike.com/hot/page/1
可以看出来,链接中page/后面的数字就是对应的页码,记住这一点为以后的编写做准备。
然后,右击查看页面源码:
观察发现,每一个段子都用div标记,其中class必为content,title是发帖时间,我们只需要用正则表达式将其“扣”出来就可以了。
明白了原理之后,剩下的就是正则表达式的内容了,可以参照这篇博文:
http://blog.csdn.net/wxg694175346/article/details/8929576
运行效果:
1 # -*- coding: utf-8 -*- 2 #--------------------------------------- 3 # 程序:糗百爬虫 4 # 版本:0.2 5 # 作者:why 6 # 日期:2013-05-15 7 # 语言:Python 2.7 8 # 操作:输入quit退出阅读糗事百科 9 # 功能:按下回车依次浏览今日的糗百热点 10 # 更新:解决了命令提示行下乱码的问题 11 #--------------------------------------- 12 13 import urllib2 14 import urllib 15 import re 16 import thread 17 import time 18 19 #----------- 处理页面上的各种标签 ----------- 20 class HTML_Tool: 21 # 用非 贪婪模式 匹配 \t 或者 \n 或者 空格 或者 超链接 或者 图片 22 BgnCharToNoneRex = re.compile("(\t|\n| |<a.*?>|<img.*?>)") 23 24 # 用非 贪婪模式 匹配 任意<>标签 25 EndCharToNoneRex = re.compile("<.*?>") 26 27 # 用非 贪婪模式 匹配 任意<p>标签 28 BgnPartRex = re.compile("<p.*?>") 29 CharToNewLineRex = re.compile("(<br/>|</p>|<tr>|<div>|</div>)") 30 CharToNextTabRex = re.compile("<td>") 31 32 # 将一些html的符号实体转变为原始符号 33 replaceTab = [("<","<"),(">",">"),("&","&"),("&","\""),(" "," ")] 34 35 def Replace_Char(self,x): 36 x = self.BgnCharToNoneRex.sub("",x) 37 x = self.BgnPartRex.sub("\n ",x) 38 x = self.CharToNewLineRex.sub("\n",x) 39 x = self.CharToNextTabRex.sub("\t",x) 40 x = self.EndCharToNoneRex.sub("",x) 41 42 for t in self.replaceTab: 43 x = x.replace(t[0],t[1]) 44 return x 45 #----------- 处理页面上的各种标签 ----------- 46 47 48 #----------- 加载处理糗事百科 ----------- 49 class HTML_Model: 50 51 def __init__(self): 52 self.page = 1 53 self.pages = [] 54 self.myTool = HTML_Tool() 55 self.enable = False 56 57 # 将所有的段子都扣出来,添加到列表中并且返回列表 58 def GetPage(self,page): 59 myUrl = "http://m.qiushibaike.com/hot/page/" + page 60 myResponse = urllib2.urlopen(myUrl) 61 myPage = myResponse.read() 62 #encode的作用是将unicode编码转换成其他编码的字符串 63 #decode的作用是将其他编码的字符串转换成unicode编码 64 unicodePage = myPage.decode("utf-8") 65 66 # 找出所有class="content"的div标记 67 #re.S是任意匹配模式,也就是.可以匹配换行符 68 myItems = re.findall('<div.*?class="content".*?title="(.*?)">(.*?)</div>',unicodePage,re.S) 69 items = [] 70 for item in myItems: 71 # item 中第一个是div的标题,也就是时间 72 # item 中第二个是div的内容,也就是内容 73 items.append([item[0].replace("\n",""),item[1].replace("\n","")]) 74 return items 75 76 # 用于加载新的段子 77 def LoadPage(self): 78 # 如果用户未输入quit则一直运行 79 while self.enable: 80 # 如果pages数组中的内容小于2个 81 if len(self.pages) < 2: 82 try: 83 # 获取新的页面中的段子们 84 myPage = self.GetPage(str(self.page)) 85 self.page += 1 86 self.pages.append(myPage) 87 except: 88 print '无法链接糗事百科!' 89 else: 90 time.sleep(1) 91 92 def ShowPage(self,q,page): 93 for items in q: 94 print u'第%d页' % page , items[0] 95 print self.myTool.Replace_Char(items[1]) 96 myInput = raw_input() 97 if myInput == "quit": 98 self.enable = False 99 break 100 101 def Start(self): 102 self.enable = True 103 page = self.page 104 105 print u'正在加载中请稍候......' 106 107 # 新建一个线程在后台加载段子并存储 108 thread.start_new_thread(self.LoadPage,()) 109 110 #----------- 加载处理糗事百科 ----------- 111 while self.enable: 112 # 如果self的page数组中存有元素 113 if self.pages: 114 nowPage = self.pages[0] 115 del self.pages[0] 116 self.ShowPage(nowPage,page) 117 page += 1 118 119 120 #----------- 程序的入口处 ----------- 121 print u""" 122 --------------------------------------- 123 程序:糗百爬虫 124 版本:0.1 125 作者:why 126 日期:2013-05-15 127 语言:Python 2.7 128 操作:输入quit退出阅读糗事百科 129 功能:按下回车依次浏览今日的糗百热点 130 --------------------------------------- 131 """ 132 133 134 print u'请按下回车浏览今日的糗百内容:' 135 raw_input(' ') 136 myModel = HTML_Model() 137 myModel.Start()