全栈工程师开发手册 (作者:栾鹏)
python教程全解

python爬虫案例——百度贴吧数据采集

通过python实现百度贴吧页面的内容采集是相对来说比较容易的,因为百度贴吧不需要登陆,不需要cookie,不需要设置http的MIME头

本案例使用python实现百度贴吧数据采集,获取百度贴吧的文章内容,楼层

百度贴吧网址比如:http://tieba.baidu.com/p/3138733512?see_lz=1&pn=1,这是一个关于NBA50大的盘点,分析一下这个地址。

 http://  代表资源传输使用http协议tieba.baidu.com 是百度的二级域名,指向百度贴吧的服务器。/p/3138733512 是服务器某个资源,即这个帖子的地址定位符see_lz和pn是该URL的两个参数,分别代表了只看楼主和帖子页码,等于1表示该条件为真

所以我们可以把URL分为两部分,一部分为基础部分,一部分为参数部分。

例如,上面的URL我们划分基础部分是 http://tieba.baidu.com/p/3138733512,参数部分是 ?see_lz=1&pn=1

爬虫过程比较简单,基本还是围绕:请求、正则解析、打印存储

注意:python3.4以后中,将urllib2、urlparse、robotparser并入了urllib模块,并且修改了urllib模块,其中包含了5个子模块,每个子模块中的常用方法如下:

python3中的库             包含了子类(python2中)
urllib.error:            ContentTooShortError;URLError;HTTPError
urllib.parse:           urlparse;_splitparams;urlsplit;urlunparse;urlunsplit;urljoin;urldefrag;unquote_to_bytes;unquote;parse_qs;parse_qsl;unquote_plus;quote;quote_plus;quote_from_bytes;urlencode;to_bytes;unwrap;splittype;splithost;splituser;splitpasswd;splitport等;
urllib.request:          urlopen; install_opener; urlretrieve; urlcleanup; request_host; build_opener; _parse_proxy; parse_keqv_list; parse_http_list; _safe_gethostbyname; ftperrors; noheaders; getproxies_environment; proxy_bypass_environment; _proxy_bypass_macosx_sysconf; Request
urllib.response:         addbase; addclosehook; addinfo;addinfourl;
urllib.robotparser:      RobotFileParser

python2.7下

# -*- coding:utf-8 -*-
import urllib
import urllib2
import re#处理页面标签类
class Tool:#去除img标签,7位长空格removeImg = re.compile('<img.*?>| {7}|')#删除超链接标签removeAddr = re.compile('<a.*?>|</a>')#把换行的标签换为\nreplaceLine = re.compile('<tr>|<div>|</div>|</p>')#将表格制表<td>替换为\treplaceTD= re.compile('<td>')#把段落开头换为\n加空两格replacePara = re.compile('<p.*?>')#将换行符或双换行符替换为\nreplaceBR = 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)#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#楼层标号,初始为1self.floor = 1#默认的标题,如果没有成功获取到标题的话则会用这个标题self.defaultTitle = u"百度贴吧"#是否写入楼分隔符的标记self.floorTag = floorTag#传入页码,获取该页帖子的代码def getPage(self,pageNum):try:#构建URLurl = 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.reasonreturn 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 = "\n"+self.tool.replace(item)+"\n"contents.append(content.encode('utf-8'))return contentsdef 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 = "\n" + str(self.floor) + u"-----------------------------------------------------------------------------------------\n"self.file.write(floorLine)self.file.write(item)self.floor += 1print(item)def start(self):indexPage = self.getPage(1)pageNum = self.getPageNum(indexPage)title = self.getTitle(indexPage)self.setFileTitle(title)if pageNum == None:print "URL已失效,请重试"returntry: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.messagefinally:print "写入任务完成"print u"请输入帖子代号"
baseURL = 'http://tieba.baidu.com/p/' + str(raw_input(u'http://tieba.baidu.com/p/'))
seeLZ = raw_input("是否只获取楼主发言,是输入1,否输入0\n")
floorTag = raw_input("是否写入楼层信息,是输入1,否输入0\n")
bdtb = BDTB(baseURL,seeLZ,floorTag)
bdtb.start()

python3.6下

# -*- coding:utf-8 -*-
import urllib.error
import urllib.parse
import urllib.request
import re#处理页面标签类
class Tool:#去除img标签,7位长空格removeImg = re.compile('<img.*?>| {7}|')#删除超链接标签removeAddr = re.compile('<a.*?>|</a>')#把换行的标签换为\nreplaceLine = re.compile('<tr>|<div>|</div>|</p>')#将表格制表<td>替换为\treplaceTD= re.compile('<td>')#把段落开头换为\n加空两格replacePara = re.compile('<p.*?>')#将换行符或双换行符替换为\nreplaceBR = 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)#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#楼层标号,初始为1self.floor = 1#默认的标题,如果没有成功获取到标题的话则会用这个标题self.defaultTitle = u"百度贴吧"#是否写入楼分隔符的标记self.floorTag = floorTag#传入页码,获取该页帖子的代码def getPage(self,pageNum):try:#构建URLurl = self.baseURL+ self.seeLZ + '&pn=' + str(pageNum)request = urllib.request.Request(url)response = urllib.request.urlopen(request)#返回UTF-8格式编码内容return response.read().decode('utf-8')#无法连接,报错except urllib.error.URLError as 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 = "\n"+self.tool.replace(item)+"\n"contents.append(content.encode('utf-8'))return contentsdef 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 = "\n" + str(self.floor) + u"-----------------------------------------------------------------------------------------\n"self.file.write(floorLine)self.file.write(str(item,'utf-8'))self.floor += 1print(str(item,'utf-8'))def start(self):indexPage = self.getPage(1)pageNum = self.getPageNum(indexPage)title = self.getTitle(indexPage)self.setFileTitle(title)if pageNum == None:print("URL已失效,请重试")returntry: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 as e:print("写入异常,原因" + e.message)finally:print("写入任务完成")print("请输入帖子代号")
baseURL = 'http://tieba.baidu.com/p/' + str(input(u'http://tieba.baidu.com/p/'))
seeLZ = input("是否只获取楼主发言,是输入1,否输入0\n")
floorTag = input("是否写入楼层信息,是输入1,否输入0\n")
bdtb = BDTB(baseURL,seeLZ,floorTag)
bdtb.start()

python爬虫案例——百度贴吧数据采集相关推荐

  1. python爬虫案例——糗事百科数据采集

    全栈工程师开发手册 (作者:栾鹏) python教程全解 python爬虫案例--糗事百科数据采集 通过python实现糗事百科页面的内容采集是相对来说比较容易的,因为糗事百科不需要登陆,不需要coo ...

  2. python爬虫案例——csdn数据采集

    全栈工程师开发手册 (作者:栾鹏) python教程全解 python爬虫案例--csdn数据采集 通过python实现csdn页面的内容采集是相对来说比较容易的,因为csdn不需要登陆,不需要coo ...

  3. python爬虫案例-Python爬虫案例集合

    原标题:Python爬虫案例集合 urllib2 urllib2是Python中用来抓取网页的库,urllib2 是 Python2.7 自带的模块(不需要下载,导入即可使用) 在python2.x里 ...

  4. python爬虫简单实例-最简单的Python爬虫案例,看得懂说明你已入门,附赠教程

    原标题:最简单的Python爬虫案例,看得懂说明你已入门,附赠教程 这是最简单的Python爬虫案例,如果你能看懂,那么请你保持信心,因为你已经入门Python爬虫,只要带着信心和努力,你的技术能力在 ...

  5. Python爬虫系列之唯品会商品数据采集

    Python爬虫系列之唯品会商品数据采集 如有疑问点击这里联系我们 微信请扫描下方二维码 代码仅供学习交流,请勿用于非法用途 直接上代码 import requests from queue impo ...

  6. python爬虫获取百度贴吧内容

    python爬虫获取百度贴吧内容 python爬虫获取百度贴吧内容 *声明:本文仅供学习交流使用,请勿用于商业用途,违者后果自负.* python爬虫获取百度贴吧内容 博主是一个比较懒的人,不会按时更 ...

  7. [Python爬虫案例]-中国古诗网

    [Python爬虫案例]-中国古诗网 看懂代码,你需要相关知识 爬虫必备知识 只是想得到目标的话,直接运行就好了 import requests import re import jsondef pa ...

  8. Python 爬虫案例(二)--附件下载

    Python 爬虫案例(二) 此篇文章将爬取的网站是:http://www.warrensburg-mo.com/Bids.aspx (有时候打开不一定会有标书,因为标书实时更新) 类型跟上一篇相似, ...

  9. Python 爬虫 - 获取百度关键字搜索内容

    Python 爬虫 获取百度关键字搜索内容 https://www.cnblogs.com/w0000/p/bd_search_page.html Github headers内的参数,仅有UA时,返 ...

最新文章

  1. 十年公务员转行IT,自学AI三年,他淬炼出746页机器学习入门笔记
  2. 使用元学习来进行少样本图像分类
  3. html制作动态坐标轴,HTML5 canvas制作动态随机星图
  4. 管理本地多个SSH Key
  5. 1085 PAT单位排行 (25 分
  6. ABP理论学习之Abp Session
  7. TDA2030功放电路图
  8. 小米手机的专用计算机连接软件,详细教您小米手机怎么连接电脑
  9. 数字电路中表示频率误差的ppm是什么意思?
  10. 《东周列国志》第七十七回 泣秦庭申包胥借兵 退吴师楚昭王返国
  11. #最短路径,最小生成树#CH 6202 黑暗城堡
  12. Kaggle 时间序列教程
  13. 计算机网络中速率、带宽、吞吐量的区别
  14. linux d14 Apache、 Vsftpd
  15. 努力工作,却永不升职,是种怎样的体验?
  16. Win10 清理备用内存
  17. 面向端到端的情感对话生成研究综述
  18. 使用html2canvas和jspdf把网页保存pdf并下载
  19. 【深度学习】使用labelImg标注图像
  20. Unity2019.4.31f1 通过鼠标和WASD在游戏内控制摄像机移动

热门文章

  1. 没个百来万就想自建技术团队?亲身经历告诉你,一个APP从无到有的开发到底要花多少钱!...
  2. 【数据结构和算法笔记】插入排序(直接插入排序,折半插入排序)
  3. 修改mysql表前缀_使用phpMyAdmin批量修改Mysql数据表前缀的方法
  4. mybatis开启log_mybatis使用spring-druid数据源连接池配置log4j打印sql语句以及开启监控平台...
  5. HDOJ水题集合5:杂题
  6. 【CCCC】L2-006 树的遍历 (25分),根据后序与中序遍历建立二叉树(我讨厌树,系列1)
  7. 2020 年百度之星·程序设计大赛 - 初赛一 Drink
  8. 【luogu3368】模板 树状数组 2
  9. Android替换view父节点,android – issue:指定的子节点已经有父节点.您必须首先在孩子的父母上调用removeView()...
  10. android http 416,HTTP 416 错误 – 所请求的范围无法满足 (Requested Range not satisfiable)...