打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
python爬取贴吧帖子

一、介绍

我们常遇到一些很长的贴吧连载帖子想存到本地再看
此文就是运用python爬取指定百度贴吧的帖子并存到本地满足需求
环境:python2.7
目标网页:【长篇连载】剑网3的正史和野史——从头开始讲剧情故事
源码存放:源码github
本文参考:静觅博客python实战系列


二、页面的抓取

目标网页网址为https://tieba.baidu.com/p/2196794546
满足可以选择是否只看楼主的抓取我们点一下 只看楼主 并点一下后页的链接来获取只看楼主和翻页的参数



这时候可以看到只看楼主多出的参数 see_lz 和当前页的参数 pn

接下来定义一个DEMO类开始获取整个网页

# -*- coding:utf-8 -*-import urllibimport urllib2import reclass DEMO: def __init__(self,baseUrl): self.baseURL = baseUrl def getPage(self): url = baseURL request = urllib2.Request(url) response = urllib2.urlopen(request) print response.read()baseURL = 'https://tieba.baidu.com/p/2196794546?see_lz=1&pn=3'demo = DEMO(baseURL)demo.getPage()

运行结果:


爬取网页代码成功后我们完善一下代码,将只看楼主和页码提为参数

def __init__(self,baseUrl,seeLZ): self.baseURL = baseUrl self.seeLZ = '?see_lz=' str(seeLZ) self.tool = Tool() def getPage(self,pageNum): try: url = self.baseURL self.seeLZ '&pn=' str(pageNum) request = urllib2.Request(url) response = urllib2.urlopen(request) return response.read().decode('utf-8') except urllib2.URLError, e: if hasattr(e,'reson'): print u'链接失败,原因:',e.reason return None

三、提取出想要的信息

打开目标网页审查元素(F12)
首先找到帖子标题的代码段:



<h3 class='core_title_txt pull-left text-overflow ' title='【长篇连载】剑网3的正史和野史——从头开始讲剧情故事' style='width: 416px'>【长篇连载】剑网3的正史和野史——从头开始讲剧情故事</h3>

我们将提取此<h3>里的文本则正则表达式为:

<h3 class='core_title_txt.*?>(.*?)</h3>

接下来我们就可以写一个提取标题的方法:

def getTitle(self,title): page = self.getPage(1) pattern = re.compile('<h3 class='core_title_txt.*?>(.*?)</h3>',re.S) result = re.search(pattern,page) if result: return result.group(1).strip() else: return None

同理找到帖子页数的代码段,可得出提取页数的正则:

<li class='l_reply_num'.*?</span>.*?<span.*?>(.*?)</span>

提取页数的方法:

def getPageNum(self,page): page = self.getPage(1) 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

接下来是我们主要目的,提取正文,正则为:

<div id='post_content_.*?>(.*?)</div>

这个正则提取出来的只是div里面的文本内容,它还会包括了图片标签,换行符,段落符等的标签。所以我们还需处理一下。
这时候添加一个类利用正则将这些标签都替换掉

class Tool: removeImg = re.compile('<img.*?>| {7}|') removeAddr = re.compile('<a.*?>|</a>') replaceLine = re.compile('<tr>|<div>|</div>|</p>') replaceTD = re.compile('<td>') replacePara = re.compile('<p.*?>') replaceBR = 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,'\n',x) x = re.sub(self.replaceTD,'\t',x) x = re.sub(self.replacePara,'\n ',x) x = re.sub(self.replaceBR,'\n',x) x = re.sub(self.removeExtraTag,'',x) return x.strip()

初始化类后,我们可以写提取正文的方法:

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 = '\n' self.tool.replace(item) '\n' contents.append(content.encode('utf-8')) return contents

四、写入文件,保存为txt

def setFileTitle(self,title): 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: self.file.write(item)

五、完善代码

有了以上的方法作为基础,我们来写运行的方法:

def start(self): indexPage = self.getPage(1) pageNum = self.getPageNum(indexPage) title = self.getTitle(indexPage) self.setFileTitle(title) if pageNum == None: print 'URL已失效,请重试' return None 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 '写入任务完成'

此时完成的代码:

# -*- coding:utf-8 -*-import urllibimport urllib2import reclass Tool: removeImg = re.compile('<img.*?>| {7}|') removeAddr = re.compile('<a.*?>|</a>') replaceLine = re.compile('<tr>|<div>|</div>|</p>') replaceTD = re.compile('<td>') replacePara = re.compile('<p.*?>') replaceBR = 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,'\n',x) x = re.sub(self.replaceTD,'\t',x) x = re.sub(self.replacePara,'\n ',x) x = re.sub(self.replaceBR,'\n',x) x = re.sub(self.removeExtraTag,'',x) return x.strip()class DEMO: def __init__(self,baseUrl,seeLZ): self.baseURL = baseUrl self.seeLZ = '?see_lz=' str(seeLZ) self.tool = Tool() def getPage(self,pageNum): try: url = self.baseURL self.seeLZ '&pn=' str(pageNum) request = urllib2.Request(url) response = urllib2.urlopen(request) return response.read().decode('utf-8') except urllib2.URLError, e: if hasattr(e,'reson'): print u'链接失败,原因:',e.reason return None def getTitle(self,title): page = self.getPage(1) pattern = re.compile('<h3 class='core_title_txt.*?>(.*?)</h3>',re.S) result = re.search(pattern,page) if result: return result.group(1).strip() else: return None def getPageNum(self,page): page = self.getPage(1) 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 = '\n' self.tool.replace(item) '\n' contents.append(content.encode('utf-8')) return contents def setFileTitle(self,title): 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: self.file.write(item) def start(self): indexPage = self.getPage(1) pageNum = self.getPageNum(indexPage) title = self.getTitle(indexPage) self.setFileTitle(title) if pageNum == None: print 'URL已失效,请重试' return None 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/' str(raw_input(u'http://tieba.baidu.com/p/'))seeLZ = raw_input('是否只获取楼主发言,是输入1,否输入0\n')demo = DEMO(baseURL,seeLZ)demo.start()

好我们来运行一下试试:




到这里输入目标网页的代号:




整个运行过程:


好,这时候该目录下多了这个txt文件,打开看看



文本已经成功存到本地,到这里就成功了。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
python爬虫实战|如何爬取百度贴吧上的帖子,含源码
Skr-Eric的爬虫课堂(二)——爬虫的解析模块和数据持久化存储
python爬虫爬虫,爬取电影榜单
python 爬虫基础(1)
PAT个人代码的抓取 | WAmaker
Python爬虫实战六之抓取爱问知识人问题并保存至数据库 | 静觅
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服