python爬虫
python作业二——半自动爬虫
题目:在百度贴吧中寻找一个自己喜欢的贴吧,将其中一篇热门帖子的每层 楼的发帖人、发帖内容和发帖时间抓取下来。 提示:可以先手动把网页复制下来并保存到一个文件中,再通过利用 Python 的正则表达式和文件操作进行信息的提取。
这里我找的是一个30楼左右的网页,老师说楼层越高分数越高,我这个菜鸡还是量力而行叭。。。
网页链接:http://tieba.baidu.com/p/1180908096
html文件手动保存
直接查网页源码,把代码复制进txt里。
发帖人
发帖人:在这个网页中我找的都是名字前后没有任何图片装饰的,因为刚开始学正则表达式,不知道如何过滤掉img标签,或者说替换为文字,但是在后面提取发帖内容的时候,我找到了办法解决这个问题。
这个就是发帖人的名字有图片,可以看到源码中在中文后面跟了一个img标签,如果我们不过滤掉,那么结果中会显示username+<img···标签后的内容。具体解决办法请看提取发帖内容的处理
代码
打开文件:
with open('tieba.html',encoding='utf-8' ) as f:
html=f.read()
找发帖人
name=re.findall('a data-field=.*?>(.*?)</a',html,re.S)
这里不用代码<target="_blank">和后面的</a来匹配是因为匹配不到,我也不知道是什么原因,只有自己一次次尝试。
发帖时间
从网页代码中可以看到,按理说用
幸好,在这里找到了,但是通过前后的字符依然匹配不到。
为什么呢?
因为眼见不为实,字符不是这个。
右键编辑html,可以看到代码变成了这样。
代码
正确匹配应该如下:
time=re.findall('<div class=''.*?date":"(.*?)"',html,re.S)
发帖内容
以一个带图片的内容为例:
如果我们代码为:
content=re.findall('<div id="post_content.*?>.?(.*?)</div',html,re.S)
没有清除中间的
和<img= >标签,那么运行结果就是这样
这个问题和上文中提到的发帖人名字中带图片的问题是相同的,我的处理方法是:
clear=re.sub(r'<img.*?>||<br>',"",html)
#把多余标签删掉
content=re.findall('<div id="post_content.*?>.?(.*?)</div',clear,re.S)
#找回复内容
循环显示每楼信息
for i in range(len(name)):
print(str(i+1)+'楼:'+name[i]+"\n"+content[i]+"\n"+time[i]+"\n\n")
#循环显示
完整代码及结果
#coding=utf-8
import os
import re
with open('tieba.html',encoding='utf-8' ) as f:
html=f.read()
name=re.findall('a data-field=.*?>(.*?)</a',html,re.S)
#找回复ID
time=re.findall('<div class=''.*?date":"(.*?)"',html,re.S)
#找回复时间
clear=re.sub(r'<img.*?>||<br>',"",html)
#把多余标签删掉
content=re.findall('<div id="post_content.*?>.?(.*?)</div',clear,re.S)
#找回复内容
for i in range(len(name)):
print(str(i+1)+'楼:'+name[i]+"\n"+content[i]+"\n"+time[i]+"\n\n")
#循环显示
总结
整个过程中,找到正则表达式的规律是非常重要的,要熟练的去应用还需要再认真练习,其中有说的不对的地方还请dalao们指出,我也非常希望别人能够指点一手~