吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1496|回复: 5
收起左侧

[讨论] 小白日常学习 视频异步爬取

[复制链接]
lihu5841314 发表于 2021-6-27 14:49
[Asm] 纯文本查看 复制代码
import requests,re,os,time
import asyncio
import aiofile
import aiohttp


"""
文件读取方式:

read([size]):读取文件(读取size字节,默认读取全部)

readline([size]):读取一行

readline([size]) :读取缓冲buf(io.DEFAULT_SET_BUFFER),返回每一行所组成的列表

iter:使用迭代器遍历读取文件 f.open(name);iter_f = iter(f);用for line in iter_f循环迭代器

文件写入方式:

write(str):将字符串写入文件

writelines(sequence_of_strings):写多行到文件,参数为可迭代的对象
"""

headers= {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36',
}


url = "https://www.91kanju.com/vod-play/59611-1-1.html"

def  get_m3u8(url):
    resp = requests.get(url=url,headers=headers)
    resp.encoding =resp.apparent_encoding
    if resp.status_code == 200:
       return  resp
    else:
        print("----没有响应----")

def m3u8_prase(m3u8_url):
    m3u8 = get_m3u8(m3u8_url)
    with open('../u8.m3u8', "w", encoding="utf-8") as f:
        f.write(m3u8.text)
    # 解析m3u8文件
    dics = []
    with open("../u8.m3u8", mode="r", encoding="utf-8") as f:
        for n in f: #open读取出来的是列表
            # 先去掉空白 换行之类
            n = n.strip()
            if n.startswith("#"):
                continue
            else:
               name =  n.split('/')[-1]
               name = re.sub('png','ts',name)
               print(name)
            dic = {
                "name": str(name),
                "url": n
            }
            dics.append(dic)
    return dics

async def  movie_down(dic,semaphore):
    async  with semaphore:  # 限制并发量
        m_url = dic["url"]
        name = dic["name"]
        print("---------------异步协程开启----------------")
        async with  aiohttp.ClientSession() as session:
                 async with await  session.get(m_url) as mov:
                     path = 'mov/' + name
                     async with aiofile.async_open(path,'wb') as f_b:
                          mov = await  mov.read()
                          await   f_b.write(mov)
                          print(name,'下载完成')
                          await  asyncio.sleep(1)


def  mian():
     semaphore = asyncio.Semaphore(20)  # 限制并发量为20
     start_time = time.time()
     if not os.path.exists('mov'):
        os.mkdir("mov")
     resp = get_m3u8(url)
     # print(resp.text)
     m3u8_url = re.findall(r'line\[lineIndex\] \+ "(.*?)"\);',resp.text)[0]
     print(m3u8_url)
     dics = m3u8_prase(m3u8_url)
     tasks = []
     for dic in dics:
         task = asyncio.ensure_future(movie_down(dic,semaphore))
         tasks.append(task)
     loop.run_until_complete(asyncio.wait(tasks))
     loop.close()
     print('一共耗时',time.time()-start_time)

def he_bing():
    
    pass


if __name__ == '__main__':
     loop = asyncio.get_event_loop()
     mian()
"""
假如你的并发达到2000个,程序会报错:ValueError: too many file descriptors in select()。报错的原因字面上看是 Python 调取的 select 对打开的文件有最大数量的限制,这个其实是操作系统的限制,linux打开文件的最大数默认是1024,windows默认是509,超过了这个值,程序就开始报错。这里我们有三种方法解决这个问题:

1.限制并发数量。(一次不要塞那么多任务,或者限制最大并发数量)

2.使用回调的方式。

3.修改操作系统打开文件数的最大限制,在系统里有个配置文件可以修改默认值,具体步骤不再说明了。

不修改系统默认配置的话,个人推荐限制并发数的方法,设置并发数为500,处理速度更快。
"""

免费评分

参与人数 3吾爱币 +4 热心值 +2 收起 理由
zyl1998 + 1 谢谢@Thanks!
pelephone + 1 + 1 我很赞同!
kingaero + 2 + 1 谢谢@Thanks!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

kingaero 发表于 2021-6-27 15:08
一直想学习m3u8的下载方式
xiaoshan1818 发表于 2021-6-27 15:35
不负韶华 发表于 2021-6-27 16:38
傅粉何郎 发表于 2021-6-27 19:40
爬多了怕不是会入yu
xiaoliuzi 发表于 2021-6-27 22:31
学习一下
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止回复与主题无关非技术内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-4-25 09:00

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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