利用python的爬虫技术爬取百度贴吧的帖子
在爬取糗事百科的段子后,我又在知乎上找了一个爬取百度贴吧帖子的实例,为了巩固提升已掌握的爬虫知识,于是我打算自己也做一个。
实现目标:1,爬取楼主所发的帖子
2,显示所爬去的楼层以及帖子题目
3,将爬取的内容写入到文件里,并实现动态显示爬取进度
实现工具:python的requests库和正则表达式以及bs4库
首先我们爬取的帖子网址为:https://tieba.baidu.com/p/3138733512?see_lz=1&pn=1,该网址是只看楼主的帖子的网址,因此该网站的源代码内容均为楼主所发贴的内容,爬取起来也比较方便。我们发现需要爬取的帖子一共有5页,我们可以通过for循环来进行对每一页信息的爬取。
接下来我们来整体构建爬取的思路:
1,爬取该网页的源代码
2,用正则表达式提取所需内容
3,用正则匹配对所取内容进行精准修改以达到我们想要的内容
4,把内容写入到文件并显示写入进度
下面来介绍每一步的具体实现:
首先是获取源代码,这个已经比较简单了,大多数获取源代码的方式都可以用这段代码来实现:
def getHTMLText(url):
try:
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
headers = {'User-Agent': user_agent}
r = requests.get(url,headers = headers)
r.raise_for_status()
r.encoding = r.apparent_encoding
return r.text
except:
return ""
其中的user_agent配置可以在网页的源代码中找到,其目的是将爬虫进行伪装成用户以此来获取更好的爬取体验
接下来我们要通过正则表达式来获取我们需要的“标题”,“帖子主要内容”以及“楼层”信息
通过分析源代码我们发现“标题”在
<title>......</title>
中可以找到,“帖子主要内容”在
<div id="post_content_\d*" class="d_post_content j_d_post_content ">......</div>
中可以找到,“楼层”信息可以在
<span class="tail-info">......</span><span class="tail-info">
中找到。其中“.......”表示所要提取内容,我们分别用两个函数来实现对此的提取
def printTitle(html):
try:
soup = BeautifulSoup(html, "html.parser")
titleTag = soup.find_all('title')
patten = re.compile(r'<title>(.*?)</title>', re.S)
title = re.findall(patten, str(titleTag))
return title
except:
return ""
def fillUnivlist(lis,li,html):
try:
patten = re.compile(r'<div id="post_content_\d*" class="d_post_content j_d_post_content ">(.*?)</div>', re.S)
nbaInfo = re.findall(patten, str(html))
pattenFloor = re.compile(r'<span class="tail-info">(\d*楼)</span><span class="tail-info">', re.S)
floorText = re.findall(pattenFloor, str(html))
number = len(nbaInfo)
for i in range(number):
Info = textTools.remove(nbaInfo[i])
Info1 = textTools.remove(floorText[i])
lis.append(Info1)
li.append(Info)
except:
return ""
我们对每个方法都用try except 来保证其强健性。
但是我们发现我们对所提取的帖子内容有很多多余的成分:
<img class="BDE_Image" src="https://imgsa.baidu.com/forum/w%3D580/sign=cb6ab1f8708b4710ce2ffdc4f3ccc3b2/06381f30e924b899d8ca30e16c061d950b7bf671.jpg" pic_ext="jpeg" pic_type="" width="" height=""><br><br><br><br>50 惊喜新人王 <a href="http://jump2.bdimg.com/safecheck/index?url=x+Z5mMbGPAsY/M/Q/im9DR3tEqEFWbC4Yzg89xsWivS12AkS11WcjnMQsTddE2yXZInIi4k8KEu5449mWp1SxBADVCHPuUFSTGH+WZuV+ecUBG6CY6mAz/Zq1mzxbFxzAG+4Cm4FSU0=" class="ps_cb" target="_blank" onclick="$.stats.track(0, \'nlp_ps_word\',{obj_name:\'迈卡威\'});$.stats.track(\'Pb_content_wordner\',\'ps_callback_statics\')">迈卡威</a><br>上赛季数据<br>篮板 6.2 助攻 6.3 抢断 1.9 盖帽 0.6 失误 3.5 犯规 3 得分 16.7<br><br><br> 新赛季第50位,我给上赛季的新人王<a href="http://jump2.bdimg.com/safecheck/index?url=x+Z5mMbGPAsY/M/Q/im9DR3tEqEFWbC4Yzg89xsWivS12AkS11WcjnMQsTddE2yXZInIi4k8KEu5449mWp1SxBADVCHPuUFSTGH+WZuV+ecUBG6CY6mAz/Zq1mzxbFxzAG+4Cm4FSU0=" class="ps_cb" target="_blank" onclick="$.stats.track(0, \'nlp_ps_word\',{obj_name:\'迈卡威\'});$.stats.track(\'Pb_content_wordner\',\'ps_callback_statics\')">迈卡威</a>。 上赛季迈卡威在彻底重建的<a href="http://jump2.bdimg.com/safecheck/index?url=x+Z5mMbGPAsY/M/Q/im9DR3tEqEFWbC4Yzg89xsWivTbCBRGuF91e6cwvXwi+nOsUCFQWyjKvntqT9uy6c+e1s3eo9XM+kBUaJGaqtq7WOznXcLnooXruQBvuApuBUlN" class="ps_cb" target="_blank" onclick="$.stats.track(0, \'nlp_ps_word\',{obj_name:\'76人\'});$.stats.track(\'Pb_content_wordner\',\'ps_callback_statics\')">76人</a>中迅速掌握了球队,一开始就三双搞定了热火赢得了万千眼球。后来也屡屡有经验的表现,新秀赛季就拿过三双的球员不多,迈卡威现在可以说在76人站稳了脚跟。<br> 作为上赛季弱队的老大,<a href="http://jump2.bdimg.com/safecheck/index?url=x+Z5mMbGPAsY/M/Q/im9DR3tEqEFWbC4Yzg89xsWivS12AkS11WcjnMQsTddE2yXZInIi4k8KEu5449mWp1SxBADVCHPuUFSTGH+WZuV+ecUBG6CY6mAz/Zq1mzxbFxzAG+4Cm4FSU0=" class="ps_cb" target="_blank" onclick="$.stats.track(0, \'nlp_ps_word\',{obj_name:\'迈卡威\'});$.stats.track(\'Pb_content_wordner\',\'ps_callback_statics\')">迈卡威</a>刷出了不错的数据,但我们静下心来看一看他,还是发现他有很多问题。首先,投篮偏弱刚刚40%的命中率和惨淡的26%的三分命中率肯定是不合格的!加之身体瘦弱,个字高大横移速度一般,防守端并没有数据表现得这么好!作为控卫失误偏多,离巨星还是有一定的差距,小子你是一飞冲天,还是迅速陨落,就看你的努力了!<br> 说完缺点,来说说优点,作为后卫篮板球非常突出,高大的身形能较好的影响对方的出手,也能发现己方的空位球员。突破虽然速度一般,但节奏感不错,大局观也在平均水准之上。提醒瘦而高大,不会投篮,突破节奏好,大局观不错!这在几年前说出来是谁?没错断腿前的<a href="http://jump2.bdimg.com/safecheck/index?url=x+Z5mMbGPAsY/M/Q/im9DR3tEqEFWbC4Yzg89xsWivT5ggWFC92MLwFHpDNBmn4rETPyFf5XUHwripOOA15C4U+GRIwDgEI46b99l0XyUM/jR49NyMTc/6qmUGNB+hoByExmB9N/65I=" class="ps_cb" target="_blank" onclick="$.stats.track(0, \'nlp_ps_word\',{obj_name:\'利文斯顿\'});$.stats.track(\'Pb_content_wordner\',\'ps_callback_statics\')">利文斯顿</a>! <br> 就球队地位而言,<a href="http://jump2.bdimg.com/safecheck/index?url=x+Z5mMbGPAsY/M/Q/im9DR3tEqEFWbC4Yzg89xsWivS12AkS11WcjnMQsTddE2yXZInIi4k8KEu5449mWp1SxBADVCHPuUFSTGH+WZuV+ecUBG6CY6mAz/Zq1mzxbFxzAG+4Cm4FSU0=" class="ps_cb" target="_blank" onclick="$.stats.track(0, \'nlp_ps_word\',{obj_name:\'迈卡威\'});$.stats.track(\'Pb_content_wordner\',\'ps_callback_statics\')">迈卡威</a>现在是绝对的老大,球你想怎么玩就怎么玩,数据你想怎么刷就怎么刷!去年的潜力新人<a href="http://jump2.bdimg.com/safecheck/index?url=x+Z5mMbGPAsY/M/Q/im9DR3tEqEFWbC4Yzg89xsWivTKm3O5uii9sKBrDcAE8/xDK4qTjgNeQuFPhkSMA4BCOOm/fZdF8lDP40ePTcjE3P+qplBjQfoaAchMZgfTf+uS" class="ps_cb" target="_blank" onclick="$.stats.track(0, \'nlp_ps_word\',{obj_name:\'诺尔\'});$.stats.track(\'Pb_content_wordner\',\'ps_callback_statics\')">诺尔</a>是<a href="http://jump2.bdimg.com/safecheck/index?url=x+Z5mMbGPAsY/M/Q/im9DR3tEqEFWbC4Yzg89xsWivQdeSiO+EjvouPd1sAEaAOyK4qTjgNeQuFPhkSMA4BCOOm/fZdF8lDP40ePTcjE3P+qplBjQfoaAchMZgfTf+uS" class="ps_cb" target="_blank" onclick="$.stats.track(0, \'nlp_ps_word\',{obj_name:\'蓝领\'});$.stats.track(\'Pb_content_wordner\',\'ps_callback_statics\')">蓝领</a>,其他人都可以清退,恩比德还受伤不能打,<a href="http://jump2.bdimg.com/safecheck/index?url=x+Z5mMbGPAsY/M/Q/im9DR3tEqEFWbC4Yzg89xsWivTbCBRGuF91e6cwvXwi+nOsUCFQWyjKvntqT9uy6c+e1s3eo9XM+kBUaJGaqtq7WOznXcLnooXruQBvuApuBUlN" class="ps_cb" target="_blank" onclick="$.stats.track(0, \'nlp_ps_word\',{obj_name:\'76人\'});$.stats.track(\'Pb_content_wordner\',\'ps_callback_statics\')">76人</a>队的战绩怎么样,就看你了!但是等到诺尔成熟(假如不是水货),恩比德伤愈(他技术上不可能水,只是看伤病了)你就有一队很好的内线组合了!你能把他们带成什么成绩,这时候就是考验你迈卡威除了刷数据还有什么能力的时候了。'
这段提取的信息里有着大量多余的信息,因此需要我们进行细分,基本思路为将多余的信息用正则匹配出来,然后利用正则的替换方法把这些多余的内容替换为空格或者换行
在这里,我们来构建一个处理信息的类
class Tools:
removeImg = re.compile('<img.*?>')
removBr = re.compile('<br>')
removeHef = re.compile('<a href.*?>')
removeA = re.compile('</a>')
removeClass = re.compile('<a class.*?>|<aclass.*?>')
removeNull = re.compile(' ') def remove(self,te):
te = re.sub(self.removeImg,'',te)
te = re. sub(self.removBr,'\n',te)
te = re.sub(self.removeHef,'',te)
te = re.sub(self.removeA,'',te)
te = re.sub(self.removeClass,'',te)
te = re.sub(self.removeNull, '', te)
return te
将刚才乱码的信息经过这个类的处理后,我们可以得到下列信息:
50惊喜新人王迈卡威
上赛季数据
篮板6.2助攻6.3抢断1.9盖帽0.6失误3.5犯规3得分16.7 新赛季第50位,我给上赛季的新人王迈卡威。上赛季迈卡威在彻底重建的76人中迅速掌握了球队,一开始就三双搞定了热火赢得了万千眼球。后来也屡屡有经验的表现,新秀赛季就拿过三双的球员不多,迈卡威现在可以说在76人站稳了脚跟。
作为上赛季弱队的老大,迈卡威刷出了不错的数据,但我们静下心来看一看他,还是发现他有很多问题。首先,投篮偏弱刚刚40%的命中率和惨淡的26%的三分命中率肯定是不合格的!加之身体瘦弱,个字高大横移速度一般,防守端并没有数据表现得这么好!作为控卫失误偏多,离巨星还是有一定的差距,小子你是一飞冲天,还是迅速陨落,就看你的努力了!
说完缺点,来说说优点,作为后卫篮板球非常突出,高大的身形能较好的影响对方的出手,也能发现己方的空位球员。突破虽然速度一般,但节奏感不错,大局观也在平均水准之上。提醒瘦而高大,不会投篮,突破节奏好,大局观不错!这在几年前说出来是谁?没错断腿前的利文斯顿!
就球队地位而言,迈卡威现在是绝对的老大,球你想怎么玩就怎么玩,数据你想怎么刷就怎么刷!去年的潜力新人诺尔是蓝领,其他人都可以清退,恩比德还受伤不能打,76人队的战绩怎么样,就看你了!但是等到诺尔成熟(假如不是水货),恩比德伤愈(他技术上不可能水,只是看伤病了)你就有一队很好的内线组合了!你能把他们带成什么成绩,这时候就是考验你迈卡威除了刷数据还有什么能力的时候了。
这样的表达效果就可以让我清晰看到提取到的信息,所以这个类是成功的。接下来我们只需要将提取的信息输出就行。
我们先写一个写入标题信息和主体内容的方法,因为标题只在第一个网页上所以可以单独写一个方法
def writeText(titleText,fpath):
try:
with open(fpath, 'a', encoding='utf-8') as f:
f.write(str(titleText) + '\n')
f.write('\n')
f.close()
except:
return ""
def writeUnivlist(lis,li,fpath,num):
with open(fpath, 'a', encoding='utf-8') as f:
for i in range(num):
f.write(str(lis[i])+'\n')
f.write('*'*50 + '\n')
f.write(str(li[i]) + '\n')
f.write('*' * 50 + '\n')
f.close()
接下来我们只需要写一个执行的主函数即可,我们定义一下所要写入文件的路径,然后先写入文件的标题
count = 0
url = 'https://tieba.baidu.com/p/3138733512?see_lz=1&pn=1'
output_file = 'D:/StockInfo.txt'
html = getHTMLText(url)
titleText = printTitle(html)
writeText(titleText, output_file)
接下来利用for循环来实现对每个网页的信息的输入,并打印写入文件的进度
for i in range(5):
i = i + 1
lis = []
li = []
url = 'https://tieba.baidu.com/p/3138733512?see_lz=1&pn=' + str(i)
html = getHTMLText(url)
fillUnivlist(lis, li, html)
writeUnivlist(lis, li, output_file, len(lis))
count = count + 1
print("\r当前进度: {:.2f}%".format(count * 100 / 5), end="")
以上就是爬取百度贴吧的帖子的所以内容,最后我认为如果我们将这些函数方法封装成一个类,效果会更好。
以下是全部代码
import requests
from bs4 import BeautifulSoup
import re class Tools:
removeImg = re.compile('<img.*?>')
removBr = re.compile('<br>')
removeHef = re.compile('<a href.*?>')
removeA = re.compile('</a>')
removeClass = re.compile('<a class.*?>|<aclass.*?>')
removeNull = re.compile(' ') def remove(self,te):
te = re.sub(self.removeImg,'',te)
te = re. sub(self.removBr,'\n',te)
te = re.sub(self.removeHef,'',te)
te = re.sub(self.removeA,'',te)
te = re.sub(self.removeClass,'',te)
te = re.sub(self.removeNull, '', te)
return te textTools = Tools() def getHTMLText(url):
try:
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
headers = {'User-Agent': user_agent}
r = requests.get(url,headers = headers)
r.raise_for_status()
r.encoding = r.apparent_encoding
return r.text
except:
return "" def printTitle(html):
try:
soup = BeautifulSoup(html, "html.parser")
titleTag = soup.find_all('title')
patten = re.compile(r'<title>(.*?)</title>', re.S)
title = re.findall(patten, str(titleTag))
return title
except:
return "" def fillUnivlist(lis,li,html):
try:
patten = re.compile(r'<div id="post_content_\d*" class="d_post_content j_d_post_content ">(.*?)</div>', re.S)
nbaInfo = re.findall(patten, str(html))
pattenFloor = re.compile(r'<span class="tail-info">(\d*楼)</span><span class="tail-info">', re.S)
floorText = re.findall(pattenFloor, str(html))
number = len(nbaInfo)
for i in range(number):
Info = textTools.remove(nbaInfo[i])
Info1 = textTools.remove(floorText[i])
lis.append(Info1)
li.append(Info)
except:
return "" def writeText(titleText,fpath):
try:
with open(fpath, 'a', encoding='utf-8') as f:
f.write(str(titleText) + '\n')
f.write('\n')
f.close()
except:
return "" def writeUnivlist(lis,li,fpath,num):
with open(fpath, 'a', encoding='utf-8') as f:
for i in range(num):
f.write(str(lis[i])+'\n')
f.write('*'*50 + '\n')
f.write(str(li[i]) + '\n')
f.write('*' * 50 + '\n')
f.close() def main():
count = 0
url = 'https://tieba.baidu.com/p/3138733512?see_lz=1&pn=1'
output_file = 'D:/StockInfo.txt'
html = getHTMLText(url)
titleText = printTitle(html)
writeText(titleText, output_file)
for i in range(5):
i = i + 1
lis = []
li = []
url = 'https://tieba.baidu.com/p/3138733512?see_lz=1&pn=' + str(i)
html = getHTMLText(url)
fillUnivlist(lis, li, html)
writeUnivlist(lis, li, output_file, len(lis))
count = count + 1
print("\r当前进度: {:.2f}%".format(count * 100 / 5), end="") main()
这个还有很多完善的地方,希望大家多多指教
-------来自一个热爱自学编程的小白
利用python的爬虫技术爬取百度贴吧的帖子的更多相关文章
- 利用python的爬虫技术爬去糗事百科的段子
初次学习爬虫技术,在知乎上看了如何爬去糗事百科的段子,于是打算自己也做一个. 实现目标:1,爬取到糗事百科的段子 2,实现每次爬去一个段子,每按一次回车爬取到下一页 技术实现:基于python的实现, ...
- 使用htmlparse爬虫技术爬取电影网页的全部下载链接
昨天,我们利用webcollector爬虫技术爬取了网易云音乐17万多首歌曲,而且还包括付费的在内,如果时间允许的话,可以获取更多的音乐下来,当然,也有小伙伴留言说这样会降低国人的知识产权保护意识,诚 ...
- 使用htmlparser爬虫技术爬取电影网页的全部下载链接
昨天,我们利用webcollector爬虫技术爬取了网易云音乐17万多首歌曲,而且还包括付费的在内,如果时间允许的话,可以获取更多的音乐下来,当然,也有小伙伴留言说这样会降低国人的知识产权保护意识,诚 ...
- 第三百三十四节,web爬虫讲解2—Scrapy框架爬虫—Scrapy爬取百度新闻,爬取Ajax动态生成的信息
第三百三十四节,web爬虫讲解2—Scrapy框架爬虫—Scrapy爬取百度新闻,爬取Ajax动态生成的信息 crapy爬取百度新闻,爬取Ajax动态生成的信息,抓取百度新闻首页的新闻rul地址 有多 ...
- python网络爬虫《爬取get请求的页面数据》
一.urllib库 urllib是python自带的一个用于爬虫的库,其主要作用就是可以通过代码模拟浏览器发送请求.其常被用到的子模块在python3中的为urllib.request和urllib. ...
- 十三 web爬虫讲解2—Scrapy框架爬虫—Scrapy爬取百度新闻,爬取Ajax动态生成的信息
crapy爬取百度新闻,爬取Ajax动态生成的信息,抓取百度新闻首页的新闻rul地址 有多网站,当你浏览器访问时看到的信息,在html源文件里却找不到,由得信息还是滚动条滚动到对应的位置后才显示信息, ...
- Python爬虫爬取百度贴吧的帖子
同样是参考网上教程,编写爬取贴吧帖子的内容,同时把爬取的帖子保存到本地文档: #!/usr/bin/python#_*_coding:utf-8_*_import urllibimport urlli ...
- python爬虫之爬取百度图片
##author:wuhao##爬取指定页码的图片,如果需要爬取某一类的所有图片,整体框架不变,但需要另作分析#import urllib.requestimport urllib.parseimpo ...
- java爬虫实现爬取百度风云榜Top10
最近在项目中遇到了java和python爬虫进行程序调用和接口对接的问题, 刚开始也是调试了好久才得出点门道. 而后,自己也发现了爬虫的好玩之处,边想着用java来写个爬虫玩玩,虽说是个不起眼的dem ...
随机推荐
- [html] 学习笔记-Canvas图形绘制处理
使用Canvas API 可以将一个图形重叠绘制在另外一个图形上,也可以给图形添加阴影效果. 1.Canvas 图形组合 通过 globalCompositeOperation = 属性 来指定重叠效 ...
- Windows 10 IoT Serials 5 - 如何为树莓派应用程序添加语音识别与交互功能
都说语音是人机交互的重要手段,虽然个人觉得在大庭广众之下,对着手机发号施令会显得有些尴尬.但是在资源受限的物联网应用场景下(无法外接鼠标键盘显示器),如果能够通过语音来控制设备,与设备进行交互,那还是 ...
- 如何在linux下制作一个windows的可启动u盘?
如何在linux下制作一个windows的可启动u盘? 情景是这样的,有一个windows10的iso,现在想通过U盘安装,要求即支持UEFI(启动引导器),又支持Legacy(启动引导器),因为有一 ...
- JAVA内存关注总结,作为个程序员需要对自己系统的每块内存做到了如指掌
服务器的JAVA进程使用的内存是否正常 服务器中,JAVA进程的内存占用= JVM内存+ JAVA堆最大内存大小(Xmx)+JAVA堆外内存大小+栈区( 线程数* Xss) 最需要关注: 1., 服务 ...
- 基于服务的SOA架构_后续篇
今天是元宵节,首先祝各位广大博友在接下来的光阴中技术更上一层,事事如意! 昨天简单介绍了一下本人在近期开发过的一个电商购物平台的架构流程和一些技术说明:今天将详细总结一下在项目中用到的各个架构技术的环 ...
- PHP文件上传处理
web中,文件上传是一个很常用的功能.如:上传头像.上传图片.这些提交到后台的图片都要交给后端处理.php提供了几个上传处理的函数,我把它们封装成类,以便日后使用. 处理流程(可能有不合理的地方,用时 ...
- VS2008编译汇编程序的问题
在VS2008 pro里已经集成了MASM,经过相关设置后,编译出了程序,但是执行后,说少msvcr90.dll39944然后自己写了个39945 那个testprintf是执行正常的.虽然两个都有引 ...
- Linux系统(一)文件系统、压缩、打包操作总结
序言 当前的形势,.Net已经开源,.Net Core 正在跨平台,可见微软巨人在努力,在改变,在进步,在走向春天.从前被微软供作上帝的.Net从业者,如果不打开心扉面向开源,改变自己,那么很可能在不 ...
- wikioi 3132 高精度乘法(FFT)
第一次学FFT,先膜拜一下法法塔大神ORZ 关于FFT的话,有一篇博文特别赞http://z55250825.blog.163.com/blog/static/15023080920143127465 ...
- BZOJ 1898: [Zjoi2004]Swamp 沼泽鳄鱼(矩阵乘法)
可以发现,如果没有鳄鱼,那么就是裸地一道题,但是可以发现鳄鱼最多每12次重复,那么就少于12的那部分dp,其他的就矩阵乘法就行了 PS:第一次吧矩阵乘法AC了好开心QAQ CODE: #include ...