#知识点 #理解m3u8视频结构 把长的视频切成小片段,不断加载的过程 #Requests模块使用 #json数据提取 #re模块使用 #bs4提取数据 #tqdm模块使用 import json from bs4 import BeautifulSoup import pprint import re from tqdm import tqdm import requests headers={ 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36' # 'Cookie':'csrfToken=1iGcGyCmLIJQNJCq7aUp2Vrn; _did=web_9682077584854F37; webp_supported=%7B%22lossy%22%3Atrue%2C%22lossless%22%3Atrue%2C%22alpha%22%3Atrue%2C%22animation%22%3Atrue%7D; Hm_lvt_2af69bc2b378fb58ae04ed2a04257ed1=1721353272; HMACCOUNT=ADC202C257290F1A; lsv_js_player_v2_main=e4d400; uuid=7ae76485943e1f1af48d666de88ae802; safety_id=AAFo3UJctQI2vE8rhmVPB5vN; _did=web_9682077584854F37; Hm_lpvt_2af69bc2b378fb58ae04ed2a04257ed1=1721355283; cur_req_id=568175026C6CA7DD_cde007fae07665f9c236fc1842944b25_video_monkey_recommend; cur_group_id=568175026C6CA7DD_cde007fae07665f9c236fc1842944b25_video_monkey_recommend_1', # 'Referer':'https://www.acfun.cn/' } #获取m3u8列表文件 def get_m3u8_list(url): r=requests.get(url,headers=headers) # print(r.status_code) # print(r.text) info=re.findall(' window.pageInfo = window.videoInfo =(.*?) window.videoResource',r.text,re.S)[0].strip()[:-1]#re.S允许换行 # print(info) info_json=json.loads(json.loads(info)['currentVideoInfo']['ksPlayJson'])['adaptationSet'][0]['representation'][0]['url']#转换成json filename=json.loads(info)['title'] filename=re.sub(r'[|><>/\\]','',filename)#是一个用于替换字符串中匹配的部分的正则表达式函数r'[|><>/\\]' 是正则表达式模式,表示要匹配的字符集合。具体来说:/ 和 \ 表示斜杠和反斜杠(\\ 在正则表达式中表示反斜杠字符)。'' 是替换的内容,即将匹配到的字符替换为空字符(即删除这些字符)。filename 是要处理的字符串变量。 print(filename) # pprint.pprint(info_json) return info_json,filename #提取所有视频片段的播放地址 ts文件 def get_ts_files(url): r=requests.get(url,headers=headers) ts_files=re.sub('#.*','',r.text).split() #print(ts_files) return ts_files #下载并合并视频片段 def download_combine(ts_files,path,filename): with open(f'{path}/{filename}.mp4','ab') as f: for ts in tqdm(ts_files): ts='https://ali-safety-video.acfun.cn/mediacloud/acfun/acfun_video/'+ts ts_content=requests.get(ts,headers=headers).content #print(ts_content) f.write(ts_content) #获取目录页的视频链接 def get_index_links(index_url): r=requests.get(index_url,headers=headers) soup=BeautifulSoup(r.text,'html.parser') link_list=soup.find_all('h1',class_='list-content-title') links=[] for a in link_list: link="https://www.acfun.cn"+a.a.get('href')#a.a 表示从 a 对象中获取其嵌套的第一个 <a> 标签(即超链接标签)。 links.append(link) return links def main(): #index_url="https://www.acfun.cn/v/list135/index.htm?sortFiled=rankScore&duration=all&default&page=1"; index_url = "https://www.acfun.cn/v/list135/index.htm" links=get_index_links(index_url) path = 'D:\python学习笔记课后题\爬虫\实战\视频' for url in links: #url='https://www.acfun.cn/v/ac34857244' m3u8_url,filename=get_m3u8_list(url) ts_files=get_ts_files(m3u8_url) download_combine(ts_files,path,filename) if __name__ == '__main__': main()