使用Python3.x的版本 对http://tieba.baidu.com/p/2005436135,该百度贴吧帖子进行爬取操作。
一.使用到的库。
1. urllib.request :对链接进行解析,以及图片的保存
参考资料:http://www.jb51.net/article/42630.htm
http://www.cnblogs.com/Lands-ljk/p/5447127.html
2. re :正则表达式的处理模块
参考资料:http://www.cnblogs.com/huxi/archive/2010/07/04/1771073.html
3. os :文件的操作模块
参考资料:http://developer.51cto.com/art/201003/186045.htm
二.对帖子链接的分析。
该帖子是对部分美剧的分析和推荐。
原始链接为:http://tieba.baidu.com/p/2005436135
如果只看楼主的话会变成:http://tieba.baidu.com/p/2005436135?see_lz=1
如果选择第几页的话变成:http://tieba.baidu.com/p/2005436135?see_lz=1&pn=2
可以看出:?see_lz=1是选择只看楼主,?see_lz=0,取消只看楼主,&pn=x , x就是第几页。
三.使用urllib.request模块获取到网页源码。
1.urllib.request.open() 可以直接使用Url作为参数,或者一个Request对象作为参数。
在此使用Request对象作为参数。
request = urllib.request.Request(Url)
response = urllib.request.urlopen(request)
response.read().decode('utf-8')
根据需求可分为只看楼主或者不只看楼主,根据输入的链接Url,是否只看楼主SeeLZ,开始的页数Num,做参数,得到如下代码。
def getPage(self,Url,SeeLZ,Num):
if(SeeLZ == 1):
Url = Url.strip() + '?see_lz=1' + '&pn=' + str(Num) # strip()去掉字符串左右两边的空格
if(SeeLZ == 0):
Url = Url.strip() + '?see_lz=0' + '&pn=' + str(Num)
try:
request = urllib.request.Request(Url)
response = urllib.request.urlopen(request)
return response.read().decode('utf-8')
except urllib.request.URLError as e:
if hasattr(e,'reason'):
print('连接错误:',e.reason)
return None
五.运用正则表达式得到帖子的题目和回复的数目和页数。
1.得到帖子的题目。
class
="core_title_txt member_thread_title_pb" title="【30部屌丝必备美剧】逆袭吧,屌丝。"style="width: 470px">【30部屌丝必备美剧】逆袭吧,屌丝。
在网页源码中可以找到,帖子的题目在这里出现。
编写正则表达式,得到帖子的题目。
def getTitle(self,page): #得到帖子的题目
pattern = re.compile(r'
2.得到帖子的回复数目和页数。
与得到帖子题目的做法一致,在网页源码中找到位置,编写正则表达式进行匹配即可。
def getPageNumAndReply(self,page): #得到帖子的回复数目和页数
pattern = re.compile(r'(\d+).*?>(\d+)')
result = pattern.search(page)
print('该帖子共',result.group(1),'回复 ; 共',result.group(2),'页数')
self.pageReply = result.group(1) #得到帖子的总回复
self.pageNum = result.group(2) #得到帖子的总页数
六.得到回复的内容和回复者的名字。
1.得到原始的回复的内容。
依然是使用正则表达式对网页源码中的内容进行匹配,分析源码找到回复内容出现的地方。
pattern = re.compile(r'pattern1 = re.compile(r'src="(.*?)"',re.S) #用来匹配回复中的照片
该正则表达式用于在回复的内容中进行匹配。
若在回复中匹配到图片,则调用另一个保存图片的方法,将该图片进行保存。
def savePicture(self,Picture,num):
filepath = os.getcwd() + '\\' + self.name # 得到文件的路径
for url in Picture:
a = 1
temp = filepath + '\\' + str(num) + '(' + str(a) + ')L.jpg'
urllib.request.urlretrieve(url, temp) # 保存到本地文件中
a += 1
3.对回复中的其他内容进行处理。
回复中除了图片以外,还有其他的hrml代码,需要将其转换成相应的内容。
将回复中的超链接删除掉,将换行符br替换成\n,同是将其他的一些内容删除掉。
def removeOthers(self,page):
removeImg = re.compile(r'') #删除掉图片的链接
removeAddr = re.compile(r'|') #删除掉超链接
replaceBr = re.compile('
') #替换换行符
removeOthers = re.compile(r'<.*?>') #删除其他的内容
page = re.sub(removeImg,'',page)
page = re.sub(removeAddr,'',page)
page = re.sub(replaceBr,'\n',page)
page = re.sub(removeOthers,'',page)
return page
4.将回复的内容写入文件中。
写入文件比较简单,得到工作的目录,然后在目录下创建一个新的文件写入即可。
写入的同是可以添加一些内容使其看起来更为美观。
def wiriteFile(self,name,content,num): #对文件的路劲需要处理
path = os.getcwd() + '\\' + self.name + '\\' + self.name + r'.txt' #得到当前工作目录
path = path.replace('\\','//',1) #替换目录中的\ 为// ,为创建文件做准备
file = open(path,'a')
if num == 1:
file.write('帖子名称:')
file.write(self.name)
file.write(' | 帖子总回复:')
file.write(self.pageReply)
file.write(' | 帖子总页数:')
file.write(self.pageNum)
file.write('\n----------------------------\n')
file.write('第')
num = str(num)
file.write(num)
file.write('楼\n\n')
file.write(name)
file.write('\n\n')
file.write(content)
print(num,'楼内容已爬取完成...')
5.整个得到回复内容的总结。
使用x变量是对楼层进行统计,在命名图片的时候使用。
def getContent(self,page): #得到帖子的回复的内容以及回复者,得到回复中的图片
pattern = re.compile(r'
七.将整个内容进行整合。
可以使用input函数输入相应的Url,Num,SeeLZ等。
同是在爬取的开始应该建立一个新的文件夹,让得到的内容方便处理。
def start(self):
url = input("请输入所要爬取的帖子链接:")
seeLZ = input("是否只看楼主:")
Num = input("从第几页开始:")
if(seeLZ == '是'):
seeLZ = 1
if(seeLZ == '否'):
seeLZ = 0
self.x = 1
page = self.getPage(url,seeLZ,Num)
self.getTitle(page)
self.getPageNumAndReply(page)
filepath = os.getcwd() + '\\' + self.name # 得到文件的路径
print(filepath)
if os.path.exists(filepath) is False:
print('Hlloasdk')
os.mkdir(filepath)
y1 = int(Num)
y2 = int(self.pageNum) + 1
for y in range(y1,y2):
page = self.getPage(url, seeLZ, y)
self.getContent(page)
print('爬取完成,实际爬取到',self.x-1,'楼!')
代码:https://github.com/leafage666/SpiderBaiDuTieba/blob/master/Spider