Python3 简单爬虫爬取百度贴吧帖子

使用Python3.x的版本 对http://tieba.baidu.com/p/2005436135,该百度贴吧帖子进行爬取操作。


一.使用到的库。

1.   urllib.request   :对链接进行解析,以及图片的保存

参考资料:http://www.jb51.net/article/42630.htm

http://www.cnblogs.com/Lands-ljk/p/5447127.html


2.   re   :正则表达式的处理模块

参考资料:http://www.cnblogs.com/huxi/archive/2010/07/04/1771073.html


3.   os   :文件的操作模块

参考资料:http://developer.51cto.com/art/201003/186045.htm


二.对帖子链接的分析。

该帖子是对部分美剧的分析和推荐。

原始链接为:http://tieba.baidu.com/p/2005436135

如果只看楼主的话会变成:http://tieba.baidu.com/p/2005436135?see_lz=1

如果选择第几页的话变成:http://tieba.baidu.com/p/2005436135?see_lz=1&pn=2

可以看出:?see_lz=1是选择只看楼主,?see_lz=0,取消只看楼主,&pn=x , x就是第几页。


三.使用urllib.request模块获取到网页源码。

1.urllib.request.open()  可以直接使用Url作为参数,或者一个Request对象作为参数。

在此使用Request对象作为参数。

request = urllib.request.Request(Url)
response = urllib.request.urlopen(request)


2.read() 方法   将得到的源码显示出来,并且使用decode('utf-8'),进行解码,得到网页源码。

response.read().decode('utf-8')

四.构造方法,得到网页源码。

根据需求可分为只看楼主或者不只看楼主,根据输入的链接Url,是否只看楼主SeeLZ,开始的页数Num,做参数,得到如下代码。

    def getPage(self,Url,SeeLZ,Num):
        if(SeeLZ == 1):
            Url = Url.strip() + '?see_lz=1' + '&pn=' + str(Num)  # strip()去掉字符串左右两边的空格
        if(SeeLZ == 0):
            Url = Url.strip() + '?see_lz=0' + '&pn=' + str(Num)
        try:
            request = urllib.request.Request(Url)
            response = urllib.request.urlopen(request)
            return response.read().decode('utf-8')
        except urllib.request.URLError as e:
            if hasattr(e,'reason'):
                print('连接错误:',e.reason)
                return None

根据传入的参数,完善整个Url,然后返回整个网页源码,在这里使用异常捕捉,来捕捉异常。


五.运用正则表达式得到帖子的题目和回复的数目和页数。

1.得到帖子的题目。

class="core_title_txt member_thread_title_pb" title="【30部屌丝必备美剧】逆袭吧,屌丝。"style="width: 470px">【30部屌丝必备美剧】逆袭吧,屌丝。


在网页源码中可以找到,帖子的题目在这里出现。

编写正则表达式,得到帖子的题目。

    def getTitle(self,page): #得到帖子的题目
        pattern = re.compile(r'


2.得到帖子的回复数目和页数。

与得到帖子题目的做法一致,在网页源码中找到位置,编写正则表达式进行匹配即可。

    def getPageNumAndReply(self,page):   #得到帖子的回复数目和页数
        pattern = re.compile(r'
  • (\d+).*?>(\d+)') result = pattern.search(page) print('该帖子共',result.group(1),'回复 ; 共',result.group(2),'页数') self.pageReply = result.group(1) #得到帖子的总回复 self.pageNum = result.group(2) #得到帖子的总页数


  • 六.得到回复的内容和回复者的名字。

    1.得到原始的回复的内容。

    依然是使用正则表达式对网页源码中的内容进行匹配,分析源码找到回复内容出现的地方。


            pattern = re.compile(r'pattern1 = re.compile(r'src="(.*?)"',re.S)      #用来匹配回复中的照片

    该正则表达式用于在回复的内容中进行匹配。


    若在回复中匹配到图片,则调用另一个保存图片的方法,将该图片进行保存。

        def savePicture(self,Picture,num):
            filepath = os.getcwd() + '\\' + self.name  # 得到文件的路径
            for url in Picture:
                a = 1
                temp = filepath + '\\' + str(num) + '(' + str(a) + ')L.jpg'
                urllib.request.urlretrieve(url, temp)  # 保存到本地文件中
                a += 1


    3.对回复中的其他内容进行处理。

    回复中除了图片以外,还有其他的hrml代码,需要将其转换成相应的内容。

    将回复中的超链接删除掉,将换行符br替换成\n,同是将其他的一些内容删除掉。

        def removeOthers(self,page):
            removeImg = re.compile(r'')        #删除掉图片的链接
            removeAddr = re.compile(r'|')     #删除掉超链接
            replaceBr = re.compile('
    ') #替换换行符 removeOthers = re.compile(r'<.*?>') #删除其他的内容 page = re.sub(removeImg,'',page) page = re.sub(removeAddr,'',page) page = re.sub(replaceBr,'\n',page) page = re.sub(removeOthers,'',page) return page

    4.将回复的内容写入文件中。

    写入文件比较简单,得到工作的目录,然后在目录下创建一个新的文件写入即可。

    写入的同是可以添加一些内容使其看起来更为美观。

        def wiriteFile(self,name,content,num):          #对文件的路劲需要处理
            path = os.getcwd() + '\\' + self.name + '\\' + self.name + r'.txt'  #得到当前工作目录
            path = path.replace('\\','//',1)        #替换目录中的\ 为// ,为创建文件做准备
            file = open(path,'a')
            if num == 1:
                file.write('帖子名称:')
                file.write(self.name)
                file.write('   |   帖子总回复:')
                file.write(self.pageReply)
                file.write('   |   帖子总页数:')
                file.write(self.pageNum)
            file.write('\n----------------------------\n')
            file.write('第')
            num = str(num)
            file.write(num)
            file.write('楼\n\n')
            file.write(name)
            file.write('\n\n')
            file.write(content)
    
            print(num,'楼内容已爬取完成...')


    5.整个得到回复内容的总结。


    使用x变量是对楼层进行统计,在命名图片的时候使用。

        def getContent(self,page):   #得到帖子的回复的内容以及回复者,得到回复中的图片
            pattern = re.compile(r'



    七.将整个内容进行整合。

    可以使用input函数输入相应的Url,Num,SeeLZ等。

    同是在爬取的开始应该建立一个新的文件夹,让得到的内容方便处理。

        def start(self):
            url = input("请输入所要爬取的帖子链接:")
            seeLZ = input("是否只看楼主:")
            Num = input("从第几页开始:")
            if(seeLZ == '是'):
                seeLZ = 1
            if(seeLZ == '否'):
                seeLZ = 0
            self.x = 1
            page = self.getPage(url,seeLZ,Num)
            self.getTitle(page)
            self.getPageNumAndReply(page)
            filepath = os.getcwd() + '\\' + self.name  # 得到文件的路径
            print(filepath)
            if os.path.exists(filepath) is False:
                print('Hlloasdk')
                os.mkdir(filepath)
            y1 = int(Num)
            y2 = int(self.pageNum) + 1
            for y in range(y1,y2):
                page = self.getPage(url, seeLZ, y)
                self.getContent(page)
            print('爬取完成,实际爬取到',self.x-1,'楼!')


    代码:https://github.com/leafage666/SpiderBaiDuTieba/blob/master/Spider

    你可能感兴趣的:(Python)