结合第一次的实例,本次继续抓取网页并存储下来。
简述:对百度贴吧前五页数据进行抓取
操作系统:macOS Mojave 10.14.3
使用工具:PyCharm
过程:构建URL -> 访问URL -> 抓取网页代码 -> 构建存放文件目录 -> 存放抓取的文件
此时需要注意,按照第一步的方法,以‘c语言吧’为例:http://tieba.baidu.com/f?ie=utf-8&kw=c语言&fr=search
打印获取的网页代码,发现无法准确定位的需要网站,这个牵扯到url编码的一个问题。
打开谷歌浏览器,首先我们进入c语言贴吧,右键网页选择‘检查’,进入‘network’后刷新网站,可以看到首先加载的内容
实际请求URL为http://tieba.baidu.com/f?ie=utf-8&kw=c%E8%AF%AD%E8%A8%80&fr=search&red_tag=u0923371448
而我们输入的URL为:http://tieba.baidu.com/f?ie=utf-8&kw=c语言&fr=search&red_tag=u0923371448
因为之前玩了一丢丢时间的密码箱,可以很快发现牵扯到搜索内容的一个转码问题
附赠该转码网址:http://tool.oschina.net/encode?type=4
所以,当我们搜索内容时,有两种选择,一:构建URL时填写转换的URL编码,二:使用quote函数进行转换。
方法一:emmmm...URL直接改成http://tieba.baidu.com/f?ie=utf-8&kw=c%E8%AF%AD%E8%A8%80&fr=search&red_tag=u0923371448。
方法二:传入数据时使用quote函数,稍后代码将采用这种方式。
代码如下(前五页网址也存在规律,很容易发现,本帖暂缺次内容了):
from urllib.request import urlopen
from urllib.parse import quote
def open_baidu(name,page):
#建立url
url='https://tieba.baidu.com/f?kw={}&ie=utf-8&pn={}'.format(quote(name),page)
print(url)
response=urlopen(url)
return response.read().decode()
def save_baidu(page,html,name):
#建立文件路径
file_name='tieba/{}_page_{}.html'.format(name,page)
with open(file_name,'w',encoding='UTF-8') as file:
file.write(html)
return html
if __name__ == '__main__':
x=input('请输入需要搜索的贴吧:')
i=0
while i<5:
html=open_baidu(x,i*50)
i=i+1
因为存在某些贴吧内容过少(该贴吧仅一页内容),这样提取的五页实际内容相同,浪费时间和空间,采取一定的优化:
from urllib.request import urlopen
from urllib.parse import quote
import re
def open_baidu(name,page):
#建立url
url='https://tieba.baidu.com/f?kw={}&ie=utf-8&pn={}'.format(quote(name),page)
print(url)
response=urlopen(url)
return response.read().decode()
def save_baidu(page,html,name):
#建立文件路径
file_name='tieba/{}_page_{}.html'.format(name,page)
with open(file_name,'w',encoding='UTF-8') as file:
file.write(html)
return html
if __name__ == '__main__':
old_html=''
x=input('请输入需要搜索的贴吧:')
#测试的固定贴吧:此贴吧仅含有五个帖子
#x='哒哒哒哒'
i=0
while i<5:
html=open_baidu(x,i*50)
#如果上一次的内容的中文内容等于本次提取的内容 则证明本贴吧内容过少
#if(re.findall(r"a(.+?)b", html)):该方法为提取贴吧帖子数量进行判断,未写完
if(re.sub("[A-Za-z0-9\!\%\[\]\,\。<>\-=\"\'\:/:.+/{}? ()|;&~^__$!#,,!、]", "", repr(html).replace('\\','%')) == re.sub("[[A-Za-z0-9\!\%\[\]\,\。<>\-=\"\'\:/:.+/{}? ()|;&~^__$!#,,!、]", "", repr(old_html).replace('\\','%'))):
break
else:
old_html=save_baidu(i,html,x)
i=i+1
存储上一次网页内容,利用正则表达式去掉除中文外其他内容进行比较,如果上次网页中文等于本次提取内容中文,则认定为此贴吧已无下页内容(该方法也有一定缺陷,例如广告- -)
在此,在提供一种方法,对截取内容提取帖子数目,进行判断是否满足五页,emmmm这个也有点难,因为帖子内容不一样导致每页帖子数目其实并不固定?