今天在 http://python.jobbole.com/81351/ 学习了Python爬虫的相关知识,试着爬取糗事百科 http://www.qiushibaike.com/hot/ 的内容,感谢作者的无私分享。
貌似由于现在网址结构有所变化,所以提供的代码的正则表达式匹配部分不能良好运行了。遂根据今天所学的知识进行了些许修改。使用 Beautiful Soup 来进行段子抓取。期间也遇到了一些问题,比如文本中有<br>则不能成功抓取,后利用.get_text("|", strip=True)解决并消除了空白行。
运行结果:
正在读取糗事百科,按回车查看新段子,Q退出
author: 大湿的乳来伸掌
story: 他会赶走你身边的邪恶,抓走你身边的小人,要想远离小人的,赶紧左下!!!
author: 小小懒蓝兔子
story: 高手出民间
author: 范冰冰的娇喘助理
story: 前几天去旅游,在大巴上后面坐着一个男的和一个女的,女的把头靠在男的肩膀上秀恩爱。其实我还感觉挺温馨。过了一会那男的说我两合个影吧。那女的说别用我手机,我怕我老公看见。这么一句让我刚喝的一口水给喷了出来!
修改后的具体代码如下:
# -*- coding: UTF-8 -*- __author__ = 'CQC' import urllib2 from bs4 import BeautifulSoup # 糗事百科爬虫类 class QSBK: # 初始化方法,定义一些变量 def __init__(self): self.pageIndex = 1 self.user_agent = 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0' # 初始化headers self.headers = {'User-Agent': self.user_agent} # 存放段子的变量,每一个元素是每一页的段子们 self.stories = [] # 存放程序是否继续运行的变量 self.enable = False # 传入某一页的索引获得页面代码 def getPage(self, pageIndex): try: url = 'http://www.qiushibaike.com/hot/page/' + str(pageIndex) # 构建请求的request request = urllib2.Request(url, headers=self.headers) # 利用urlopen获取页面代码 response = urllib2.urlopen(request) # 将页面转化为UTF-8编码 pageCode = response.read().decode('utf-8') return pageCode except urllib2.URLError, e: if hasattr(e, "reason"): print u"连接糗事百科失败,错误原因", e.reason return None # 传入某一页代码,返回本页不带图片的段子列表 def getPageItems(self, pageIndex): pageCode = self.getPage(pageIndex) pageStories = [] pageAuthors = [] if not pageCode: print "页面加载失败...." return None soup = BeautifulSoup(pageCode, 'lxml') contents = soup.findAll(attrs={"class": "content"}) authors = soup.findAll(attrs={"class": "author clearfix"}) for author in authors: pageAuthors.append(author.get_text("|", strip=True)) for content in contents: pageStories.append(content.get_text("|", strip=True)) return zip(pageStories, pageAuthors) # 加载并提取页面的内容,加入到列表中 def loadPage(self): # 如果当前未看的页数少于2页,则加载新一页 if self.enable == True: if len(self.stories) < 2: # 获取新一页 pageStoriesAndAuthors = self.getPageItems(self.pageIndex) # 将该页的段子存放到全局list中 if pageStoriesAndAuthors: self.stories.append(pageStoriesAndAuthors) # 获取完之后页码索引加一,表示下次读取下一页 self.pageIndex += 1 # 调用该方法,每次敲回车打印输出一个段子 def getOneStory(self, pageStoriesAndAuthors, page): # 遍历一页的段子 for story, author in pageStoriesAndAuthors: # 等待用户输入 input = raw_input() # 每当输入回车一次,判断一下是否要加载新页面 self.loadPage() # 如果输入Q则程序结束 if input == "Q": self.enable = False # return print u' author: %s \n story: %s' % (author, story) # 开始方法 def start(self): print u"正在读取糗事百科,按回车查看新段子,Q退出" # 使变量为True,程序可以正常运行 self.enable = True # 先加载一页内容 self.loadPage() # 局部变量,控制当前读到了第几页 nowPage = 0 while self.enable: if len(self.stories) > 0: # 从全局list中获取一页的段子 pageStories = self.stories[0] # 当前读到的页数加一 nowPage += 1 # 将全局list中第一个元素删除,因为已经取出 del self.stories[0] # 输出该页的段子 self.getOneStory(pageStories, nowPage) spider = QSBK() spider.start()