简单的python爬虫程序(爬取百度贴吧帖子)

因刚刚开始学习python,水平有限,仅供参考,如果错误,欢迎大家在指出改正!


1.URL 地址分析

我选取的一个百度贴吧帖子的网址是http://tieba.baidu.com/p/4739169817(这是一个秦时明月吧的帖子,因小弟是秦迷),各位可以点击进去查看一下。

如果点击只看楼主或者翻页,则会产生两个参数http://tieba.baidu.com/p/4739169817?pn=2或http://tieba.baidu.com/p/4739169817?see_lz=1,分析一下该网址如下:

  • http://tieba.baidu.com/p/4739169817?see_lz=1 这是网址
  • see_lz 该参数表示是否只看楼主发的帖子,1表示true
  • pn 该参数表示表示第几页

2.页面抓取

我们构建一个类BDTB,该类作为爬取百度贴吧的主要的类,我们利用urllib包中的方法urlopen。
我选用的python版本为:python3.5,所以urllib包下又有四个包,分别为requeset、error…(详情可查看官方文档)
代码如下:

import urllib.request
import urllib.error
import re

#百度贴吧爬虫类
class BDTB:
    def __init__(self, baseUrl, seeLZ):
        self.baseURL = baseUrl
        self.seeLZ = '?see_LZ=' + str(seeLZ)
        self.tool = Tool()
        self.file = None
        self.defaultFileTitile = u'百度贴吧'
        self.floor = 1

    def getPage(self, pageNum):
        try:
            url = self.baseURL + self.seeLZ + '&pn=' + str(pageNum)
            request = urllib.request.Request(url)
            response = urllib.request.urlopen(request)
            return response.read().decode('utf-8')
        except urllib.error.URLError as e:
                print('连接百度贴吧失败,原因为:' + e.reason)
                return None

方法getPage()爬取页面中的全部内容,参数pageNum为访问的页码。

3.利用正则表达式提取需要的信息

3.1 提取帖子标题

我们可查看提取出的html文件中的标题处的代码,例如:

<h3 class="core_title_txt pull-left text-overflow  " title="可能不是胜七弱,而是我们低估了骨妖梅三娘" style="width: 396px">可能不是胜七弱,而是我们低估了骨妖梅三娘h3>

我写的正则表达式为:

="core_title_txt pull-left text-overflow.*?>(.*?)

因此代码为:

    #获取帖子标题
    def getTitle(self):
        page = self.getPage(1)
        pattern = re.compile('

if result: return result.group(1) else: return None

3.2获取帖子总数

总起来说分析html代码中的共几页的,然后书写正则表达式。

    #获取帖子一共有多少页
    def getPageNum(self):
        page = self.getPage(1)
        pattern = re.compile('
  • if result: return result.group(1).strip() else: return None
  • 3.3提取正文中的内容

    核心问题是分析代码主体中的想要提取的内容,根据具体的标签分析出正则表达式,不多说,代码如下:

        #获取每一层楼的内容
        def getContent(self, page):
            pattern = re.compile('
    return result

    大家还运行一下结果会发现,提取出来内容,里面还有好多img\br等标签,所以可以写一个类或者方法,将其中的去除掉。代码如下:

    class Tool:
        removeTag = re.compile('<.*?>', re.I)
        def replace(self, x):
            x = re.sub(self.removeTag, '\n',  x)
            return x.strip()

    我写的是一个类,很简单,当然您也可以丰富起来。

    3.4将爬下来的内容写入文件中

    代码很简单,大家都会写:

        file = open(“tb.txt”,”w”)
    
        file.writelines(obj)

    4.全部代码

    全部代码,未经整理,优化,仅供参考:

    #爬取百度贴吧中的帖子的内容
    import urllib.request
    import urllib.error
    import re
    
    class Tool:
        removeTag = re.compile('<.*?>', re.I)
        def replace(self, x):
            x = re.sub(self.removeTag, '\n',  x)
            return x.strip()
    
    #百度贴吧爬虫类
    class BDTB:
        def __init__(self, baseUrl, seeLZ):
            self.baseURL = baseUrl
            self.seeLZ = '?see_LZ=' + str(seeLZ)
            self.tool = Tool()
            self.file = None
            self.defaultFileTitile = u'百度贴吧'
            self.floor = 1
    
        def getPage(self, pageNum):
            try:
                url = self.baseURL + self.seeLZ + '&pn=' + str(pageNum)
                request = urllib.request.Request(url)
                response = urllib.request.urlopen(request)
                return response.read().decode('utf-8')
            except urllib.error.URLError as e:
                    print('连接百度贴吧失败,原因为:' + e.reason)
                    return None
        #获取帖子标题
        def getTitle(self):
            page = self.getPage(1)
            pattern = re.compile('

    if result: return result.group(1) else: return None #获取帖子一共有多少页 def getPageNum(self): page = self.getPage(1) pattern = re.compile('
  • if result: return result.group(1).strip() else: return None #获取每一层楼的内容 def getContent(self, page): pattern = re.compile('
    return result def setFileTitle(self, title): if title is not None: self.file = open(title + '.txt', 'w') else: self.file = open(self.defaultFileTitile + '.txt', 'w') def writeData(self, contents): for item in contents: item = self.tool.replace(item) self.file.write(str(self.floor)+'楼--------------------------------------------------------------------\n') self.file.write(item + '\n') self.floor += 1 baseUrl = 'http://tieba.baidu.com/p/4739169817' seeLZ = 1 bdtb = BDTB(baseUrl, seeLZ) bdtb.setFileTitle(bdtb.getTitle()) bdtb.writeData(bdtb.getContent(bdtb.getPage(1)))
  • 你可能感兴趣的:(python)