用爬虫下载视频,得到视频m3u8的url后,下载后打开不太对
这是原代码'''
流程:
1.拿到网页源代码
2.从源代码中提取到m3u8的url
3.下载m3u8
4.读取m3u8文件,下载视频
5.合并视频
'''
import requests
import re
# 拿到网页的源代码
main_url = 'https://wx.vzan.com/live/tvchat-1353603565?shauid=3L2J-FI9aT8UjjZ1EgQeHA**&vprid=0&sharetstamp=1633088881811&ver=6118677193634a4bb9139998ea15739d#/'
headers = {
'accept': 'text/plain, */*; q=0.01',
'accept-encoding': 'gzip, deflate, br',
'accept-language': 'zh-CN,zh;q=0.9',
'cache-control': 'no-cache',
'origin': 'https://wx.vzan.com',
'pragma': 'no-cache',
'referer': 'https://wx.vzan.com/live/tvchat-1353603565?shauid=3L2J-FI9aT8UjjZ1EgQeHA**&vprid=0&sharetstamp=1633088881811&ver=6118677193634a4bb9139998ea15739d',
'sec-ch-ua': '" Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"',
'sec-ch-ua-mobile': '?0',
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'cross-site',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.164 Safari/537.36'
}
resp_main_url = requests.get(main_url, headers=headers)
# print(resp_main_url)
obj = re.compile(r"var hlsUrl = '(?P<m3u8_url>.*?)';", re.S)# 写正则
# 拿到m3u8的源代码
m3u8_url = obj.search(resp_main_url.text).group('m3u8_url')
print(m3u8_url)
# 下载m3u8文件
resp_m3u8 = requests.get(m3u8_url).content.decode('utf-8')
# print(resp_m3u8)
with open("岩土.m3u8", mode='w') as f:
f.write(resp_m3u8)
print('over!')
运行结果:
<?xml version='1.0' encoding='utf-8' ?>
<Error>
<Code>NoSuchKey</Code>
<Message>The specified key does not exist.</Message>
<Resource>pull-sh1-1251575313.cos.ap-shanghai.myqcloud.com/2D16I16F10f0k8g14h8V6X18J/8I12y16I12F2b12N14Z0l12Q2O4M12F10T0L2V18f6b16r/replay.1632042576.30049749.m3u8</Resource>
<RequestId>NjE2MmZmZDNfNzU0OTIyMDlfMTQxZF8xZjhjM2Mw</RequestId>
<TraceId>OGVmYzZiMmQzYjA2OWNhODk0NTRkMTBiOWVmMDAxODc0OWRkZjk0ZDM1NmI1M2E2MTRlY2MzZDhmNmI5MWI1OTkwMTkyODMxODFlYzJhYTVmMmIyNDI0YjMyOGQxMzc1MTJhNjg4YjMxOWNiMGVjYWRiYWRlYTc0MjhlN2M3NWY=</TraceId>
</Error>
百度也没百度到啥东西,看错误说明大致可以猜到是被加密了,请问有啥办法么?
这代码不是自己写的吧,自己走亲自抓包木有??
import requests
import re
def main():
url = 'https://wx.vzan.com/live/tvchat-1353603565?shauid=3L2J-FI9aT8UjjZ1EgQeHA**&vprid=0&sharetstamp' \
'=1633088881811&ver=6118677193634a4bb9139998ea15739d#/'
headers = {'user-agent': 'Mozilla'}
r = requests.get(url, headers=headers)
m3 = re.findall(r"var hlsUrl = '(.*?)'", r.text).split('/')[-1]
zbid = re.findall(r"zbid: (.*?),", r.text)
stream = re.findall(r"stream: '(.*?)',", r.text)
m3u8_url = f"https://pull-sh1.weizan.cn/{zbid}/{stream}/{m3}"# html自带的不能直接用,得自己合成。
r = requests.get(m3u8_url, headers=headers)
print(r.text)
if __name__ == '__main__':
main()
wp231957 发表于 2021-10-11 06:38
这代码不是自己写的吧,自己走亲自抓包木有??
是自己写的啊,跟着视频教程写的,只是把网页url换了,想下这个视频 suchocolate 发表于 2021-10-11 09:02
非常感谢!我研究一下你这个代码~ 来迟了
服务器可能使用了某种反爬虫机制,这个地址我这边一开始是会报错的,和你的报错信息一样,之后我使用 curl 和 wget 一个参数一个参数的排除,然后现在是不添加 headers 也可以用了
我没有弄明白服务器检查了哪个参数,因为我现在这边正常了,我弄不回那个不能用的状态了,没办法再一个参数一个参数的排除了
还有,你这个视频 13 个小时,一共有 15245 个 ts 视频,8 线程下载这些 ts 我这边花了 1 个多小时,合并视频花了 5 个多小时,合并后的 mp4 文件 11.9GB,^_^
下面这个代码是我前不久写的,思路和你的完全一样,不过就是没有第 1 步和第 2 步,毕竟这个代码不是我用的,是帮别人写的,所以这些简单的部分我就没有写
#!/usr/bin/env python
#coding=utf-8
import re
import requests
import threadpool
import shutil
import os
import sys
import subprocess
def get_file(url):
global session
while True:
try: content = session.get(url).content
except: sys.stderr.write('"' + url + '": download failed, retry!\n'); continue
break
return content
def get_base_url(url):
return re.search(r'^(.+?://.+?)/', url).group(1)
def get_list_full_path(url_list, base_url):
for i in range(len(url_list)):
url_list = url_list if re.search(r'^.+?://', url_list) else base_url + url_list
return url_list
def get_media_play_list(url):
play_list = get_file(url).decode()
master_play_list = re.findall(r'^.+\.m3u8$', play_list, re.MULTILINE)
if len(master_play_list) == 0: return play_list
master_play_list = get_list_full_path(master_play_list, get_base_url(url))
return get_file(master_play_list).decode()
def get_ts_list(media_play_list):
return re.findall(r'^.+?://.+?\.ts$', media_play_list, re.MULTILINE)
def download_file(url, path):
filename = re.search(r'^.+/(.+)$', url).group(1)
with open(path + '/' + filename, 'wb') as f: f.write(get_file(url))
sys.stdout.write(path + ': ' + url + '\n')
def get_video_info(path):
ffprobe_cmd = ['ffprobe', '-protocol_whitelist', 'https,file,crypto,tls,tcp', '-show_streams', '-print_format', 'json', path]
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
startupinfo.wShowWindow = subprocess.SW_HIDE
ffprobe = subprocess.Popen(ffprobe_cmd, stdout = subprocess.PIPE, startupinfo = startupinfo)
ffprobe.wait()
return json.loads(ffprobe.stdout.read())
def convert_video_format(v1, v2):
ffmpeg_cmd = ['ffmpeg', '-y', '-protocol_whitelist', 'https,file,crypto,tls,tcp', '-i', v1, '-c:v', 'h264', v2]
ffmpeg = subprocess.Popen(ffmpeg_cmd)
ffmpeg.wait()
return ffmpeg.returncode
url = 'https://pull-sh1.weizan.cn/1885047439/468616706126501938/replay.1632042576.30049749.m3u8'
session = requests.Session()
path = 'download'
shutil.rmtree(path, True)
os.mkdir(path)
media_play_list = get_media_play_list(url)
ts_list = get_ts_list(media_play_list)
pool = threadpool.ThreadPool(8)
requests = threadpool.makeRequests(download_file, [((url, path), None) for url in ts_list])
pool.wait()
media_play_list = re.sub(r'^.+/(.+?\.ts)$', r'\1', media_play_list, flags = re.MULTILINE)
with open(path + '/index.m3u8', 'w') as f: f.write(media_play_list)
print(convert_video_format(path + '/index.m3u8', '31.mp4'))
人造人 发表于 2021-10-12 01:57
来迟了
服务器可能使用了某种反爬虫机制,这个地址我这边一开始是会报错的,和你的报错信息一样,之后我使 ...
{:5_106:}{:5_109:}哇!!非常感谢!!最近在学爬虫,用多线程或者协程来爬,正好有个视频要下,就干脆爬这个了,确实非常非常的大,毕竟是个学术报告~哈哈~ 人造人 发表于 2021-10-12 01:57
来迟了
服务器可能使用了某种反爬虫机制,这个地址我这边一开始是会报错的,和你的报错信息一样,之后我使 ...
随便能请教一个问题么?我用异步协程下载视频ts文件,出现了这样的错误是怎么回事?
File "D:\Python_study\爬虫\爬取视频\简单版本 爬取朱德霖\下载(异步,有问题).py", line 6, in download_ts
async with session.get(url) as resp:
File "D:\Python_study\venv\lib\site-packages\aiohttp\client.py", line 1117, in __aenter__
self._resp = await self._coro
File "D:\Python_study\venv\lib\site-packages\aiohttp\client.py", line 619, in _request
break
File "D:\Python_study\venv\lib\site-packages\aiohttp\helpers.py", line 656, in __exit__
raise asyncio.TimeoutError from None
asyncio.exceptions.TimeoutError
Task exception was never retrieved
future: <Task finished name='Task-5706' coro=<download_ts() done, defined at D:\Python_study\爬虫\爬取视频\简单版本 爬取朱德霖\下载(异步,有问题).py:5> exception=TimeoutError()>
Traceback (most recent call last):
File "D:\Python_study\爬虫\爬取视频\简单版本 爬取朱德霖\下载(异步,有问题).py", line 6, in download_ts
async with session.get(url) as resp:
File "D:\Python_study\venv\lib\site-packages\aiohttp\client.py", line 1117, in __aenter__
self._resp = await self._coro
File "D:\Python_study\venv\lib\site-packages\aiohttp\client.py", line 619, in _request
break
File "D:\Python_study\venv\lib\site-packages\aiohttp\helpers.py", line 656, in __exit__
raise asyncio.TimeoutError from None
asyncio.exceptions.TimeoutError
进程已结束,退出代码为 -1
3530366912 发表于 2021-10-12 22:11
随便能请教一个问题么?我用异步协程下载视频ts文件,出现了这样的错误是怎么回事?
File "D:\Python_s ...
发代码看看 人造人 发表于 2021-10-12 22:22
发代码看看
# 里面有很多没用的东西,因为是根据别人的代码改编过来的
import aiofiles
import aiohttp
import asyncio
async def download_ts(url, name, session):
async with session.get(url) as resp:
async with aiofiles.open(f"岩土视频/{name}.ts", mode="wb") as f:
await f.write(await resp.content.read())# 把下载到的内容写入到文件中
print(f"{name}下载完毕")
# 解析m3u8文件 异步下载
async def aio_download():
tasks = []
n = 1
async with aiohttp.ClientSession() as session:# 提前准备好session
async with aiofiles.open("岩土.txt", mode="r", encoding='utf-8') as f:
async for line in f:
if line.startswith("#"):
continue
line = line.strip()
task = asyncio.create_task(download_ts(line, n, session))# 创建任务
tasks.append(task)
n = n + 1
await asyncio.wait(tasks)# 等待任务结束
def main(url, headers):
asyncio.run(aio_download())
if __name__ == '__main__':
headers = {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.192 Safari/537.36"
}
url = "https://www.91kanju.com/vod-play/58988-1-1.html" # 根据别人的代码改的,别在意这个url
main(url, headers)
奇怪,你的回复我这边没有收到通知,还好我记得这件事,点进来才发现你已经回复了我,我找时间看看 岩土.txt 的内容是什么?
看报错信息是超时了
人造人 发表于 2021-10-13 19:33
岩土.txt 的内容是什么?
看报错信息是超时了
内容就是下载下来的m3u8文件内容,我把它弄到txt文件里面去了~ 3530366912 发表于 2021-10-13 20:28
内容就是下载下来的m3u8文件内容,我把它弄到txt文件里面去了~
那么,文件后缀应该是 m3u8,不是 txt
3530366912 发表于 2021-10-13 20:28
内容就是下载下来的m3u8文件内容,我把它弄到txt文件里面去了~
你发一下这个文件的内容吧 人造人 发表于 2021-10-13 20:42
你发一下这个文件的内容吧
#EXT-X-TARGETDURATION:6
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-PLAYLIST-TYPE:VOD
#EXTINF:3.999,
http://pull-sh1.weizan.cn/1885047439/468616706126501938/703220957200-3_3968_0.ts
#EXTINF:4,
http://pull-sh1.weizan.cn/1885047439/468616706126501938/703220957200-3_3989_1.ts
#EXTINF:4,
http://pull-sh1.weizan.cn/1885047439/468616706126501938/703220957200-3_3968_2.ts
#EXTINF:4,
http://pull-sh1.weizan.cn/1885047439/468616706126501938/703220957200-3_3989_3.ts
#EXTINF:4,
http://pull-sh1.weizan.cn/1885047439/468616706126501938/703220957200-3_3968_4.ts
#EXTINF:4,
http://pull-sh1.weizan.cn/1885047439/468616706126501938/703220957200-3_3989_5.ts
#EXTINF:4,
http://pull-sh1.weizan.cn/1885047439/468616706126501938/703220957200-3_3968_6.ts
#EXTINF:4,
http://pull-sh1.weizan.cn/1885047439/468616706126501938/703220957200-3_3989_7.ts
#EXTINF:4,
http://pull-sh1.weizan.cn/1885047439/468616706126501938/703220957200-3_3968_8.ts
#EXTINF:4,
http://pull-sh1.weizan.cn/1885047439/468616706126501938/703220957200-3_3989_9.ts
#EXTINF:2.579,
http://pull-sh1.weizan.cn/1885047439/468616706126501938/703220957200-3_2560_10.ts
就是这个,视频片段的链接~我把它重命名成txt了,,(别问为啥重命名,问就是无聊哈哈哈) 人造人 发表于 2021-10-13 20:42
你发一下这个文件的内容吧
为啥我的回复要审核啊,,你之前说没收到通知的那次,也是要审核,, 3530366912 发表于 2021-10-13 21:25
为啥我的回复要审核啊,,你之前说没收到通知的那次,也是要审核,,
我有时候也要,回复的内容不能出现某些单词、句子,具体是哪些我也不清楚
人造人 发表于 2021-10-13 22:02
我有时候也要,回复的内容不能出现某些单词、句子,具体是哪些我也不清楚
txt文件的内容,就是16楼的那堆东西 3530366912 发表于 2021-10-14 17:40
txt文件的内容,就是16楼的那堆东西
用代码格式发,不然无法复制
页:
[1]
2