今天,学习了爬虫的基础知识,尝试着写了本人的第一个小爬虫——爬取糗百上的热门段子。一开始自己做的是爬取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!
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python爬虫实战(一) - Python技术站