lihu5841314 发表于 2021-6-27 14:49

小白日常学习 视频异步爬取

import requests,re,os,time
import asyncio
import aiofile
import aiohttp


"""
文件读取方式:

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

readline():读取一行

readline() :读取缓冲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"

defget_m3u8(url):
    resp = requests.get(url=url,headers=headers)
    resp.encoding =resp.apparent_encoding
    if resp.status_code == 200:
       returnresp
    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 defmovie_down(dic,semaphore):
    asyncwith semaphore:# 限制并发量
      m_url = dic["url"]
      name = dic["name"]
      print("---------------异步协程开启----------------")
      async withaiohttp.ClientSession() as session:
               async with awaitsession.get(m_url) as mov:
                     path = 'mov/' + name
                     async with aiofile.async_open(path,'wb') as f_b:
                        mov = awaitmov.read()
                        await   f_b.write(mov)
                        print(name,'下载完成')
                        awaitasyncio.sleep(1)


defmian():
   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\ \+ "(.*?)"\);',resp.text)
   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,处理速度更快。
"""

kingaero 发表于 2021-6-27 15:08

一直想学习m3u8的下载方式

xiaoshan1818 发表于 2021-6-27 15:35

片段式下载,再拼接嘛?

不负韶华 发表于 2021-6-27 16:38

`main`吧,咋能是`mian`

傅粉何郎 发表于 2021-6-27 19:40

爬多了怕不是会入yu{:1_886:}

xiaoliuzi 发表于 2021-6-27 22:31

学习一下
页: [1]
查看完整版本: 小白日常学习 视频异步爬取