首先用直接的方法写,先尝试下能否爬取成功
#coding:utf-8
import urllib2,urllib
import re
'''
1.准备url地址
2.准备请求头
3.创建请求对象
4.发起请求获取第一页源代码,接收响应
5.通过第一页源代码,找到总页数和标题
6.for循环执行总页数次
6.1 根据页码拼接完整的URL地址
6.2 创建request对象,发起请求,接受响应
6.3 根据正则匹配数据,包含用户名和帖子内容
6.4 去除、替换数据中的html标签
6.5 写入本地文件
'''
ide = raw_input('请输入要爬取的帖子的编号:')
#1准备url地址
url = 'https://tieba.baidu.com/p/'+ide
#2准备请求头
headers = {
'User-Agent':'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50'
}
#3创建请求对象
request = urllib2.Request(url,headers=headers)
#4发起请求获取第一页源代码,接受响应
response = urllib2.urlopen(request)
# 5.通过第一页源代码,找到总页数和标题
#5.1准备正则
pattern = re.compile(r'<li class="l_reply_num.*?<span.*?<span class="red">(.*?)</span>',re.S)
#5.2查找对应正则的数据
html = response.read()
rs = re.search(pattern,html)
#5.3把字符串页数转换为数字
total = int(rs.group(1))
# 5.4 正则匹配标题
tit_pattern = re.compile(r'<h\d class="core_title_txt.*?>(.*?)</h\d>',re.S)
#5.5从源代码中搜索标题
rs = re.search(tit_pattern,html)
print rs.group(1)
title = rs.group(1)
#拼接文件名
#decode()解码,网页中的字符是utf-8编码,在python中使用的字符串都是Unicode编码,所以需要转换
filename = "%s.txt"%title.decode('utf-8')
#打开文件
file = open(filename,'w')
print '正在爬取%s,共%s页数据'%(title,total)
#6.for循环执行总页数次
for x in range(1,total+1):
print '正在爬取第%s页数据'%x
# 6.1根据页码拼接完整的URL地址
getUrl = url+'?pn=%s'%x
# 6.2创建request对象,发起请求,接受响应
request = urllib2.Request(getUrl,headers=headers)
response = urllib2.urlopen(request)
html = response.read()
# 6.3根据正则匹配数据,包含用户名和帖子内容
con_pattern = re.compile(r'<ul class="p_author.*?<li class="d_name.*?<a.*?>(.*?)</a>.*?<div id="post_content_.*?>(.*?)</div>',re.S)
rs = re.findall(con_pattern,html)
# 6.4去除、替换数据中的html标签
#1.用户名中的img标签
#2.去除帖子内容中的img标签
#3.去掉帖子内容部分的空格
#4.替换帖子中的内容部分
for r in rs:
remove_img = re.compile(r'<img.*?>',re.S)
remove_k = re.compile(r' {10}',re.S)
replace_br = re.compile(r'<br>|<br/>',re.S)
remove_ele = re.compile(r'<.*?>',re.S)
#1 去除name中的img
name = re.sub(remove_img,'',r[0])
#2 去除内容中的img
content = re.sub(remove_img,'',r[1])
# 3 去除内容中的空格
content = re.sub(remove_k,'',content)
# 4 替换内容的br
content = re.sub(replace_br,r'\n',content)
# 5 去除所有标html签
content = re.sub(remove_ele,'',content)
# 6.5写入本地文件
file.write('---------------------------------------------------------')
file.write('\n')
file.write(name)
file.write('\n')
file.write(content)
file.close()
print '数据爬取完成!'
****************************************************************************************
#执行程序,能够爬取成功,再进一步升级,用类和对象的方法来写,作进一步的尝试,先通过输入编号,爬取一个帖子的内容
****************************************************************************************
#coding:utf-8
import urllib2
import re
#工具类
class Tools(object):
#1.正则
remove_img = re.compile(r'<img.*?>',re.S)
remove_k = re.compile(r' {10}')
replace_br = re.compile(r'<br>|<br/>')
remove_ele = re.compile(r'<.*?>',re.S)
#替换文本的函数
def replace_txt(self,rs):
name = re.sub(self.remove_img,'',rs[0])
content = re.sub(self.remove_img,'',rs[1])
content = re.sub(self.remove_k,'',content)
content = re.sub(self.replace_br,r'\n',content)
content = re.sub(self.remove_ele,r'',content)
#返回替换完成的元组
return (name,content)
#百度贴吧爬虫类
class BDTB(object):
def __init__(self,numbers):
#根据帖子编号拼接url地址
self.url = 'https://tieba.baidu.com/p/'+numbers
self.headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:54.0) Gecko/20100101 Firefox/54.0'
}
#初始化工具类对象
self.tool = Tools()
#获取某一页的html源代码
def get_page(self,pageNum):
#根据页码拼接完整的url地址
getUrl = self.url+"?"+"pn=%s"%pageNum
#创建request对象
request = urllib2.Request(getUrl,headers=self.headers)
try:
#发起请求接收响应
response = urllib2.urlopen(request)
except(urllib2.HTTPError,Exception),e:
print '获取第%s页数据失败,原因%s'%(pageNum,e)
return None
else:
#如果没有异常,返回html源代码
return response.read()
#从第一页中提取总页数和标题
def get_title_total(self,html):
#1.准备正则
tit_pattern = re.compile(r'<h\d class="core_title_txt.*?>(.*?)</h\d>',re.S)
# 2.查找
tit_rs = re.search(tit_pattern,html)
# 3 .记录标题
self.title = tit_rs.group(1)
#1 查找总页数正则
total_pattern = re.compile(r'<li class="l_reply_num.*?<span.*?<span class="red">(.*?)</span>',re.S)
# 2 查找
total_rs = re.search(total_pattern,html)
# 3 记录总页数
self.total = int(total_rs.group(1))
#从html源代码中提取数据
def get_data(self,html):
# 1 准备正则
pattern = re.compile(r'<ul class="p_author.*?<li class="d_name.*?<a.*?>(.*?)</a>.*?<div id="post_content_.*?>(.*?)</div>',re.S)
# 2 查找
results = re.findall(pattern,html)
ok_results = []
for rs in results:
#替换数据中的html标签
ok_rs = self.tool.replace_txt(rs)
ok_results.append(ok_rs)
#返回替换完成后的结果列表
return ok_results
# 写入本地文件
def write_data(self,results):
for rs in results:
self.file.write('------------------------------------')
self.file.write(rs[0])
self.file.write('\n')
self.file.write(rs[1])
self.file.write('\n')
#开始爬虫函数
def start(self):
#1.获取第一页的HTML源代码
html = self.get_page(1)
if html == None:
print '连接百度失败,请稍后重试、、、、、'
return
#2.从第一页源代码中获取总页数和标题
self.get_title_total(html)
print '正在爬取帖子:%s,共%s页数据。。。'%(self.title,self.total)
#3.打开文件,用属性记录这个文件对象,方便后面使用
filename = '%s.txt'%self.title.decode('utf-8')
self.file = open(filename,'w')
#for循环 循环总页数次
for x in range(1,self.total+1):
print '正在爬取第%s页:'%x
#1 根据页码获取该页的HTML源代码
html = self.get_page(x)
if html == None:
continue
#2 从html源代码中提取数据
results = self.get_data(html)
#3 写入本地文件
self.write_data(results)
#3 .关闭文件
self.file.close()
if __name__ =='__main__':
numbers = raw_input('请输入要爬取的帖子编号:')
bdtb = BDTB(numbers)
bdtb.start()
*****************************************************************************************
#再进一步升级爬取所有精品贴内容
*****************************************************************************************
#coding:utf-8
import urllib2
import re
from tieba_class import BDTB
import time
#爬取精品贴页面所有的帖子编码
class JPT(object):
def __init__(self):
self.url = 'https://tieba.baidu.com/f/good?kw=nba&tab=good'
self.headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50'
}
#获取精品贴的HTMl源代码
def get_page(self):
# 创建对象发起请求
request = urllib2.Request(self.url, headers=self.headers)
try:
response = urllib2.urlopen(request)
except(urllib2.URLError, Exception), e:
print '获取精品贴失败,%s' % e
else:
return response.read()
def get_data(self,html):
#1.准备正则
pattern = re.compile(r'<div class="threadlist_title.*?href="/p/(.*?)"',re.S)
results = re.findall(pattern,html)
return results
def start(self):
#1.获取精品贴的HTML源代码
html = self.get_page()
#2.从精品贴源代码中提取帖子编号
results = self.get_data(html)
#for 循环遍历帖子编号,爬取内容
#创建BDTB对象,传入帖子编号
for numbers in results:
bdtb = BDTB(numbers)
bdtb.start()
time.sleep(2)
if __name__ == '__main__':
jpt = JPT()
jpt.start()