现在正则表达式在这里稍作说明
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">(.*?).*?
(.*?)') 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('
(.*?)',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 '''
View Code