今天,学习了爬虫的基础知识,尝试着写了本人的第一个小爬虫——爬取糗百上的热门段子。一开始自己做的是爬取1-35页,每页20条段子的作者、点赞数和内容,代码很简陋,贴在下面:

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 __author__ = 'ziv·chan'
 4 
 5 import requests
 6 import re
 7 
 8 user_agent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.94 Safari/537.36'
 9 headers = {
10     'User-Agent' : user_agent
11 }
12 i = 1
13 for page in range(1,36):
14     url = 'http://www.qiushibaike.com/hot/page/' + str(page)
15     html = requests.get(url,headers=headers)
16     html.encoding = 'utf-8'
17     # print html
18 
19     pattern = re.compile('div class="articl.*?" alt="(.*?)"/>.*?content">\n{2,}(.*?)\n{2,}</div>.*?number">(.*?)</i>',re.S)
20     items = re.findall(pattern,html.text)
21     for item in items:
22         replaceBr = re.compile('<br/>')
23         text = re.sub(replaceBr,'\n',item[1])
24         print i
25         i+=1
26         print u'发布者:' + item[0].strip()
27         print u'内容:' + text.strip()
28         print u'点赞数:' + item[2].strip()
29         print '\n'
30     page+=1

后改进如下(自己对类和函数的把握还是太差,中间错了好多~~):

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 __author__ = 'ziv·chan'
 4 
 5 import requests
 6 import re
 7 
 8 
 9 class QSBK:
10 
11     def __init__(self):
12         self.pageIndex = 1
13         self.user_agent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.94 Safari/537.36'
14         self.headers = {'User-Agent' : self.user_agent}
15         self.Stories = []
16         self.enable = False
17 
18     def getPagecode(self,pageIndex):
19         url = 'http://www.qiushibaike.com/hot/page/' + str(pageIndex)
20         html = requests.get(url,headers=self.headers)
21         html.encoding = 'utf-8'
22         pageCode = html.text
23         return pageCode
24 
25     def getPageItems(self,pageIndex):
26         pageCode = self.getPagecode(pageIndex)
27         pattern = re.compile('div class="articl.*?" alt="(.*?)"/>.*?content">\n{2,}(.*?)\n{2,}</div>.*?number">(.*?)</i>',re.S)
28         items = re.findall(pattern,pageCode)
29         pageStories = []
30         for item in items:
31             replaceBr = re.compile('<br/>')
32             text = re.sub(replaceBr,'\n',item[1])
33             pageStories.append([item[0].strip(),text.strip(),item[2].strip()])
34         return pageStories
35 
36     def loadPage(self):
37         if self.enable == True:
38             if len(self.Stories) < 2:
39                 pageStories = self.getPageItems(self.pageIndex)
40                 if pageStories:
41                     self.Stories.append(pageStories)
42                     self.pageIndex += 1
43 
44     def getOneStory(self,pageStories,page):
45         for story in pageStories:
46             input = raw_input()
47             self.loadPage()
48             if input == 'Q':
49                 self.enable = False
50                 return
51             print u"第%d页\t发布人:%s\t赞:%s\n%s" %(page,story[0],story[2],story[1])
52 
53     def start(self):
54         print u"正在读取糗事百科,按回车查看新段子,Q退出"
55         self.enable = True
56         self.loadPage()
57         nowpage = 0
58         while self.enable:
59             if len(self.Stories) > 0:
60                 pageStories = self.Stories[0]
61                 nowpage += 1
62                 del self.Stories[0]
63                 self.getOneStory(pageStories,nowpage)
64 
65 spider = QSBK()
66 spider.start()

学到了:

模拟浏览器请求,一定要添加‘headers’验证,正则消除空行‘ \n{2,} ’,

正则过滤多余标签:

1 replaceBr = re.compile('<br/>')
2 text = re.sub(replaceBr,'\n',content)

需要提高的地方:类和函数,复杂的正则,编码问题

正则表达式的有关说明:

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

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

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

 

部分内容参考静觅

本人的第一篇正式博客,才发现以前学知识学得太糙了,很多都不记得了,那就重新开始,记录下点点滴滴,fighting!