利用python的数个实用的包,做了一个针对特定网页视频爬取下载功能的爬虫。
爬取网页需要的技术包括了网络部份和数据处理以及内容的管理。
网络方面有两种资源请求,分别是html内容和文件资源内容,这两种资源分别对应了字符文件和二进制字节文件。针对字符文件也就是html的请求我采用强大的requests_html包,字节文件的请求我才用普通的urllib中的requset请求。
requests_html中有针对html文本的各种分析方法和参数获取办法,非常的实用,而urllib是比较原生态的包,对于字节文件的特点是非常适合的。
由于这不过是我个人使用的一次小练习,所以有很多不足,比如下载的位置固定,文件名字固定,无法多个视频同时下载等。都是可以改进的小细节。
字节文件下载器
先是重要的字节文件下载器,这里要介绍一下,首先第一句不过是为了解决访问https网页一种办法,是固定的,要先导入ssl包。
headers是为了模拟电脑端访问,防止网页存在反爬虫技术,固定即可。
saveFile可以理解为将数据保存到制定文件夹下,将会在另外工具中展现。
# 通过url下载目标资源
def downloadFile(url):
ssl._create_default_https_context = ssl._create_unverified_context
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20100101 Firefox/23.0'}
req = request.Request(url=url, headers=headers)
filename = url.split('/')[-1]
content = request.urlopen(req).read()
saveFile(filename, content)
html请求分析器
这是针对html页面的分析,这里有个前提,我对这个网页结构分析时发现了重要的视频url是通过js请求得到的,所以这里模拟js请求获取。中间有使用正则表达式分析匹配得到需要的信息,并且返回。
# 通过url得到请求地址获取视频直接地址
def getRequestUrl(url):
ids = str(url)
url = 'https://www.goutoubaoming.com/user/videourl.php?id='+ids+'&siteid=3&seek=0&ok'
session = HTMLSession()
r = session.get(url)
json_str = r.html.html
pattern = re.compile(r'https://bi\.goutoubaoming..\.com/filets/[0-9]+/list\.m3u8')
res = re.search(pattern, json_str).group(0)
return res
辅助工具
这里的辅助工具是我个人觉得有点实用的功能,一个是下载显示进度条的,一个是断续下载视频的,也就是从中间下载,一个是保存数据到本地文件中,还有一个是dos命令,合并视频并且删除原文件。
# 显示进度
def speed(a, b):
ap = 80
hd = int(ap*a/b)
print( '#'*hd + '_'*(ap-hd)+'['+str(a)+'/'+str(b)+']')
# 断续下载
def line(index, maxFileNum, qianzhui):
for each in range(index, maxFileNum + 1):
downloadFile(qianzhui+str(each).zfill(3)+'.ts')
speed(each, maxFileNum)
# 批处理的合并F:/Video/Captures/下的ts文件放到 F:/Video/下,并删除原文件
def das(filename):
print(os.system('copy /b F:\\Video\\Captures\\*.ts F:\\Video\\'+ filename +'.ts'))
print(os.system('del F:\\Video\\Captures\\*.ts F:\\Video\\Captures\\list.m3u8'))
# 将资源保存到本地文件夹F:/Video/Captures/
def saveFile(filename, content):
dirname = 'F:/Video/Captures/'
with open(dirname+filename,'wb') as files:
files.write(content)
特定工具
这个网页的视频是一种特殊的机制,先得到的是一个u3m8文件,里面有整个视频的信息,完整的视频是被切割为很多部分的,到底多少部分,都存在这个u3m8文件中,所以先分析该文件。
# 分析m3u8文件得到ts文件的数量
def getM3u8():
with open('F:/Video/Captures/list.m3u8','r') as m3u8file:
str = m3u8file.read()
maxnumber = int(str.split('#')[-2].split(',')[-1].split('.')[0])
return maxnumber
最后是主函数调用上述工具即可
def main():
#url = getName()[0]
url = getRequestUrl(input('输入编号:'))
lineNum = int(input('请输入开始下载位置:'))
filename = url.split('/')[-2]
qianzhui = url[:-9]
print(url)
downloadFile(url)
maxFileNum = getM3u8()
line(lineNum, maxFileNum, qianzhui)
das(filename)
这个网页究竟是什么,我就不透露了。狗头保命。
总之一个爬虫首先是要模拟一个用户通过浏览器访问网页的,所以先要弄明白你需要的功能通过手动访问浏览器能不能做到,网页的组成大部分是html+css+js的一些组合,信息分为动态和静态之分。静态意味着信息就在本html文件下,动态意味着信息在别的href中,需要再做一次请求,所以要额外分析。不同的网页分析的难度不一样,有的网页防爬虫做的相当好,这也没办法。其他的就是关于文件的io,字符串的处理,比对分析等等知识。