突发2024-11-28无法下载,报错 bilix.exception.APIParseError: APIParseError Caused by AttributeError in <bilix.sites.bilibili.api:get_video_info>
使用命令 bilix v https://www.bilibili.com/video/BV1R6BRYmE99 --image -q 360p -fb firefox -d C:\Users\admin\Desktop\project\1
版本 Name: bilix Version: 0.18.9
报错内容如下, 求修复方法,感谢
Traceback (most recent call last): File "C:\Users\admin\AppData\Local\Programs\Python\Python310\lib\site-packages\bilix\download\utils.py", line 90, in wrapped return await func(client, args, **kwargs) File "C:\Users\admin\AppData\Local\Programs\Python\Python310\lib\site-packages\bilix\sites\bilibili\api.py", line 431, in get_video_info return await _get_video_info_from_html(client, url) File "C:\Users\admin\AppData\Local\Programs\Python\Python310\lib\site-packages\bilix\sites\bilibili\api.py", line 445, in _get_video_info_from_html return _parse_bv_html(url, html) File "C:\Users\admin\AppData\Local\Programs\Python\Python310\lib\site-packages\bilix\sites\bilibili\api.py", line 372, in _parse_bv_html play_info = re.search('?})
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\admin\AppData\Local\Programs\Python\Python310\lib\runpy.py", line 196, in _run_module_as_main
return _run_code(code, main_globals, None,
File "C:\Users\admin\AppData\Local\Programs\Python\Python310\lib\runpy.py", line 86, in run_code
exec(code, run_globals)
File "C:\Users\admin\AppData\Local\Programs\Python\Python310\Scripts\bilix.exe_main.py", line 7, in
因为我着急用,所以写了一个临时修复的方法,修改bilix/sites/bilibili/api.py中的两处代码
1. _parse_bv_html函数
async def _parse_bv_html(client,url, html: str) -> VideoInfo:
init_info = re.search(r'<script>window.__INITIAL_STATE__=({.*?});\(', html).groups()[0] # this line may raise
init_info = json.loads(init_info)
if len(init_info.get('error', {})) > 0:
raise APIResourceError("视频已失效", url) # 啊叻?视频不见了?在分区下载的时候可能产生
# extract meta
pages = []
h1_title = legal_title(re.search('<h1[^>]*title="([^"]*)"', html).groups()[0])
status = Status(**init_info['videoData']['stat'])
bvid = init_info['bvid']
desc = init_info['videoData'].get('desc', '')
tags = [i['tag_name'] for i in init_info['tags']]
aid = init_info['aid']
(p, cid), = init_info['cidMap'][bvid]['cids'].items()
p = int(p) - 1
title = legal_title(init_info['videoData']['title'])
base_url = url.split('?')[0]
for idx, i in enumerate(init_info['videoData']['pages']):
p_url = f"{base_url}?p={idx + 1}"
p_name = f"P{idx + 1}-{i['part']}" if len(init_info['videoData']['pages']) > 1 else ''
pages.append(Page(p_name=p_name, p_url=p_url))
# extract dash and flv_url
play_info_response = await req_retry(client, f'https://api.bilibili.com/x/player/wbi/playurl?bvid={bvid}&cid={cid}&fnval=4048')
play_info = json.loads(play_info_response.text)['data']
dash, other = None, []
try:
dash = Dash.from_dict(play_info)
except KeyError:
pass
try:
for i in play_info['durl']:
suffix = re.search(r'\.([a-zA-Z0-9]+)\?', i['url']).group(1)
other.append(Media(base_url=i['url'], backup_url=i['backup_url'], suffix=suffix))
except KeyError:
pass
# extract img url
img_url = re.search('property="og:image" content="([^"]*)"', html).groups()[0]
if not img_url.startswith('http'): # https://github.com/HFrost0/bilix/issues/52 just for some video
img_url = 'http:' + img_url.split('@')[0]
# construct data
video_info = VideoInfo(title=title, aid=aid, cid=cid, status=status,
p=p, pages=pages, img_url=img_url, bvid=bvid, dash=dash, other=other,
desc=desc, tags=tags)
return video_info
_get_video_info_from_html函数
async def _get_video_info_from_html(client: httpx.AsyncClient, url: str) -> VideoInfo:
res = await req_retry(client, url, follow_redirects=True)
if str(res.url).startswith("https://www.bilibili.com/festival"):
raise APIInvalidError("特殊节日页面", url)
html = res.text
if "window._riskdata_" in html:
raise APIInvalidError("web 前端访问被风控", url)
if "window.__INITIAL_STATE__" in html:
return await _parse_bv_html(client,url, html)
elif "__NEXT_DATA__" in html:
video_info = _parse_ep_html(url, html)
await _attach_ep_dash(client, video_info)
return video_info
else:
raise APIUnsupportedError("未知页面类型", url)
因为我着急用,所以写了一个临时修复的方法,修改
bilix/sites/bilibili/api.py中的两处代码 1._parse_bv_html函数async def _parse_bv_html(client,url, html: str) -> VideoInfo: init_info = re.search(r'<script>window.__INITIAL_STATE__=({.*?});\(', html).groups()[0] # this line may raise init_info = json.loads(init_info) if len(init_info.get('error', {})) > 0: raise APIResourceError("视频已失效", url) # 啊叻?视频不见了?在分区下载的时候可能产生 # extract meta pages = [] h1_title = legal_title(re.search('<h1[^>]*title="([^"]*)"', html).groups()[0]) status = Status(**init_info['videoData']['stat']) bvid = init_info['bvid'] desc = init_info['videoData'].get('desc', '') tags = [i['tag_name'] for i in init_info['tags']] aid = init_info['aid'] (p, cid), = init_info['cidMap'][bvid]['cids'].items() p = int(p) - 1 title = legal_title(init_info['videoData']['title']) base_url = url.split('?')[0] for idx, i in enumerate(init_info['videoData']['pages']): p_url = f"{base_url}?p={idx + 1}" p_name = f"P{idx + 1}-{i['part']}" if len(init_info['videoData']['pages']) > 1 else '' pages.append(Page(p_name=p_name, p_url=p_url)) # extract dash and flv_url play_info_response = await req_retry(client, f'https://api.bilibili.com/x/player/wbi/playurl?bvid={bvid}&cid={cid}') play_info = json.loads(play_info_response.text)['data'] dash, other = None, [] try: dash = Dash.from_dict(play_info) except KeyError: pass try: for i in play_info['durl']: suffix = re.search(r'\.([a-zA-Z0-9]+)\?', i['url']).group(1) other.append(Media(base_url=i['url'], backup_url=i['backup_url'], suffix=suffix)) except KeyError: pass # extract img url img_url = re.search('property="og:image" content="([^"]*)"', html).groups()[0] if not img_url.startswith('http'): # https://github.com/HFrost0/bilix/issues/52 just for some video img_url = 'http:' + img_url.split('@')[0] # construct data video_info = VideoInfo(title=title, aid=aid, cid=cid, status=status, p=p, pages=pages, img_url=img_url, bvid=bvid, dash=dash, other=other, desc=desc, tags=tags) return video_info
_get_video_info_from_html函数async def _get_video_info_from_html(client: httpx.AsyncClient, url: str) -> VideoInfo: res = await req_retry(client, url, follow_redirects=True) if str(res.url).startswith("https://www.bilibili.com/festival"): raise APIInvalidError("特殊节日页面", url) html = res.text if "window._riskdata_" in html: raise APIInvalidError("web 前端访问被风控", url) if "window.__INITIAL_STATE__" in html: return await _parse_bv_html(client,url, html) elif "__NEXT_DATA__" in html: video_info = _parse_ep_html(url, html) await _attach_ep_dash(client, video_info) return video_info else: raise APIUnsupportedError("未知页面类型", url)
太牛了,感谢, 救世主一样的瞬间出现.
因为我着急用,所以写了一个临时修复的方法,修改
bilix/sites/bilibili/api.py中的两处代码 1._parse_bv_html函数async def _parse_bv_html(client,url, html: str) -> VideoInfo: init_info = re.search(r'<script>window.__INITIAL_STATE__=({.*?});\(', html).groups()[0] # this line may raise init_info = json.loads(init_info) if len(init_info.get('error', {})) > 0: raise APIResourceError("视频已失效", url) # 啊叻?视频不见了?在分区下载的时候可能产生 # extract meta pages = [] h1_title = legal_title(re.search('<h1[^>]*title="([^"]*)"', html).groups()[0]) status = Status(**init_info['videoData']['stat']) bvid = init_info['bvid'] desc = init_info['videoData'].get('desc', '') tags = [i['tag_name'] for i in init_info['tags']] aid = init_info['aid'] (p, cid), = init_info['cidMap'][bvid]['cids'].items() p = int(p) - 1 title = legal_title(init_info['videoData']['title']) base_url = url.split('?')[0] for idx, i in enumerate(init_info['videoData']['pages']): p_url = f"{base_url}?p={idx + 1}" p_name = f"P{idx + 1}-{i['part']}" if len(init_info['videoData']['pages']) > 1 else '' pages.append(Page(p_name=p_name, p_url=p_url)) # extract dash and flv_url play_info_response = await req_retry(client, f'https://api.bilibili.com/x/player/wbi/playurl?bvid={bvid}&cid={cid}') play_info = json.loads(play_info_response.text)['data'] dash, other = None, [] try: dash = Dash.from_dict(play_info) except KeyError: pass try: for i in play_info['durl']: suffix = re.search(r'\.([a-zA-Z0-9]+)\?', i['url']).group(1) other.append(Media(base_url=i['url'], backup_url=i['backup_url'], suffix=suffix)) except KeyError: pass # extract img url img_url = re.search('property="og:image" content="([^"]*)"', html).groups()[0] if not img_url.startswith('http'): # https://github.com/HFrost0/bilix/issues/52 just for some video img_url = 'http:' + img_url.split('@')[0] # construct data video_info = VideoInfo(title=title, aid=aid, cid=cid, status=status, p=p, pages=pages, img_url=img_url, bvid=bvid, dash=dash, other=other, desc=desc, tags=tags) return video_info
_get_video_info_from_html函数async def _get_video_info_from_html(client: httpx.AsyncClient, url: str) -> VideoInfo: res = await req_retry(client, url, follow_redirects=True) if str(res.url).startswith("https://www.bilibili.com/festival"): raise APIInvalidError("特殊节日页面", url) html = res.text if "window._riskdata_" in html: raise APIInvalidError("web 前端访问被风控", url) if "window.__INITIAL_STATE__" in html: return await _parse_bv_html(client,url, html) elif "__NEXT_DATA__" in html: video_info = _parse_ep_html(url, html) await _attach_ep_dash(client, video_info) return video_info else: raise APIUnsupportedError("未知页面类型", url)太牛了,感谢, 救世主一样的瞬间出现.
我刚刚发现需要再加一个fnval=4048参数才能下载音频,所以又更新了下代码,希望能帮到你~
因为我着急用,所以写了一个临时修复的方法,修改
bilix/sites/bilibili/api.py中的两处代码 1._parse_bv_html函数async def _parse_bv_html(client,url, html: str) -> VideoInfo: init_info = re.search(r'<script>window.__INITIAL_STATE__=({.*?});\(', html).groups()[0] # this line may raise init_info = json.loads(init_info) if len(init_info.get('error', {})) > 0: raise APIResourceError("视频已失效", url) # 啊叻?视频不见了?在分区下载的时候可能产生 # extract meta pages = [] h1_title = legal_title(re.search('<h1[^>]*title="([^"]*)"', html).groups()[0]) status = Status(**init_info['videoData']['stat']) bvid = init_info['bvid'] desc = init_info['videoData'].get('desc', '') tags = [i['tag_name'] for i in init_info['tags']] aid = init_info['aid'] (p, cid), = init_info['cidMap'][bvid]['cids'].items() p = int(p) - 1 title = legal_title(init_info['videoData']['title']) base_url = url.split('?')[0] for idx, i in enumerate(init_info['videoData']['pages']): p_url = f"{base_url}?p={idx + 1}" p_name = f"P{idx + 1}-{i['part']}" if len(init_info['videoData']['pages']) > 1 else '' pages.append(Page(p_name=p_name, p_url=p_url)) # extract dash and flv_url play_info_response = await req_retry(client, f'https://api.bilibili.com/x/player/wbi/playurl?bvid={bvid}&cid={cid}') play_info = json.loads(play_info_response.text)['data'] dash, other = None, [] try: dash = Dash.from_dict(play_info) except KeyError: pass try: for i in play_info['durl']: suffix = re.search(r'\.([a-zA-Z0-9]+)\?', i['url']).group(1) other.append(Media(base_url=i['url'], backup_url=i['backup_url'], suffix=suffix)) except KeyError: pass # extract img url img_url = re.search('property="og:image" content="([^"]*)"', html).groups()[0] if not img_url.startswith('http'): # https://github.com/HFrost0/bilix/issues/52 just for some video img_url = 'http:' + img_url.split('@')[0] # construct data video_info = VideoInfo(title=title, aid=aid, cid=cid, status=status, p=p, pages=pages, img_url=img_url, bvid=bvid, dash=dash, other=other, desc=desc, tags=tags) return video_info
_get_video_info_from_html函数async def _get_video_info_from_html(client: httpx.AsyncClient, url: str) -> VideoInfo: res = await req_retry(client, url, follow_redirects=True) if str(res.url).startswith("https://www.bilibili.com/festival"): raise APIInvalidError("特殊节日页面", url) html = res.text if "window._riskdata_" in html: raise APIInvalidError("web 前端访问被风控", url) if "window.__INITIAL_STATE__" in html: return await _parse_bv_html(client,url, html) elif "__NEXT_DATA__" in html: video_info = _parse_ep_html(url, html) await _attach_ep_dash(client, video_info) return video_info else: raise APIUnsupportedError("未知页面类型", url)太牛了,感谢, 救世主一样的瞬间出现.
我刚刚发现需要再加一个fnval=4048参数才能下载音频,所以又更新了下代码,希望能帮到你~
给了我巨大的帮助,感谢老板,好人一生平安, 工作流回复正常了