Python爬取91网站视频教程:实战m3u8下载与处理

Python爬取91网站视频教程:实战m3u8下载与处理

最近在研究如何利用python爬取某91网站的视频资源,有一点小小的成果,由于考虑到一些其他因素,此处只提供获取视频的方法!!!好了,言归正传,进入主题。

首先,我们需要有一个构建代码的思路,或者说是爬取的流程

一、流程:

1.请求548121-1-1.html的页面代码

2.从源代码中提取m3u8

3.下载m3u8

4.读取m3u8文件,下载视频,(注意反扒问题) 超级播

import ...

def n_path():

pass

if __name__ == '__main__':

pass

二、现在我们就要构建我们的代码

1.书写主模块,将一些必要的变量和全局操作放在该部分!

注意:moive文件夹建议手动创建成exclused形式的文件夹,要不卡死了别找我!!!

if __name__ == '__main__':

start = time.time()

failure_list = [] # 保存下载失败的片段

# 创建一个文件夹

list = ['./moive', './mp4'] # 建议手动创建成exclused形式的文件夹

for path in list:

if not os.path.exists(path):

os.mkdir(path)

else:

print('文件夹已存在!!!')

headers = {

'Connection': 'close',

"user-agent": "*****"

}

for page in range(1, 29):

url = "*****" + str(page) + ".html" # 直接拼接出所用网址

# 代理已过期,再次使用时使用新代理,代理最好在下载视频时使用,此处没用到

proxies = ['', '']

proxy = {'HTTPS': random.choice(proxies)} # 使每集的代理不一样

print(proxy)

# "copy/b moive\*.ts mp4\movie.mp4"

moive_name = "欧美电视剧第%d集" % page

address = f"copy/b moive\*.ts mp4\{moive_name}"

main(url)

print(("欧美电视剧第%d集下载完毕!!!" % page) + url)

os.rmdir('./moive') # 此时该文件夹应该为空,回收文件夹moive

end = time.time()

print('总耗时', end - start)

print('程序结束!!!')

2.需要用到的包

import requests

import re

import asyncio

import aiohttp

import aiofiles

import os

import glob

import random

import time

3.建立模块

3.1获取m3u8_url

def get_m3u8_url(url, headers):

obj = re.compile(r"url: '(?P.*?)',", re.S) # 提取m3u8地址

response = requests.get(url=url, headers=headers)

m3u8_url = obj.search(response.text).group("url")

print(m3u8_url)

print("m3u8_url 下载完毕!")

return m3u8_url

3.2下载 m3u8_file

def download_m3u8_file(url, name):

# 下载m3u8文件

response = requests.get(url=url, headers=headers, timeout=30, proxys=proxy)

with open(name, mode="wb") as f:

f.write(response.content)

response.close()

print("下载 “moive.m3u8 完毕!")

# 加载太慢直接写进文件

3.3 下载ts,由于使用的是异步协程爬取信息,此处对网络超时、请求错误等进行处理。

async def download_ts(url, name, session, flag=0):

try:

async with session.get(url) as response:

async with aiofiles.open(f"moive/{name}", mode="wb") as fp:

# 双await是由于下载和读写均异步

await fp.write(await response.content.read()) # 把下载的内容写入到文件内

if flag == 1:

data_list = []

data_list.append(name)

data_list.append(url)

failure_list.remove(data_list)

data_list.clear() # 每次都清空,但其实每判断一次都会自动清零,但不想修改运行后的代码

except:

print('请求失败!')

data = []

if name not in data:

data.append(name)

data.append(url)

if data not in failure_list:

failure_list.append(data)

print(f"{name}下载完毕")

3.4 由于下载ts前需要先对m3u8文件将进行处理,且此处对反扒问题进行处理,如果不对302自动重新请求处理,虽然可以下载到视频,但是有少数ts文件会无法下载下来。可以试想一下,看到关键是否卡住是多气人,或者直接跳过精彩片段。

async def aio_download():

n = 0

tasks = [] # 创建任务列表

# 在这创建session,避免多次创建

async with aiohttp.ClientSession() as session:

async with aiofiles.open("movie_m3u8.txt", mode="r", encoding='utf-8') as fp:

async for line in fp:

if line.startswith("#"): # 跳过#号语句

continue

line = line.strip()

if len(line) != 0: # 对302情况进行处理,情况不一样,该平台不同源的影片处理方式不一样

async with session.get(url=line, headers=headers, allow_redirects=False) as response:

result = response.text

print(str(result))

obj = re.compile(r"'Location': '(?P.*?)',", re.S)

new_requests_url = obj.search(str(result)).group("url")

print(new_requests_url)

n += 1

k = "{:0>4d}".format(n)

task = asyncio.create_task(download_ts(new_requests_url, k + ".ts", session, 0)) # 创建任务

tasks.append(task)

await asyncio.wait(tasks) # 等待任务结束

3.4.1 效果图

3.5 由于在构建代码是没有考虑到超时问题,后面构建的是否又不想重现写,突发奇想CV大法构建一个新的模块,真的是机智如我。

async def reaio_download(): # 直接新建一个模块调用download_ts

tasks = [] # 创建任务列表

# 在这创建session,避免多次创建

async with aiohttp.ClientSession() as session:

for recall in failure_list:

if len(recall[1]) == 0:

failure_list.remove(recall)

continue

task = asyncio.create_task(download_ts(recall[1], recall[0], session, 1)) # 创建任务

tasks.append(task)

await asyncio.wait(tasks) # 等待任务结束

3.6 接下来就是合并文件了,merge_ts

def merge_ts():

path = './moive'

files = os.listdir(path)

moive_name = "反贪风暴第%d集" % page

address = f"copy/b moive\*.ts mp4\{moive_name}"

print(address)

if len(files) != 0:

# "copy/b moive\*.ts mp4\movie.mp4",安卓系统下的命令,苹果系统无法使用

os.system(address) # 这里的文件名需要需改,否则会覆盖前一集

print(moive_name + "合并完成!")

else:

print(moive_name + "合并失败,文件夹为空文件夹!!!")

3.7 做为一个懒人是不可能自己动手取删除ts等文件的啦!给它写个代码

def deleteFile(file_path):

print("开始删除文件")

for infile in glob.glob(os.path.join(file_path, '*.ts')):

os.remove(infile)

paths = ["movie_m3u8.txt"] # 文件路径

for path in paths:

if os.path.exists(path): # 如果文件存在

# 删除文件

os.remove(path)

else:

print('no such file!!!') # 则返回文件不存在

print("文件删除完成")

3.8 写了这么多模块,肯定要组装起来呀!

def main(url):

# 1.获取m3u8的地址

m3u8_url = get_m3u8_url(url, headers)

# 2.下载m3u8文件

download_m3u8_file(m3u8_url, "movie_m3u8.txt")

# 3. 下载视频

# 异步协程

# loop = asyncio.get_event_loop()

# loop.run_until_complete(aio_download())

asyncio.run(aio_download())

# 4. 合并ts文件

merge_ts()

# 5.删除ts文件

file_path = './moive'

deleteFile(file_path)

4 搞了这么多嘻嘻哈哈的操作,不给个整体肯定是在欺负人!!!

#!/usr/bin/env python

# author = 'MIMG LOU'

# time = 2021/9/29

# project = 扒光一部电视剧

'''

流程:

1.请求548121-1-1.html的页面代码

2.从源代码中提取m3u8

3.下载m3u8

4.读取m3u8文件,下载视频,超级播

'''

# 编程思想:各需求分为各个模块,通过主模块调用,主函数尽量只防止全局参数和只需创建一次的内容

import requests

import re

import asyncio

import aiohttp

import aiofiles

import os

import glob

import random

import time

def get_m3u8_url(url, headers):

obj = re.compile(r"url: '(?P.*?)',", re.S) # 提取m3u8地址

response = requests.get(url=url, headers=headers)

m3u8_url = obj.search(response.text).group("url")

print(m3u8_url)

print("m3u8_url 下载完毕!")

return m3u8_url

def download_m3u8_file(url, name):

# 下载m3u8文件

response = requests.get(url=url, headers=headers, timeout=30, proxys=proxy)

with open(name, mode="wb") as f:

f.write(response.content)

response.close()

print("下载 “moive.m3u8 完毕!")

# 加载太慢直接写进文件

async def download_ts(url, name, session, flag=0):

try:

async with session.get(url) as response:

async with aiofiles.open(f"moive/{name}", mode="wb") as fp:

# 双await是由于下载和读写均异步

await fp.write(await response.content.read()) # 把下载的内容写入到文件内

if flag == 1:

data_list = []

data_list.append(name)

data_list.append(url)

failure_list.remove(data_list)

data_list.clear() # 每次都清空,但其实每判断一次都会自动清零,但不想修改运行后的代码

except:

print('请求失败!')

data = []

if name not in data:

data.append(name)

data.append(url)

if data not in failure_list:

failure_list.append(data)

print(f"{name}下载完毕")

async def aio_download():

n = 0

tasks = [] # 创建任务列表

# 在这创建session,避免多次创建

async with aiohttp.ClientSession() as session:

async with aiofiles.open("movie_m3u8.txt", mode="r", encoding='utf-8') as fp:

async for line in fp:

if line.startswith("#"): # 跳过#号语句

continue

line = line.strip()

if len(line) != 0: # 对302情况进行处理,情况不一样,该平台不同源的影片处理方式不一样

async with session.get(url=line, headers=headers, allow_redirects=False) as response:

result = response.text

print(str(result))

obj = re.compile(r"'Location': '(?P.*?)',", re.S)

new_requests_url = obj.search(str(result)).group("url")

print(new_requests_url)

n += 1

k = "{:0>4d}".format(n)

task = asyncio.create_task(download_ts(new_requests_url, k + ".ts", session, 0)) # 创建任务

tasks.append(task)

await asyncio.wait(tasks) # 等待任务结束

async def reaio_download(): # 直接新建一个模块调用download_ts

tasks = [] # 创建任务列表

# 在这创建session,避免多次创建

async with aiohttp.ClientSession() as session:

for recall in failure_list:

if len(recall[1]) == 0:

failure_list.remove(recall)

continue

task = asyncio.create_task(download_ts(recall[1], recall[0], session, 1)) # 创建任务

tasks.append(task)

await asyncio.wait(tasks) # 等待任务结束

def merge_ts():

path = './moive'

files = os.listdir(path)

moive_name = "欧美电视剧第%d集" % page

address = f"copy/b moive\*.ts mp4\{moive_name}"

print(address)

if len(files) != 0:

# "copy/b moive\*.ts mp4\movie.mp4",安卓系统下的命令,苹果系统无法使用

os.system(address) # 这里的文件名需要需改,否则会覆盖前一集

print(moive_name + "合并完成!")

else:

print(moive_name + "合并失败,文件夹为空文件夹!!!")

'''

删除合并后的文件

file_path

'''

def deleteFile(file_path):

print("开始删除文件")

for infile in glob.glob(os.path.join(file_path, '*.ts')):

os.remove(infile)

paths = ["movie_m3u8.txt"] # 文件路径

for path in paths:

if os.path.exists(path): # 如果文件存在

# 删除文件

os.remove(path)

else:

print('no such file!!!') # 则返回文件不存在

print("文件删除完成")

def main(url):

# 1.获取m3u8的地址

m3u8_url = get_m3u8_url(url, headers)

# 2.下载m3u8文件

download_m3u8_file(m3u8_url, "movie_m3u8.txt")

# 3. 下载视频

# 异步协程

# loop = asyncio.get_event_loop()

# loop.run_until_complete(aio_download())

asyncio.run(aio_download())

# 4. 合并ts文件

merge_ts()

# 5.删除ts文件

file_path = './moive'

deleteFile(file_path)

if __name__ == '__main__':

start = time.time()

failure_list = [] # 保存下载失败的片段

# 创建一个文件夹

list = ['./moive', './mp4'] # 建议手动创建成exclused形式的文件夹

for path in list:

if not os.path.exists(path):

os.mkdir(path)

else:

print('文件夹已存在!!!')

headers = {

'Connection': 'close',

"user-agent": "***"

}

for page in range(1, 29):

url = "***" + str(page) + ".html" # 直接拼接出所用网址

# 代理已过期,再次使用时使用新代理,代理最好在下载视频时使用,此处没用到

proxies = ['','']

proxy = {'HTTPS': random.choice(proxies)} # 使每集的代理不一样

print(proxy)

# "copy/b moive\*.ts mp4\movie.mp4"

moive_name = "反贪风暴第%d集" % page

address = f"copy/b moive\*.ts mp4\{moive_name}"

main(url)

print(("反贪风暴第%d集下载完毕!!!" % page) + url)

os.rmdir('./moive') # 此时该文件夹应该为空,回收文件夹moive

end = time.time()

print('总耗时', end - start)

print('程序结束!!!')

'''

最终电视剧的聚集存放在MP4文件中

'''

5 来看一下效果吧!!!

白嫖生活从此开始!!!

相关推荐

2024美加墨世界杯中国队名单揭晓,年轻力量崛起 365在线体育投注

2024美加墨世界杯中国队名单揭晓,年轻力量崛起

歌曲《马来风光》歌词 bt365在线

歌曲《马来风光》歌词

2025年深圳92所公办高中招生代码与地址全攻略! det365在线平台

2025年深圳92所公办高中招生代码与地址全攻略!