51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 1486|回复: 3
打印 上一主题 下一主题

关于网页视频解析爬取以及合成的问题

[复制链接]
  • TA的每日心情
    无聊
    昨天 09:47
  • 签到天数: 528 天

    连续签到: 1 天

    [LV.9]测试副司令

    跳转到指定楼层
    1#
    发表于 2021-11-1 11:47:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    1测试积点

    实现功能:在爬取一个网站的视频
    1、拿到主页面的页面源代码,找到iframe
    2、从iframe页面源代码中拿到m3u8文件
    3、下载第一层m3u8文件,拿到真实地址
    4、下载视频
    5、下载key(密钥),进行解密操作
    6、合并所有ts文件为一个MP4文件
    '''

    目前基本确定是在第4步和第5步是有问题的,但不清楚是代码错误的原因,还是因为好像有几个分段视频没有下载完成引起的;
    所以导致第6步的问题也不清楚是什么导致的;求老鸟

    问题截图:




    代码页

    1. import requests
    2. from bs4 import BeautifulSoup
    3. import re   
    4. import asyncio
    5. import aiohttp   
    6. import aiofiles   
    7. from Crypto.Cipher import AES
    8. import os   
    9. #正则提取规则
    10. obj1=re.compile(r'2.html","link_pre":"","url":"(?P<src>.*?)","url_next":"https:')
    11. #2.1子程序:找到主页面的源代码,找到iframe对应的url
    12. def get_iframe_src(url):
    13.     resp=requests.get(url)
    14.     #print(resp.text)  #测试是否正常爬取到源代码

    15.     #修改为正则爬取,这里提取完之后就是第一层的m3u8地址了
    16.     content=resp.text  #把源代码变成text格式存储起来,用来提取
    17.     main_page=obj1.finditer(content)
    18.     for it in main_page:
    19.         #print(it.group('src'))  
    20.         src_modify=it.group('src').replace('\\','')   
    21.         #print(src_modify)
    22.         return src_modify  #输出正确的第一层m3u8地址
    23.     resp.close()
    24.   

    25. #2.2、子程序:拿到第一层的m3u8文件下载地址;这一步只在课程里91看剧需要,实操的网址2.1里拿到的就是第一层m3u8了
    26. def get_first_m3u8_url(url):
    27.     resp=requests.get(url)
    28.     #print(resp.text)
    29.     obj2=re.compile(r'var main=''(?P<m3u8_url>.*?)''')
    30.     m3u8_url=obj2.search(resp.text).group('m3u8_url')   #这里是把m3u8地址提取出来
    31.     #print(m3u8_url)
    32.     resp.close()
    33.     return m3u8_url  #让函数返回这一个地址

    34. #2.3、子程序:下载第一层m3u8文件
    35. def download_m3u8_file(url,name):
    36.     resp=requests.get(url)
    37.     with open(name,mode='wb')as f:
    38.         f.write(resp.content)
    39.     resp.close()

    40. #2.5.1、子程序:异步协程进行下载
    41. async def download_ts(url,name,session):
    42.     async with session.get(url)as resp:
    43.         async with aiofiles.open(f'4.9-video2/{name}',mode='wb')as f:
    44.             await f.write(await resp.content.read())  #把下载到的内容写入文件中
    45.     print(f'{name}下载完毕')

    46. #2.5、子程序:异步协程处理拼接下载

    47. #实操版
    48. async def aio_download(up_url):
    49.     tasks=[]
    50.    
    51.     async with aiohttp.ClientSession() as session:
    52.         async with aiofiles.open('4.93-抓取91看剧复杂版——second-m3u8.txt',mode='r',encoding='utf-8')as f:
    53.             async for line in f:
    54.                 if line.startswith('#'):  #’#‘开头的行不要
    55.                     continue
    56.                 # line就是xxxx.ts文件
    57.                 url = line.strip()
    58.                 name1=line.rsplit('/',1)[1]
    59.                 name=name1.strip()
    60.                 task=asyncio.create_task(download_ts(url,name,session))
    61.                 tasks.append(task)
    62.             await asyncio.wait(tasks)  #等待任务结束
    63. #2.6.1获取密钥
    64. def get_key(url):
    65.     resp=requests.get(url)
    66.     print(resp.text)  
    67.     a=resp.text
    68.     b=bytes(a,'utf-8')  
    69.     return b
    70. #2.6.2创建解密视频的任务
    71. async def aio_dec(key):
    72.     #思路:解密,需要把下载的文件一个个打开;但是因为这里我们是直接用m3u8文件里后面的字符命名的
    73.     tasks=[]
    74.     async with aiofiles.open('4.93-抓取91看剧复杂版——second-m3u8.txt',mode='r',encoding='utf-8')as f:
    75.         async for line in f:
    76.             if line.startswith('#'):
    77.                 continue
    78.             line1=line.rsplit('/',1)[1]  #取网址最后一个斜杠后面的字符作为文件名,意思是:从右边切,切一次,得到【1】的位置的内容
    79.             line=line1.strip()
    80.             #开始创建异步任务
    81.             task=asyncio.create_task(dec_ts(line,key))
    82.             tasks.append(task)
    83.         await asyncio.wait(tasks)
    84. #2.6.3创建解密函数
    85. async def dec_ts(name,key):
    86.     aes=AES.new(key=key,IV=b'0000000000000000',mode=AES.MODE_CBC)
    87.     async with aiofiles.open(f'4.9-video2/{name}',mode='rb')as f1,\
    88.         aiofiles.open(f'4.9-video2/temp_{name}',mode='wb')as f2:
    89.         bs=await f1.read()  #从源文件读取文件
    90.         await f2.write(aes.decrypt(bs))  #把解密好的内容写入文件
    91.     print(f'{name}处理完毕')
    92. #2.7合并视频为mp4
    93. def merge_ts():
    94.     #mac:cat 1.ts 2.ts 3.ts > xxx.mp4
    95.     #windows:copy/b 1.ts+2.ts+3.ts > xxx.mp4
    96.     lst=[]
    97.     with open('4.93-抓取91看剧复杂版——second-m3u8.txt',mode='r',encoding='utf-8')as f:
    98.         for line in f:
    99.             if line.startswith('#'):
    100.                 continue
    101.             line1 = line.rsplit('/', 1)[1]  # 取网址最后一个斜杠后面的字符作为文件名,意思是:从右边切,切一次,得到【1】的位置的内容
    102.             line=line1.strip()
    103.             lst.append(f'4.9-video2/temp_{line}')
    104.     s=''.join(lst)
    105.     os.system(f'copy /b {s} >movie.mp4')
    106.     print('搞定!')

    107. #2、主程序
    108. def main(url):
    109.     #2.1、找到主页面的源代码,找到iframe对应的url
    110.     iframe_src=get_iframe_src(url)
    111.     #print(iframe_src)
    112.     #2.3下载第一层m3u8文件
    113.     download_m3u8_file(iframe_src,'4.93-抓取91看剧复杂版——first-m3u8.txt')  #按照课程正常的话括号里的’iframe_src‘要改为2.2里的’first_m3u8_url_ture‘
    114.     #2.4下载第二层m3u8文件
    115.     with open('4.93-抓取91看剧复杂版——first-m3u8.txt',mode='r',encoding='utf-8') as f:
    116.         for line in f:
    117.             if line.startswith('#'):  #让程序识别文件里面时,自动跳过‘#’开头的行段
    118.                 continue
    119.             else:
    120.                 line=line.strip()  #去掉空白或者换行符
    121.                 #准备拼接第二层m3u8的下载路径
    122.                 second_m3u8_url=iframe_src.split('/20210730')[0]+line
    123.                 download_m3u8_file(second_m3u8_url,'4.93-抓取91看剧复杂版——second-m3u8.txt')
    124.                 print('第二层m3u8下载完毕')
    125.     #2.5下载视频
    126.     #实操写法
    127.     up_url='开始'
    128.     #asyncio.run(aio_download(up_url))   #这个会报错:RuntimeError: Event loop is closed
    129.     loop=asyncio.get_event_loop()     
    130.     loop.run_until_complete(aio_download(up_url))   
    131.     #2.6.1拿到密钥
    132.     #实操
    133.     key_url='https://ts6.hhmm0.com:9999/20210730/QoNAXIDD/1000kb/hls/key.key'  
    134.    
    135.     key=get_key(key_url)  #访问密匙的路径,拿到密匙
    136.     #2.6.2解密
    137.     asyncio.run(aio_dec(key))
    138.     #2.7合并ts文件为mp4文件
    139.     merge_ts()
    140. #1、主程序调用处
    141. if __name__=='__main__':
    142.     url='https://www.pianba.net/yun/84961-1-1/'
    143.     main(url)
    复制代码


    附件: 您需要 登录 才可以下载或查看,没有帐号?(注-册)加入51Testing
    分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏
    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    9 小时前
  • 签到天数: 1803 天

    连续签到: 2 天

    [LV.Master]测试大本营

    2#
    发表于 2021-11-2 09:25:14 | 只看该作者
    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    8 小时前
  • 签到天数: 1518 天

    连续签到: 2 天

    [LV.Master]测试大本营

    3#
    发表于 2021-11-2 11:08:24 | 只看该作者
    那就试下是否下载完全
    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    10 小时前
  • 签到天数: 2814 天

    连续签到: 2 天

    [LV.Master]测试大本营

    4#
    发表于 2021-11-2 18:35:45 | 只看该作者
    看完全下载是否有问题,看是否有判断
    回复

    使用道具 举报

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2024-11-19 18:24 , Processed in 0.062927 second(s), 22 queries .

    Powered by Discuz! X3.2

    © 2001-2024 Comsenz Inc.

    快速回复 返回顶部 返回列表