Python 解析西瓜视频 | 无水印高清下载

时间:2022-12-29 10:59:38

很多小伙伴都有使用西瓜视频,现在西瓜视频作为字节旗下的全家桶一员,拥有很多优质的视频,是很多自媒体小伙伴需要的。但是如何无水印下载这些西瓜视频呢?却让很多人为难,缺少这个趁手的工具


示例链接:

https://www.ixigua.com/6826594712636359176?id=6819257002665968131&logTag=41f04767e576704d4c3f


打开链接我们 source 页面查看源码,经分析,可以看到Js代码中有SSR_HYDRATED_DATA,这里面的数据是属于页面的具体数据,我们只需要拿到这里的数据,然后根据下标读取数据即可。


Python 解析西瓜视频 | 无水印高清下载


我们看到videoResource下面的dynamic_video_list中有四条数据,这里我们选取的是1080P的,发现其中的mian_url时发现它的值字母加数字,不是我们想要的url地址,只是一段字符串,大家如果看到这种大小写字母加数字的加密,可以考虑用base64来试试,经测试可以解码成功。解码后的数据如下:

http://v9-xg-web-pc.ixigua.com/c8aeff4f39bd7ac1bb6bf1ce7d22d603/634f888e/video/tos/cn/tos-cn-vd-0026/0f89613a67cb44f096f5c5a3a313adfd/media-video-avc1/?a=1768&ch=0&cr=0&dr=0&er=0&cd=0%7C0%7C0%7C0&cv=1&br=3297&bt=3297&cs=0&ds=4&mime_type=video_mp4&qs=0&rc=OzgzNzs4aTZlaTY6aTppPEBpajM3ZjlpcGdmdDMzNjczM0BjMzAzMWI0X2IxLzJiLTIzYSNwLmReZjRocWVfLS0wLS9zcw%3D%3D&l=2022101912045001021003903507D66B2C

那到这里的话,我们已经可以成功的获取到,具体的视频地址,打开视频地址,发现播放的视频没有声音,发现还有一个音频文件,用上述同样的方法也可成功的获取到音频链接地址。


到此我们直接请求链接下载视频和音频文件即可,下载成功后的文件可根据ffmpeg进行数据合并即可。


示例代码使用需要注意两个地方:

1. cookie需要换成自己的cookie,不带 cookie 不会返回正确的页面,无法获取到相关的视频数据

2. ffmpeg需要更换成自己的存放位置,不会使用的可以把合并代码屏蔽了。


示例代码:

import requests
import re
import json
import base64
import os
import subprocess
import time




class Xigua(object):
# cookie换成自己的
headers = {
"cookie": "__ac_signature=_02B4Z6wo00f01.afvsgAAIDDdp1EipzTiYv2v7pAAJ7z5d; support_webp=true;"
" support_avif=true; MONITOR_WEB_ID=7155726949787633160; _tea_utm_cache_1300=undefined;"
" ttcid=eaed359f5daa4153b4b40685482e3a6367; ixigua-a-s=1; __ac_nonce=0634e5329007ddcd5542b;"
" msToken=O50hT5X-ZfqTBmSEW86M3H_oHBDjBEA_j89vfaq1FHkvTgPd2rUVqSUl8cDrpz5NsPPqKXPeIx"
"Gy2p6hdcuWiwRRwv4qoW4uqgFfqETDOiSH5J08YrMIxmXbb6jeiA==;"
" tt_scid=7vaFnCJA3efLJiYuS3g3LTFVkuL80JWjWmCwc69uBsG0PMjoBhyQk16yHKmNxQ.Zf81e; ttwid=1%7CEd5O7G3s6F"
"8mQ4ejoDjaK9vIbup9go2Mmngq9JxWIQ4%7C1666079260%7Cb4346288ad2b19ddfe3c6e90f3dd7b3"
"8633dd90735912cb2af983ef5ae62aff3",
"user-agent": "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36"
}
regx_str = r"<script id=\"SSR_HYDRATED_DATA\">window\._SSR_HYDRATED_DATA=(.*)<\/script><script.*>.*<\/script>"


def __init__(self, video_url):
# pass
video_data = self.url_parse(video_url)
print(video_data)
self.save_file(video_data)


def save_file(self, video_data):
if not os.path.exists('西瓜'):
os.mkdir('西瓜')
video_strem = requests.get(video_data[1], stream=True) # 解析出下载链接并发起下载请求
video_file = open("./西瓜/" + video_data[0] + ".mp4", "wb") # 保存视频
for chunk in video_strem.iter_content(chunk_size=512):
if chunk:
video_file.write(chunk)
print('mp4下载完毕…')


mp3_strem = requests.get(video_data[2], stream=True) # 解析出下载链接并发起下载请求
mp3_file = open("./西瓜/" + video_data[0] + ".mp3", "wb") # 保存视频
for chunk in mp3_strem.iter_content(chunk_size=512):
if chunk:
mp3_file.write(chunk)
print('mp3下载完毕…')
print("音频视频文件合并中……")
self.ff_merg(video_data[0])


def send_request(self, url, params={}):
response = requests.get(url, params=params, headers=self.headers)
return response.content.decode(response.apparent_encoding)


def ff_merg(self, file_name):
# ffmpeg 换成自己的地址 我的是E:/py/ffmpeg/bin/ffmpeg
ffmpegs = 'E:/py/ffmpeg/bin/ffmpeg -i ' + './西瓜/' + file_name + '.mp4' + ' -i ' + './西瓜/' + file_name + '.mp3' + ' -acodec copy -vcodec copy ' + "西瓜/" + file_name + 'bak.mp4'
ff_over = subprocess.Popen(ffmpegs, shell=False)
# for i in range(10000):
# flag = subprocess.Popen.poll(ff_over)
# if flag != None:
# os.remove('./西瓜/' + file_name + '.mp4')
# os.remove('./西瓜/' + file_name + '.mp3')
# print('合并完成!')
# break
# time.sleep(1)


def url_parse(self, video_url):
rtn_page = self.send_request(video_url)
tmp_data = re.search(self.regx_str, rtn_page).group(1)
print(tmp_data)
res_json = tmp_data.replace(":undefined", ':"undefined"').replace("null", '"null"')
json_data = json.loads(res_json)
tmp_json = json_data['anyVideo']['gidInformation']['packerData']['video']
video_base = tmp_json['videoResource']['dash']['dynamic_video']['dynamic_video_list'][-1]['main_url']
audio_base = tmp_json['videoResource']['dash']['dynamic_video']['dynamic_audio_list'][-1]['main_url']
video_title = tmp_json['title']
play_url = base64.b64decode(video_base).decode("utf-8")
audio_url = base64.b64decode(audio_base).decode("utf-8")
return video_title, play_url, audio_url




if __name__ == "__main__":
# video_url = input('请输入音频话题地址:')
video_url = "https://www.ixigua.com/6826594712636359176?id=6819257002665968131&logTag=41f04767e576704d4c3f"
Xg = Xigua(video_url)