[extractor/bilibili:SpaceVideo] Extract signature (#7149)
Authored by: elyse0 Closes #6956, closes #7081
This commit is contained in:
parent
03789976d3
commit
6f10cdcf7e
1 changed files with 52 additions and 5 deletions
|
@ -1,7 +1,9 @@
|
||||||
import base64
|
import base64
|
||||||
import functools
|
import functools
|
||||||
|
import hashlib
|
||||||
import itertools
|
import itertools
|
||||||
import math
|
import math
|
||||||
|
import time
|
||||||
import urllib.error
|
import urllib.error
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
|
|
||||||
|
@ -26,6 +28,7 @@ from ..utils import (
|
||||||
srt_subtitles_timecode,
|
srt_subtitles_timecode,
|
||||||
str_or_none,
|
str_or_none,
|
||||||
traverse_obj,
|
traverse_obj,
|
||||||
|
try_call,
|
||||||
unified_timestamp,
|
unified_timestamp,
|
||||||
unsmuggle_url,
|
unsmuggle_url,
|
||||||
url_or_none,
|
url_or_none,
|
||||||
|
@ -514,19 +517,63 @@ class BilibiliSpaceVideoIE(BilibiliSpaceBaseIE):
|
||||||
'id': '3985676',
|
'id': '3985676',
|
||||||
},
|
},
|
||||||
'playlist_mincount': 178,
|
'playlist_mincount': 178,
|
||||||
|
}, {
|
||||||
|
'url': 'https://space.bilibili.com/313580179/video',
|
||||||
|
'info_dict': {
|
||||||
|
'id': '313580179',
|
||||||
|
},
|
||||||
|
'playlist_mincount': 92,
|
||||||
}]
|
}]
|
||||||
|
|
||||||
|
def _extract_signature(self, playlist_id):
|
||||||
|
session_data = self._download_json('https://api.bilibili.com/x/web-interface/nav', playlist_id, fatal=False)
|
||||||
|
|
||||||
|
key_from_url = lambda x: x[x.rfind('/') + 1:].split('.')[0]
|
||||||
|
img_key = traverse_obj(
|
||||||
|
session_data, ('data', 'wbi_img', 'img_url', {key_from_url})) or '34478ba821254d9d93542680e3b86100'
|
||||||
|
sub_key = traverse_obj(
|
||||||
|
session_data, ('data', 'wbi_img', 'sub_url', {key_from_url})) or '7e16a90d190a4355a78fd00b32a38de6'
|
||||||
|
|
||||||
|
session_key = img_key + sub_key
|
||||||
|
|
||||||
|
signature_values = []
|
||||||
|
for position in (
|
||||||
|
46, 47, 18, 2, 53, 8, 23, 32, 15, 50, 10, 31, 58, 3, 45, 35, 27, 43, 5, 49, 33, 9, 42, 19, 29, 28, 14, 39,
|
||||||
|
12, 38, 41, 13, 37, 48, 7, 16, 24, 55, 40, 61, 26, 17, 0, 1, 60, 51, 30, 4, 22, 25, 54, 21, 56, 59, 6, 63,
|
||||||
|
57, 62, 11, 36, 20, 34, 44, 52
|
||||||
|
):
|
||||||
|
char_at_position = try_call(lambda: session_key[position])
|
||||||
|
if char_at_position:
|
||||||
|
signature_values.append(char_at_position)
|
||||||
|
|
||||||
|
return ''.join(signature_values)[:32]
|
||||||
|
|
||||||
def _real_extract(self, url):
|
def _real_extract(self, url):
|
||||||
playlist_id, is_video_url = self._match_valid_url(url).group('id', 'video')
|
playlist_id, is_video_url = self._match_valid_url(url).group('id', 'video')
|
||||||
if not is_video_url:
|
if not is_video_url:
|
||||||
self.to_screen('A channel URL was given. Only the channel\'s videos will be downloaded. '
|
self.to_screen('A channel URL was given. Only the channel\'s videos will be downloaded. '
|
||||||
'To download audios, add a "/audio" to the URL')
|
'To download audios, add a "/audio" to the URL')
|
||||||
|
|
||||||
|
signature = self._extract_signature(playlist_id)
|
||||||
|
|
||||||
def fetch_page(page_idx):
|
def fetch_page(page_idx):
|
||||||
|
query = {
|
||||||
|
'keyword': '',
|
||||||
|
'mid': playlist_id,
|
||||||
|
'order': 'pubdate',
|
||||||
|
'order_avoided': 'true',
|
||||||
|
'platform': 'web',
|
||||||
|
'pn': page_idx + 1,
|
||||||
|
'ps': 30,
|
||||||
|
'tid': 0,
|
||||||
|
'web_location': 1550101,
|
||||||
|
'wts': int(time.time()),
|
||||||
|
}
|
||||||
|
query['w_rid'] = hashlib.md5(f'{urllib.parse.urlencode(query)}{signature}'.encode()).hexdigest()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
response = self._download_json('https://api.bilibili.com/x/space/arc/search',
|
response = self._download_json('https://api.bilibili.com/x/space/wbi/arc/search',
|
||||||
playlist_id, note=f'Downloading page {page_idx}',
|
playlist_id, note=f'Downloading page {page_idx}', query=query)
|
||||||
query={'mid': playlist_id, 'pn': page_idx + 1, 'jsonp': 'jsonp'})
|
|
||||||
except ExtractorError as e:
|
except ExtractorError as e:
|
||||||
if isinstance(e.cause, urllib.error.HTTPError) and e.cause.code == 412:
|
if isinstance(e.cause, urllib.error.HTTPError) and e.cause.code == 412:
|
||||||
raise ExtractorError(
|
raise ExtractorError(
|
||||||
|
@ -556,9 +603,9 @@ class BilibiliSpaceVideoIE(BilibiliSpaceBaseIE):
|
||||||
class BilibiliSpaceAudioIE(BilibiliSpaceBaseIE):
|
class BilibiliSpaceAudioIE(BilibiliSpaceBaseIE):
|
||||||
_VALID_URL = r'https?://space\.bilibili\.com/(?P<id>\d+)/audio'
|
_VALID_URL = r'https?://space\.bilibili\.com/(?P<id>\d+)/audio'
|
||||||
_TESTS = [{
|
_TESTS = [{
|
||||||
'url': 'https://space.bilibili.com/3985676/audio',
|
'url': 'https://space.bilibili.com/313580179/audio',
|
||||||
'info_dict': {
|
'info_dict': {
|
||||||
'id': '3985676',
|
'id': '313580179',
|
||||||
},
|
},
|
||||||
'playlist_mincount': 1,
|
'playlist_mincount': 1,
|
||||||
}]
|
}]
|
||||||
|
|
Loading…
Reference in a new issue