<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          ?Python爬蟲:使用協(xié)程下載m3u8視頻

          共 5201字,需瀏覽 11分鐘

           ·

          2022-03-04 19:29

          前言

          學(xué)了一段時(shí)間爬蟲,終于把進(jìn)程、線程、協(xié)程給搞明白了,還沒搞明白的強(qiáng)烈推薦看一下螞蟻老師B站的視頻:https://www.bilibili.com/video/BV1bK411A7tV?p=1,思路很清晰。爬蟲屬于IO密集型任務(wù),且資源開銷少,對(duì)于爬蟲來說很有優(yōu)勢(shì),對(duì)于使用爬蟲下載視頻,那效率就更高了。我們以人人影視最新一集的國(guó)王排名為例:https://www.rryy123.com/play/40479-1-18.html

          一,頁(yè)面分析

          通過抓包我們很容易發(fā)現(xiàn)index.m3u8這個(gè)包,但是響應(yīng)內(nèi)容卻沒顯示可用的數(shù)據(jù)。為了驗(yàn)證一下我們對(duì)這個(gè)網(wǎng)址https://c2.monidai.com/20220225/yOm07IlJ/index.m3u8發(fā)起請(qǐng)求,并保存為m3u8格式,打開發(fā)現(xiàn)得到的結(jié)果如下:

          但是發(fā)現(xiàn)里面的網(wǎng)址是以png結(jié)尾?于是我們對(duì)上面的一個(gè)網(wǎng)址發(fā)起請(qǐng)求進(jìn)行驗(yàn)證,并以二進(jìn)制寫入文件,文件名后綴以.ts結(jié)尾。下載完成后打開正是我們想要的視頻文件!

          那如何通過視頻的URL定位到index.m3u8地址呢?通過檢查網(wǎng)頁(yè)源代碼,搜索關(guān)鍵字m3u8很容易就定位到,如下圖:

          至此,第一步我們已經(jīng)完成,通過正則匹配可以獲得對(duì)應(yīng)地址,代碼如下:

          ????def?get_m3u8_url(self):
          ????????#?根據(jù)劇集網(wǎng)址,獲取m3u8下載索引
          ????????res?=requests.get(url=self.url,headers=self.headers).text
          ????????first_m3u8_url?=?re.findall(';var?now="(.*?)"',res,re.S)[0]?????#?獲取m3u8下載地址
          ????????self.name?=?re.findall("
        2. 正在播放:(.*?)
        3. "
          ,res,re.S)[0]???#?獲取下載片名
          ????????print(self.name+"準(zhǔn)備開始下載")
          ????????res_second?=?requests.get(url=first_m3u8_url,headers=self.headers).text
          ????????with?open(self.name+".m3u8",'w',encoding='utf-8')?as?f:
          ????????????f.write(res_second)

          二,獲取m3u8播放列表

          根據(jù)上一步下載的m3u8文件,提取下載地址,代碼如下:

          ????def?get_ts_url(self):
          ????????#?根據(jù)m3u8下載索引,獲取各個(gè)下載地址
          ????????ts_url_list?=?[]
          ????????with?open(self.name+".m3u8",'r',encoding='utf-8')?as?f:
          ????????????for?line?in?f:
          ????????????????if?line.startswith('#'):
          ????????????????????continue
          ????????????????line?=?line.strip()
          ????????????????ts_url_list.append(line)
          ????????return?ts_url_list

          三,編碼實(shí)現(xiàn)

          然后下一步我們就開始下載視頻了,完整代碼如下:

          #?-*-?coding:utf-8?-*-
          import?time
          import?re
          import?os
          import?requests
          import?asyncio
          import?aiohttp
          import?aiofiles
          import?nest_asyncio
          nest_asyncio.apply()

          class?RRyy123:
          ????def?__init__(self):
          ????????self.url?=?None
          ????????self.name?=?None
          ????????self.headers?=?{'User-Agent':'Mozilla?/?5.0(Windows?NT?10.0;Win64;x64)?AppleWebKit?/?537.36(KHTML,?likeGecko)?Chrome?/?95.0.4638.69Safari?/?537.36'}


          ????def?get_m3u8_url(self):
          ????????#?根據(jù)劇集網(wǎng)址,獲取m3u8下載索引
          ????????res?=requests.get(url=self.url,headers=self.headers).text
          ????????first_m3u8_url?=?re.findall(';var?now="(.*?)"',res,re.S)[0]?????#?獲取m3u8下載地址
          ????????self.name?=?re.findall("
        4. 正在播放:(.*?)
        5. "
          ,res,re.S)[0]???#?獲取下載片名
          ????????print(self.name+"準(zhǔn)備開始下載")
          ????????res_second?=?requests.get(url=first_m3u8_url,headers=self.headers).text
          ????????with?open(self.name+".m3u8",'w',encoding='utf-8')?as?f:
          ????????????f.write(res_second)


          ????def?get_ts_url(self):
          ????????#?根據(jù)m3u8下載索引,獲取各個(gè)ts文件地址
          ????????ts_url_list?=?[]
          ????????with?open(self.name+".m3u8",'r',encoding='utf-8')?as?f:
          ????????????for?line?in?f:
          ????????????????if?line.startswith('#'):
          ????????????????????continue
          ????????????????line?=?line.strip()
          ????????????????ts_url_list.append(line)
          ????????return?ts_url_list


          ????async?def?download_ts(self,url,session,sem):
          ????????#?使用協(xié)程下載單個(gè)ts文件
          ????????ts_name?=?os.path.splitext(url)[0].split("/")[-1]
          ????????async?with?sem:?????#?控制協(xié)程信號(hào)量
          ????????????async?with?session.get(url?=url)?as?res:
          ????????????????if?not?os.path.exists(f"./temp_{self.name}"):
          ????????????????????os.makedirs(f"./temp_{self.name}/")
          ????????????????async?with?aiofiles.open(f"./temp_{self.name}/{ts_name}.ts",'wb')?as?f:
          ????????????????????await?f.write(await?res.read())
          ????????????????????print(f"{ts_name}.ts下載完成")

          ????async?def?main(self):
          ????????#?根據(jù)m3u8文件中的ts網(wǎng)址,下載ts視頻
          ????????tasks?=?[]
          ????????self.get_m3u8_url()
          ????????ts_url_list?=?self.get_ts_url()
          ????????sem?=?asyncio.Semaphore(5)??#?設(shè)置信號(hào)量,控制異步數(shù)量
          ????????async?with?aiohttp.ClientSession(headers=self.headers)?as?session:
          ????????????for?ts_url?in?ts_url_list:
          ????????????????tasks.append(asyncio.create_task(self.download_ts(url=ts_url,session=session,sem=sem)))
          ????????????await?asyncio.wait(tasks)



          if?__name__?==?'__main__':
          ????t?=?time.time()
          ????f?=?RRyy123()
          ????f.url?=?"https://www.rryy123.com/video/?40479-1-18.html"
          ????asyncio.run(f.main())
          ????print(f"{f.name}下載完成,總耗時(shí){int(time.time()-t)}s.")

          我這是測(cè)了一下,下載一個(gè)128M的文件只要15s!!!

          四,ts文件合并

          下載完成后我們要對(duì)ts文件進(jìn)行合并了,這里推薦使用ffmpeg,windows下載地址:http://ffmpeg.org/download.html#build-windows。這里要注意的是 將解壓后的文件目錄中 bin 目錄(包含 ffmpeg.exe )添加進(jìn) path 環(huán)境變量中。使用 ffmpeg 合并ts 文件方法非常簡(jiǎn)單,只需要在終端輸入一行命令:

          ffmpeg -f concat -i filename.txt -c copy output.mp4

          首先在ts文件相同目錄中,把所有要合并的ts文件名保存在filename.txt:如下圖:

          然后使用命令行進(jìn)行合并,這里要注意文件路徑,合并完成后刪除ts文件,這里為了防止誤刪使用send2trash庫(kù),刪除內(nèi)容可以放進(jìn)回收站,代碼如下:

          import?send2trash
          import?os

          def?merge_video(name):
          ????#?合并視頻
          ????ts_url_list=[]
          ????with?open(name?+?".m3u8",?'r',?encoding='utf-8')?as?f:
          ????????for?line?in?f:
          ????????????if?line.startswith('#'):
          ????????????????continue
          ????????????line?=?line.strip()
          ????????????ts_url_list.append(line)

          ????f?=?open(f"./temp_{name}/filename.txt"?,'w'?,encoding="utf-8")
          ????for?ts_url?in?ts_url_list:
          ????????ts_name?=?os.path.splitext(ts_url)[0].split("/")[-1]
          ????????f.write("file??"+?ts_name?+".ts\n")
          ????f.close()
          ????print(f"{name}開始合并。。。。")
          ????os.system(f"ffmpeg?-f?concat?-i?./temp_{name}/filename.txt?-c?copy?{name}.mp4")
          ????print(f"{name}視頻合成成功")



          def?remove_temp(name):
          ????#?刪除ts文件,放入回收站
          ????send2trash.send2trash(f"./temp_{name}")
          ????send2trash.send2trash(f"{name}.m3u8")
          ????print("臨時(shí)文件已刪除。")

          if?__name__?==?'__main__':
          ????name?=?"國(guó)王排名-第19集"
          ????merge_video(name)
          ????remove_temp(name)


          最后,推薦螞蟻老師的Python課程:


          如果購(gòu)買課程,加微信:ant_learn_python

          找螞蟻老師,進(jìn)群、領(lǐng)資料

          瀏覽 113
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  影音先锋色噜噜av | 91四虎影院在线 | 成人AV一区二区三区四区 | 欧美日产在线 | 91美女裸体网站 |