python爬虫案例——百度贴吧数据采集
全栈工程师开发手册 (作者:栾鹏)
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爬虫案例——百度贴吧数据采集相关推荐
- python爬虫案例——糗事百科数据采集
全栈工程师开发手册 (作者:栾鹏) python教程全解 python爬虫案例--糗事百科数据采集 通过python实现糗事百科页面的内容采集是相对来说比较容易的,因为糗事百科不需要登陆,不需要coo ...
- python爬虫案例——csdn数据采集
全栈工程师开发手册 (作者:栾鹏) python教程全解 python爬虫案例--csdn数据采集 通过python实现csdn页面的内容采集是相对来说比较容易的,因为csdn不需要登陆,不需要coo ...
- python爬虫案例-Python爬虫案例集合
原标题:Python爬虫案例集合 urllib2 urllib2是Python中用来抓取网页的库,urllib2 是 Python2.7 自带的模块(不需要下载,导入即可使用) 在python2.x里 ...
- python爬虫简单实例-最简单的Python爬虫案例,看得懂说明你已入门,附赠教程
原标题:最简单的Python爬虫案例,看得懂说明你已入门,附赠教程 这是最简单的Python爬虫案例,如果你能看懂,那么请你保持信心,因为你已经入门Python爬虫,只要带着信心和努力,你的技术能力在 ...
- Python爬虫系列之唯品会商品数据采集
Python爬虫系列之唯品会商品数据采集 如有疑问点击这里联系我们 微信请扫描下方二维码 代码仅供学习交流,请勿用于非法用途 直接上代码 import requests from queue impo ...
- python爬虫获取百度贴吧内容
python爬虫获取百度贴吧内容 python爬虫获取百度贴吧内容 *声明:本文仅供学习交流使用,请勿用于商业用途,违者后果自负.* python爬虫获取百度贴吧内容 博主是一个比较懒的人,不会按时更 ...
- [Python爬虫案例]-中国古诗网
[Python爬虫案例]-中国古诗网 看懂代码,你需要相关知识 爬虫必备知识 只是想得到目标的话,直接运行就好了 import requests import re import jsondef pa ...
- Python 爬虫案例(二)--附件下载
Python 爬虫案例(二) 此篇文章将爬取的网站是:http://www.warrensburg-mo.com/Bids.aspx (有时候打开不一定会有标书,因为标书实时更新) 类型跟上一篇相似, ...
- Python 爬虫 - 获取百度关键字搜索内容
Python 爬虫 获取百度关键字搜索内容 https://www.cnblogs.com/w0000/p/bd_search_page.html Github headers内的参数,仅有UA时,返 ...
最新文章
- 十年公务员转行IT,自学AI三年,他淬炼出746页机器学习入门笔记
- 使用元学习来进行少样本图像分类
- html制作动态坐标轴,HTML5 canvas制作动态随机星图
- 管理本地多个SSH Key
- 1085 PAT单位排行 (25 分
- ABP理论学习之Abp Session
- TDA2030功放电路图
- 小米手机的专用计算机连接软件,详细教您小米手机怎么连接电脑
- 数字电路中表示频率误差的ppm是什么意思?
- 《东周列国志》第七十七回 泣秦庭申包胥借兵 退吴师楚昭王返国
- #最短路径,最小生成树#CH 6202 黑暗城堡
- Kaggle 时间序列教程
- 计算机网络中速率、带宽、吞吐量的区别
- linux d14 Apache、 Vsftpd
- 努力工作,却永不升职,是种怎样的体验?
- Win10 清理备用内存
- 面向端到端的情感对话生成研究综述
- 使用html2canvas和jspdf把网页保存pdf并下载
- 【深度学习】使用labelImg标注图像
- Unity2019.4.31f1 通过鼠标和WASD在游戏内控制摄像机移动
热门文章
- 没个百来万就想自建技术团队?亲身经历告诉你,一个APP从无到有的开发到底要花多少钱!...
- 【数据结构和算法笔记】插入排序(直接插入排序,折半插入排序)
- 修改mysql表前缀_使用phpMyAdmin批量修改Mysql数据表前缀的方法
- mybatis开启log_mybatis使用spring-druid数据源连接池配置log4j打印sql语句以及开启监控平台...
- HDOJ水题集合5:杂题
- 【CCCC】L2-006 树的遍历 (25分),根据后序与中序遍历建立二叉树(我讨厌树,系列1)
- 2020 年百度之星·程序设计大赛 - 初赛一 Drink
- 【luogu3368】模板 树状数组 2
- Android替换view父节点,android – issue:指定的子节点已经有父节点.您必须首先在孩子的父母上调用removeView()...
- android http 416,HTTP 416 错误 – 所请求的范围无法满足 (Requested Range not satisfiable)...