Python爬虫实战一之爬取糗事百科段子


现在正则表达式在这里稍作说明

1).*? 是一个固定的搭配,.和*代表可以匹配任意无限多个字符,加上?表示使用非贪婪模式进行匹配,也就是我们会尽可能短地做匹配,以后我们还会大量用到 .*? 的搭配。

2)(.*?)代表一个分组,在这个正则表达式中我们匹配了五个分组,在后面的遍历item中,item[0]就代表第一个(.*?)所指代的内容,item[1]就代表第二个(.*?)所指代的内容,以此类推。

3)re.S 标志代表在匹配时为点任意匹配模式,点 . 也可以代表换行符。

这样我们就获取了发布人,发布时间,发布内容,附加图片以及点赞数。

在这里注意一下,我们要获取的内容如果是带有图片,直接输出出来比较繁琐,所以这里我们只获取不带图片的段子就好了。

所以,在这里我们就需要对带图片的段子进行过滤。

我们可以发现,带有图片的段子会带有类似下面的代码,而不带图片的则没有,所以,我们的正则表达式的item[3]就是获取了下面的内容,如果不带图片,item[3]获取的内容便是空。

   
1 2 3 4 5 6 7 <div class="thumb">   <a href="/article/112061287?list=hot&s=4794990" target="_blank"> <img src="http://pic.qiushibaike.com/system/pictures/11206/112061287/medium/app112061287.jpg" alt="但他们依然乐观"> </a>   </div>

所以我们只需要判断item[3]中是否含有img标签就可以了。

本文完整代码如下:

  1 _author__ = 'biao'
  2 # _*_ coding:utf-8 _*_ 
  3 import urllib.request
  4 #import urllib3.request
  5 import re
  6 import _thread
  7 import time
  8 
  9 #糗事百科爬虫类
 10 class QSBK:
 11     #初始化方法,定义一些变量
 12     def __init__(self):
 13         self.pageIndex = 1
 14         self.user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
 15         #初始化headers
 16         self.headers = { 'User-Agent' : self.user_agent }
 17         #存放段子的变量,每一个元素是每一页的段子们
 18         self.stories = []
 19         #存放程序是否继续运行的变量
 20         self.enable = False
 21     #传入某一页的索引获得页面代码
 22     def getPage(self,pageIndex):
 23         try:
 24             url = 'http://www.qiushibaike.com/hot/page/' + str(pageIndex)
 25             #构建请求的request
 26             request = urllib.request.Request(url,headers = self.headers)
 27             #利用urlopen获取页面代码
 28             response = urllib.request.urlopen(request)
 29             #将页面转化为UTF-8编码
 30             pageCode = response.read().decode('utf-8')
 31             return pageCode
 32  
 33         except urllib.error.URLError as e:
 34             if hasattr(e,"reason"):
 35                 print(u"连接糗事百科失败,错误原因",e.reason)
 36                 return None
 37      #传入某一页代码,返回本页不带图片的段子列表
 38     def getPageItems(self,pageIndex):
 39         pageCode = self.getPage(pageIndex)
 40         if not pageCode:
 41             print("页面加载失败....")
 42             return None
 43         pattern = re.compile('.*?(.*?).*?'+
 44                          'content">(.*?).*?
(.*?)
(.*?)',re.S) 45 items = re.findall(pattern,pageCode) 46 #用来存储每页的段子们 47 pageStories = [] 48 #遍历正则表达式匹配的信息 49 for item in items: 50 #是否含有图片 51 haveImg = re.search("img",item[3]) 52 #如果不含有图片,把它加入list中 53 if not haveImg: 54 replaceBR = re.compile('
') 55 text = re.sub(replaceBR,"\n",item[1]) 56 #item[0]是一个段子的发布者,item[1]是内容,item[2]是发布时间,item[4]是点赞数 57 pageStories.append([item[0].strip(),text.strip(),item[2].strip(),item[4].strip()]) 58 return pageStories 59 60 61 #加载并提取页面的内容,加入到列表中 62 def loadPage(self): 63 #如果当前未看的页数少于2页,则加载新一页 64 if self.enable == True: 65 if len(self.stories) < 2: 66 #获取新一页 67 pageStories = self.getPageItems(self.pageIndex) 68 #将该页的段子存放到全局list中 69 if pageStories: 70 self.stories.append(pageStories) 71 #获取完之后页码索引加一,表示下次读取下一页 72 self.pageIndex += 1 73 74 #调用该方法,每次敲回车打印输出一个段子 75 def getOneStory(self,pageStories,page): 76 #遍历一页的段子 77 for story in pageStories: 78 #等待用户输入 79 _input = input() 80 #每当输入回车一次,判断一下是否要加载新页面 81 self.loadPage() 82 #如果输入Q则程序结束 83 if _input == "Q": 84 self.enable = False 85 return 86 print(u"第%d页\t发布人:%s\t发布时间:%s\t赞:%s\n%s" %(page,story[0],story[2],story[3],story[1])) 87 88 #开始方法 89 def start(self): 90 print(u"正在读取糗事百科,按回车查看新段子,Q退出") 91 #使变量为True,程序可以正常运行 92 self.enable = True 93 #先加载一页内容 94 self.loadPage() 95 #局部变量,控制当前读到了第几页 96 nowPage = 0 97 while self.enable: 98 if len(self.stories)>0: 99 #从全局list中获取一页的段子 100 pageStories = self.stories[0] 101 #当前读到的页数加一 102 nowPage += 1 103 #将全局list中第一个元素删除,因为已经取出 104 del self.stories[0] 105 #输出该页的段子 106 self.getOneStory(pageStories,nowPage) 107 108 109 spider = QSBK() 110 spider.start() 111 112 113 ''' 114 def run_demo(): 115 f=urllib.request.urlopen('http://www.baidu.com') 116 print(f.read()) 117 118 if __name__=='__main__': 119 run_demo() 120 ''' 121 122 ''' 123 page = 1 124 url = 'http://www.qiushibaike.com/hot/page/' + str(page) 125 user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)' 126 headers = { 'User-Agent' : user_agent } 127 try: 128 request = urllib.request.Request(url,headers = headers) 129 response = urllib.request.urlopen(request) 130 content = response.read().decode('utf-8') 131 pattern = re.compile('.*?(.*?).*?132 'content">(.*?).*?
(.*?)
(.*?)',re.S) 133 items = re.findall(pattern,content) 134 for item in items: 135 haveImg = re.search("img",item[3]) 136 if not haveImg: 137 print(item[0],item[1],item[2],item[4]) 138 # print(response.read()) 139 except urllib.error.HTTPError as e: 140 if hasattr(e,"code"): 141 print(e.code) 142 if hasattr(e,"reason"): 143 print(e.reason) 144 '''