zoukankan      html  css  js  c++  java
  • Python爬虫爬取贴吧的帖子内容

    最近在看一个大神的博客,从他那里学会了很多关于python爬虫的知识,其实python如果想用在实际应用中,你需要了解许多,比如正则表达式、引入库、过滤字段等等,下面不多说,我下面的程序是爬取Ubuntu吧的一个帖子,要是问我为什么选择Ubuntu吧,没为什么,win、mac、linux我都用,但毫无疑问,我最喜欢的系统就是ubuntu linux,这个系统让我学会了很多东西,从基本命令到shell编程等等,这个系统让我深入了解了操作系统,也让我对操作系统的概念有了进一步的学习和了解,ok,下面就是我的代码,作为参考:

    #coding=utf-8
    # __author__ = 'Abel'
    import urllib
    import urllib2
    import re
    
    #处理页面标签类
    class Tool:
        #去除img标签,7位长空格
        removeImg = re.compile('<img.*?>| {7}|')
        #删除超链接标签
        removeAddr = re.compile('<a.*?>|</a>')
        #把换行的标签换为
    
        replaceLine = re.compile('<tr>|<div>|</div>|</p>')
        #将表格制表<td>替换为	
        replaceTD= re.compile('<td>')
        #把段落开头换为
    加空两格
        replacePara = re.compile('<p.*?>')
        #将换行符或双换行符替换为
    
        replaceBR = re.compile('<br><br>|<br>')
        #将其余标签剔除
        removeExtraTag = re.compile('<.*?>')
        def replace(self,x):
            x = re.sub(self.removeImg,"",x)
            x = re.sub(self.removeAddr,"",x)
            x = re.sub(self.replaceLine,"
    ",x)
            x = re.sub(self.replaceTD,"	",x)
            x = re.sub(self.replacePara,"
        ",x)
            x = re.sub(self.replaceBR,"
    ",x)
            x = re.sub(self.removeExtraTag,"",x)
            #strip()将前后多余内容删除
            return x.strip()
    
    
    #百度贴吧爬虫类
    class BDTB:
    
        #初始化,传入基地址,是否只看楼主的参数
        def __init__(self,baseUrl,seeLZ,floorTag):
            #base链接地址
            self.baseURL = baseUrl
            #是否只看楼主
            self.seeLZ = '?see_lz='+str(seeLZ)
            #HTML标签剔除工具类对象
            self.tool = Tool()
            #全局file变量,文件写入操作对象
            self.file = None
            #楼层标号,初始为1
            self.floor = 1
            #默认的标题,如果没有成功获取到标题的话则会用这个标题
            self.defaultTitle = u"百度贴吧"
            #是否写入楼分隔符的标记
            self.floorTag = floorTag
    
        #传入页码,获取该页帖子的代码
        def getPage(self,pageNum):
            try:
                #构建URL
                url = self.baseURL+ self.seeLZ + '&pn=' + str(pageNum)
                request = urllib2.Request(url)
                response = urllib2.urlopen(request)
                #返回UTF-8格式编码内容
                return response.read().decode('utf-8')
            #无法连接,报错
            except urllib2.URLError, e:
                if hasattr(e,"reason"):
                    print u"连接百度贴吧失败,错误原因",e.reason
                    return None
    
        #获取帖子标题
        def getTitle(self,page):
            #得到标题的正则表达式
            pattern = re.compile('<h1 class="core_title_txt.*?>(.*?)</h1>',re.S)
            result = re.search(pattern,page)
            if result:
                #如果存在,则返回标题
                return result.group(1).strip()
            else:
                return None
    
        #获取帖子一共有多少页
        def getPageNum(self,page):
            #获取帖子页数的正则表达式
            pattern = re.compile('<li class="l_reply_num.*?</span>.*?<span.*?>(.*?)</span>',re.S)
            result = re.search(pattern,page)
            if result:
                return result.group(1).strip()
            else:
                return None
    
        #获取每一层楼的内容,传入页面内容
        def getContent(self,page):
            #匹配所有楼层的内容
            pattern = re.compile('<div id="post_content_.*?>(.*?)</div>',re.S)
            items = re.findall(pattern,page)
            contents = []
            for item in items:
                #将文本进行去除标签处理,同时在前后加入换行符
                content = "
    "+self.tool.replace(item)+"
    "
                contents.append(content.encode('utf-8'))
            return contents
    
        def setFileTitle(self,title):
            #如果标题不是为None,即成功获取到标题
            if title is not None:
                self.file = open(title + ".txt","w+")
            else:
                self.file = open(self.defaultTitle + ".txt","w+")
    
        def writeData(self,contents):
            #向文件写入每一楼的信息
            for item in contents:
                if self.floorTag == '1':
                    #楼之间的分隔符
                    floorLine = "
    " + str(self.floor) + u"-----------------------------------------------------------------------------------------
    "
                    self.file.write(floorLine)
                self.file.write(item)
                self.floor += 1
    
        def start(self):
            indexPage = self.getPage(1)
            pageNum = self.getPageNum(indexPage)
            title = self.getTitle(indexPage)
            self.setFileTitle(title)
            if pageNum == None:
                print "URL已失效,请重试"
                return
            try:
                print "该帖子共有" + str(pageNum) + ""
                for i in range(1,int(pageNum)+1):
                    print "正在写入第" + str(i) + "页数据"
                    page = self.getPage(i)
                    contents = self.getContent(page)
                    self.writeData(contents)
            #出现写入异常
            except IOError,e:
                print "写入异常,原因" + e.message
            finally:
                print "写入任务完成"
    
    
    
    print u"请输入帖子代号"
    baseURL = 'http://tieba.baidu.com/p/3560761301' + str(raw_input(u'http://tieba.baidu.com/p/3560761301'))
    seeLZ = raw_input("是否只获取楼主发言,是输入1,否输入0
    ")
    floorTag = raw_input("是否写入楼层信息,是输入1,否输入0
    ")
    bdtb = BDTB(baseURL,seeLZ,floorTag)
    bdtb.start()

    程序运行结果:


    然后打开工程文件里生成的ubuntu.txt文件,爬取的内容如下:


    是不是很神奇,反正我是感觉很神奇:-)

  • 相关阅读:
    putty相关知识整理
    CSS 必知的7个知识点
    Jquery学习资料链接
    转:Google Chrome浏览调试工具
    CGI小白一些漫想
    css hack
    sublime 使用技巧总结
    转:20个将js推到极致的网站
    转:haslayout:必须要理解的IE渲染概念
    正则表达式学习 (简约版)
  • 原文地址:https://www.cnblogs.com/abelsu/p/4540684.html
Copyright © 2011-2022 走看看