本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理
本文章来着腾讯云 作者:python学习教程
意外的挖掘到了一个资源网站(你懂得),但是网速慢广告多下载不了种种原因让我突然萌生了爬虫的想法。
下面说说流程:
一、网站分析
首先进入网站,F12检查,本来以为这种低端网站很好爬取,是我太低估了web主。可以看到我刷新网页之后,出现了很多js文件,并且响应获取的代码与源代码不一样,这就不难猜到这个网站是动态加载页面。
目前我知道的动态网页爬取的方法只有这两种:
1、从网页响应中找到JS脚本返回的JSON数据;
2、使用Selenium对网页进行模拟访问。
二、写代码
导入相关模块
import requestsfrom datetime import datetimeimport re#import jsonimport timeimport os #视频分类和视频列表URL的前一段url = "http://xxxxxxx/api/?d=pc&c=video&"#m3u8文件和ts文件的URL前一段m3u8_url ='https://xxxxxxxxxxxxx/videos/cherry-prod/2020/03/01/2dda82de-5b31-11ea-b5ae-1c1b0da2bc3f/hls/480/'#构造请求头信息header = {"user-agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.57.2 (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2"}#创建空列表存放视频信息vediomassag=''#返回当前时间戳TimeStamp = int(datetime.timestamp(datetime.now()))
2.定义函数,获取网站首页分类列表信息
#自定义函数获取分类def get_vediocategory(url, TimeStamp):cgURL = url + "m=categories×tamp=" + str(TimeStamp) + '&'response = requests.get(cgURL, headers=header)category = response.text# strrr='"%s"'%category# return strrrreturn category
3.定义函数,通过上一个函数返回的分类信息,根据分类对应的id,输入id并传输到当前URL中以便获取分类下的视频列表信息
#获取分类后的视频列表def get_vedioList(url, TimeStamp, tagID):listURL = url + "m=lists×tamp=" + str(TimeStamp) + '&' + "page=1&tag_id=" + str(tagID) + "&sort_type=&is_vip=0"response = requests.get(listURL, headers=header)vedioLists = response.textreturn vedioLists
4.在视频列表信息中获取视频对应的id,获取单个视频详细信息的URL
#获取单个视频的详细信息def get_vediomassages(url, TimeStamp, vedioID):videoURL = url + "m=detail×tamp=" + str(TimeStamp) + '&' + "&id=" + str(vedioID)response = requests.get(videoURL, headers=header)vediomassag = response.textreturn vediomassag
5.在视频详细信息中找到m3u8文件的下载地址,并将文件保存到创建的文件中
#将下载的m3u8文件放进创建的ts列表文件中def get_m3u8List(m3u8_url,vediomassag):lasturl = r'"m3u8_720_url":"(.*?)","download_url'last_url =re.findall(lasturl,vediomassag)lastURL=m3u8_url+str(last_url)response = requests.get(lastURL, headers=header)tsList = response.textcur_path='E:\\files' #在指定路径建立文件夹try:if not os.path.isdir(cur_path): #确认文件夹是否存在os.makedirs(cur_path) #不存在则新建except:print("文件夹存在")filename=cur_path+'\\t2.txt' #在文件夹中存放txt文件f = open(filename,'a', encoding="utf-8")f.write(tsList)f.closeprint('创建%s文件成功'%(filename))return filename
6.将m3u8文件中的ts单个提取出来放进列表中。
# 提取ts列表文件的内容,逐个拼接ts的url,形成listdef get_tsList(filename):ls = []with open(filename, "r") as file:line = f.readlines()for line in lines:if line.endswith(".ts\n"):ls.append(line[:-1])return ls
7.遍历列表获取单个ts地址,请求下载ts文件放进创建的文件夹中
# 批量下载ts文件def DownloadTs(ls):length = len(ls)root='E:\\mp4'try:if not os.path.exists(root):os.mkdir(root)except:print("文件夹创建失败")try:for i in range(length):tsname = ls[i][:-3]ts_URL=url+ls[i]print(ts_URL)r = requests.get(ts_URL)with open(root, 'a') as f:f.write(r.content)f.close()print('\r' + tsname + " -->OK ({}/{}){:.2f}%".format(i, length, i * 100 / length), end='')print("下载完毕")except:print("下载失败")
代码整合
import requestsfrom datetime import datetimeimport re#import jsonimport timeimport os url = "http://xxxxxxxx/api/?d=pc&c=video&"m3u8_url ='https://xxxxxxxxxxxxxxx/videos/cherry-prod/2020/03/01/2dda82de-5b31-11ea-b5ae-1c1b0da2bc3f/hls/480/'header = {"user-agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.57.2 (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2"}vediomassag=''TimeStamp = int(datetime.timestamp(datetime.now())) #自定义函数获取分类def get_vediocategory(url, TimeStamp):cgURL = url + "m=categories×tamp=" + str(TimeStamp) + '&'response = requests.get(cgURL, headers=header)category = response.text# strrr='"%s"'%category# return strrrreturn category #获取分类后的视频列表def get_vedioList(url, TimeStamp, tagID):listURL = url + "m=lists×tamp=" + str(TimeStamp) + '&' + "page=1&tag_id=" + str(tagID) + "&sort_type=&is_vip=0"response = requests.get(listURL, headers=header)vedioLists = response.textreturn vedioLists #获取单个视频的详细信息def get_vediomassages(url, TimeStamp, vedioID):videoURL = url + "m=detail×tamp=" + str(TimeStamp) + '&' + "&id=" + str(vedioID)response = requests.get(videoURL, headers=header)vediomassag = response.textreturn vediomassag #将下载的m3u8文件放进创建的ts列表文件中def get_m3u8List(m3u8_url,vediomassag):lasturl = r'"m3u8_720_url":"(.*?)","download_url'last_url =re.findall(lasturl,vediomassag)lastURL=m3u8_url+str(last_url)response = requests.get(lastURL, headers=header)tsList = response.textcur_path='E:\\files' #在指定路径建立文件夹try:if not os.path.isdir(cur_path): #确认文件夹是否存在os.makedirs(cur_path) #不存在则新建except:print("文件夹存在")filename=cur_path+'\\t2.txt' #在文件夹中存放txt文件f = open(filename,'a', encoding="utf-8")f.write(tsList)f.closeprint('创建%s文件成功'%(filename))return filename # 提取ts列表文件的内容,逐个拼接ts的url,形成listdef get_tsList(filename):ls = []with open(filename, "r") as file:line = f.readlines()for line in lines:if line.endswith(".ts\n"):ls.append(line[:-1])return ls # 批量下载ts文件def DownloadTs(ls):length = len(ls)root='E:\\mp4'try:if not os.path.exists(root):os.mkdir(root)except:print("文件夹创建失败")try:for i in range(length):tsname = ls[i][:-3]ts_URL=url+ls[i]print(ts_URL)r = requests.get(ts_URL)with open(root, 'a') as f:f.write(r.content)f.close()print('\r' + tsname + " -->OK ({}/{}){:.2f}%".format(i, length, i * 100 / length), end='')print("下载完毕")except:print("下载失败") '''# 整合所有ts文件,保存为mp4格式(此处函数复制而来未做实验,本人直接在根目录命令行输入copy/b*.ts 文件名.mp4,意思是将所有ts文件合并转换成自己命名的MP4格式文件。)def MergeMp4():print("开始合并")path = "E://mp4//"outdir = "output"os.chdir(root)if not os.path.exists(outdir):os.mkdir(outdir)os.system("copy /b *.ts new.mp4")os.system("move new.mp4 {}".format(outdir))print("结束合并")'''if __name__ == '__main__':# 将获取的分类信息解码显示出来# print(json.loads(get_vediocategory(url, TimeStamp)))print(get_vediocategory(url, TimeStamp))tagID = input("请输入分类对应的id")print(get_vedioList(url, TimeStamp, tagID))vedioID = input("请输入视频对应的id")get_vediomassages(url, TimeStamp, vedioID)get_m3u8List(m3u8_url,vediomassag)get_tsList(filename)DownloadTs(ls)# MergeMp4()
此时正在下载