[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,处理速度更快。
""" |