美文网首页Python新世界
Python爬虫案例——百度贴吧数据采集!最适合零基础的案例之一

Python爬虫案例——百度贴吧数据采集!最适合零基础的案例之一

作者: 919b0c54458f | 来源:发表于2018-11-21 13:57 被阅读19次

通过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表示该条件为真

进群:548377875  即可获取数十套PDF以及大量的学习教程,代码最好不要复制粘贴,自己照着敲一遍也好呢!

所以我们可以把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('| {7}|')

#删除超链接标签

removeAddr = re.compile('|')

#把换行的标签换为

replaceLine = re.compile('|

||')

#将表格制表替换为

replaceTD= re.compile('')

#把段落开头换为加空两格

replacePara = re.compile('')

#将换行符或双换行符替换为

replaceBR = re.compile('

|
')

#将其余标签剔除

removeExtraTag = re.compile('<.*?>')

def replace(self,x):

x = re.sub(self.removeImg,"",x)

x = re.sub(self.removeAddr,"",x)

x = re.sub(self.replaceLine,"",x)

x = re.sub(self.replaceTD,"",x)

x = re.sub(self.replacePara," ",x)

x = re.sub(self.replaceBR,"",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

#楼层标号,初始为1

self.floor = 1

#默认的标题,如果没有成功获取到标题的话则会用这个标题

self.defaultTitle = u"百度贴吧"

#是否写入楼分隔符的标记

self.floorTag = floorTag

#传入页码,获取该页帖子的代码

def getPage(self,pageNum):

try:

#构建URL

url = 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.reason

return None

#获取帖子标题

def getTitle(self,page):

#得到标题的正则表达式

pattern = re.compile('

result = re.search(pattern,page)

if result:

#如果存在,则返回标题

return result.group(1).strip()

else:

return None

#获取帖子一共有多少页

def getPageNum(self,page):

#获取帖子页数的正则表达式

pattern = re.compile('

result = re.search(pattern,page)

if result:

return result.group(1).strip()

else:

return None

#获取每一层楼的内容,传入页面内容

def getContent(self,page):

#匹配所有楼层的内容

pattern = re.compile('

items = re.findall(pattern,page)

contents = []

for item in items:

#将文本进行去除标签处理,同时在前后加入换行符

content = ""+self.tool.replace(item)+""

contents.append(content.encode('utf-8'))

return contents

def 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 = "" + str(self.floor) + u"-----------------------------------------------------------------------------------------"

self.file.write(floorLine)

self.file.write(item)

self.floor += 1

print(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

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")

floorTag = raw_input("是否写入楼层信息,是输入1,否输入0")

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('| {7}|')

#删除超链接标签

removeAddr = re.compile('|')

#把换行的标签换为

replaceLine = re.compile('|

||')

#将表格制表替换为

replaceTD= re.compile('')

#把段落开头换为加空两格

replacePara = re.compile('')

#将换行符或双换行符替换为

replaceBR = re.compile('

|
')

#将其余标签剔除

removeExtraTag = re.compile('<.*?>')

def replace(self,x):

x = re.sub(self.removeImg,"",x)

x = re.sub(self.removeAddr,"",x)

x = re.sub(self.replaceLine,"",x)

x = re.sub(self.replaceTD,"",x)

x = re.sub(self.replacePara," ",x)

x = re.sub(self.replaceBR,"",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

#楼层标号,初始为1

self.floor = 1

#默认的标题,如果没有成功获取到标题的话则会用这个标题

self.defaultTitle = u"百度贴吧"

#是否写入楼分隔符的标记

self.floorTag = floorTag

#传入页码,获取该页帖子的代码

def getPage(self,pageNum):

try:

#构建URL

url = 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('

result = re.search(pattern,page)

if result:

#如果存在,则返回标题

return result.group(1).strip()

else:

return None

#获取帖子一共有多少页

def getPageNum(self,page):

#获取帖子页数的正则表达式

pattern = re.compile('

result = re.search(pattern,page)

if result:

return result.group(1).strip()

else:

return None

#获取每一层楼的内容,传入页面内容

def getContent(self,page):

#匹配所有楼层的内容

pattern = re.compile('

items = re.findall(pattern,page)

contents = []

for item in items:

#将文本进行去除标签处理,同时在前后加入换行符

content = ""+self.tool.replace(item)+""

contents.append(content.encode('utf-8'))

return contents

def 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 = "" + str(self.floor) + u"-----------------------------------------------------------------------------------------"

self.file.write(floorLine)

self.file.write(str(item,'utf-8'))

self.floor += 1

print(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已失效,请重试")

return

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 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")

floorTag = input("是否写入楼层信息,是输入1,否输入0")

bdtb = BDTB(baseURL,seeLZ,floorTag)

bdtb.start()

相关文章

网友评论

    本文标题:Python爬虫案例——百度贴吧数据采集!最适合零基础的案例之一

    本文链接:https://www.haomeiwen.com/subject/bsfcqqtx.html