爬虫抓取糗事百科的段子

  抓取网页信息需要涉及到urllib,urllib2,re等模块,通过urllib和urllib2获取网页内容,通过正则匹配定制获取想要抓取的结果。本文需要抓取糗事百科段子的作者,内容,好笑数,评论数等参数。

一、非oop模式获取糗事百科某一页面的段子信息。

代码如下:

#!/usr/bin/env python
#coding:utf8
#author: xkops

import urllib
import urllib2
import re
import sys

page = 0 #获取首页信息
url = 'http://www.qiushibaike.com/hot/page/' + str(page)
user_agent = 'User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.101 Safari/537.36'
headers = { 'User-Agent': user_agent }

try:
    #如果不添加headers会出现报错
    req = urllib2.Request(url, headers = headers)
    response = urllib2.urlopen(req)
    content = response.read().decode('utf-8')
    #正则匹配
    pat1 = re.compile('<div class="author clearfix">.*?href.*?<img src.*?title=.*?<h2>(.*?)</h2>.*?<div class="content">.*?<span>(.*?)</span>.*?</div>.*?class="stats">.*?<i class="number">(.*?)</i>.*?<i class="number">(.*?)</i>',re.S)
    items = re.findall(pat1, content)
    for item in items:
        print '-----------------'
        print u"作者: " + item[0]
        print u"内容: " + item[1]
        print u"笑点: " + item[2]
        print u"评论: " + item[3]
except urllib2.URLError,e:
    if hasattr(e, "code"):
        print e.code
    if hasattr(e,"reason"):
        print e.reason

*注释:通过上面的脚本已经可以实现抓取某一页面的段子信息

二、使用oop方式实现抓逐页获取段子信息,通过回车逐渐获取每一个段子。

代码信息如下:

#!/usr/bin/env python
#coding:utf8
import urllib
import urllib2
import re
import sys

class QSBK(object):
    def __init__(self):
        self.user_agent = 'User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.101 Safari/537.36'
        self.headers = { 'User-Agent': self.user_agent }
    #获取页面内容
    def getPage(self, url, pageIndex):
        try:
            url = url + str(pageIndex)
            req = urllib2.Request(url, headers = self.headers)
            response = urllib2.urlopen(req)
            html = response.read().decode('utf-8')
            return html
        except urllib2.URLError,e:
            if hasattr(e,"reason"):
                print '无法打开糗事百科,错误原因:',e.reason
                return None

    #正则匹配页面内容中相应的信息: 1:作者 2:内容 3:好笑数 4:评论数 5:当前页数
    def getItems(self, url, pageIndex):
        html = self.getPage(url, pageIndex)
        if not html:
            print '页面加载失败...'
            return None
        #re.S的含义: 使 "." 特殊字符完全匹配任何字符,包括换行;没有这个标志, "." 匹配除了换行外的任何字符。
        pat1 = re.compile('<div class="author clearfix">.*?href.*?<img src.*?title=.*?<h2>(.*?)</h2>.*?<div class="content">.*?<span>(.*?)</span>.*?</div>.*?class="stats">.*?<i class="number">(.*?)</i>.*?<i class="number">(.*?)</i>',re.S)
        items = re.findall(pat1, html)
        pageStories = []
        for item in items:
            replace_br = re.compile('<br/>')
            text = re.sub(replace_br, '\n\t', item[1]) #将<br/>标签替换成<\n\t>.
            pageStories.append([item[0].strip(),text.strip(),item[2].strip(),item[3].strip()])

        return pageStories

            
    #获取当前页的段子,每次输入回车,输出一个段子。
    def getOneStory(self, pageStories, page):
        for story in pageStories:
            input = raw_input("Continue(Enter),Quit(q/Q):").strip()
            if not input:
                print '--------------------'
                print u'作者:%s\n内容:\n\t%s\n好笑数: %s\n评论数: %s\n页数: 第%s页\n' %(story[0],story[1],story[2],story[3],page)
            elif input  in 'qQ':
                print "退出"
                sys.exit("程序退出")
            else:
                print '--------------------'
                print u'作者:%s\n内容:\n\t%s\n好笑数: %s\n评论数: %s\n页数: 第%s页\n' %(story[0],story[1],story[2],story[3],page)

    #主函数,执行调用
    def start(self, url, page=1):
        nowpage = page
        url = url
        while True:
            pageStories = self.getItems(url, nowpage)
            self.getOneStory(pageStories, nowpage)
            nowpage += 1  
if __name__ == '__main__':
    sc1 = QSBK()
    sc1.start('http://www.qiushibaike.com/hot/page/', 2)

*注释: 从第二页开始获取段子信息,效果如下:

*提示: 如果代码失效,问题大部分出现在正则匹配的位置,需要根据糗事百科的页面信息修改相应的正则表达式。

 

posted @ 2016-09-13 14:09  xkops  阅读(788)  评论(0编辑  收藏  举报