Skip to content

Commit a697223

Browse files
committed
UPDATE: 增加B站Android官方API, 具体参考python\BiliHelper.ipynb
TODO: 看看能不能直接从B站下资源?
1 parent 67457f5 commit a697223

File tree

2 files changed

+180
-102
lines changed

2 files changed

+180
-102
lines changed

app/src/main/java/com/brainor/bilihelper/Api.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,10 @@ static String getMediaURL3(Long cid) {//HTML5播放器获得视频地址, checke
8686
url += "&sign=" + getSign(url, appSecret);
8787
return url;
8888
}
89+
static String getMediaURL4(SeriesInfo seriesInfo){//Android客户端官方API
8990

91+
return "";
92+
}
9093
static String getPageInfoURL(String aid, int page) {////利用aid获得PageInfo
9194
String url;
9295
if (page > 0) {//av开头的id, 获取的是视频

python/BiliHelper.ipynb

Lines changed: 177 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
"metadata": {},
77
"outputs": [],
88
"source": [
9-
"\n",
109
"appSecret = \"94aba54af9065f71de72f5508f1cd42e\"\n",
1110
"appKey = \"84956560bc028eb7\"\n",
1211
"appkey = \"c1b107428d337928\"\n",
@@ -121,104 +120,11 @@
121120
"print('{:.0f}s'.format(cid2DownUrl(list2Cid(seasonId2List(1071)))['durl'][0]['length']/1000))"
122121
]
123122
},
124-
{
125-
"cell_type": "code",
126-
"execution_count": 64,
127-
"metadata": {},
128-
"outputs": [
129-
{
130-
"name": "stdout",
131-
"output_type": "stream",
132-
"text": [
133-
"15s\n"
134-
]
135-
}
136-
],
137-
"source": [
138-
"print('{:.0f}s'.format(cid2DownUrl(list2Cid(seasonId2List(进击)))['durl'][0]['length']/1000))"
139-
]
140-
},
141-
{
142-
"cell_type": "code",
143-
"execution_count": 10,
144-
"metadata": {},
145-
"outputs": [
146-
{
147-
"data": {
148-
"text/plain": [
149-
"{'code': -404, 'message': '结果为空或者已被删除'}"
150-
]
151-
},
152-
"execution_count": 10,
153-
"metadata": {},
154-
"output_type": "execute_result"
155-
}
156-
],
157-
"source": [
158-
"cid2DownUrl(38521143)"
159-
]
160-
},
161-
{
162-
"cell_type": "code",
163-
"execution_count": 7,
164-
"metadata": {},
165-
"outputs": [
166-
{
167-
"data": {
168-
"text/plain": [
169-
"61573130"
170-
]
171-
},
172-
"execution_count": 7,
173-
"metadata": {},
174-
"output_type": "execute_result"
175-
}
176-
],
177-
"source": [
178-
"list2Cid(seasonId2List(25617))"
179-
]
180-
},
181-
{
182-
"cell_type": "code",
183-
"execution_count": 39,
184-
"metadata": {},
185-
"outputs": [
186-
{
187-
"data": {
188-
"text/plain": [
189-
"{'accept_description': ['高清 720P', '流畅 360P'],\n",
190-
" 'accept_format': 'hdmp4,mp4',\n",
191-
" 'accept_quality': [48, 16],\n",
192-
" 'bp': 0,\n",
193-
" 'code': 0,\n",
194-
" 'durl': [{'length': 15126,\n",
195-
" 'order': 1,\n",
196-
" 'size': 124627,\n",
197-
" 'url': 'http://cn-zjwz4-dx-v-09.acgvideo.com/upgcxcode/43/69/8986943/8986943-1-16.mp4?expires=1541192700&platform=ios&ssig=uQRrBovVZESrWYpBa-ZMJQ&oi=3078818617&nfa=7VMUDqBQpI8VGBbhQ1faUQ==&dynamic=1&hfa=2045739811&hfb=ZWI2ODUxMTI1YmRhNTcxZjcwNTFjMTUwOTdkZTc0ZDM=&trid=ad4383a37d9a4b7797f807f4cfc192ed&nfc=1'}],\n",
198-
" 'format': 'mp4',\n",
199-
" 'from': 'local',\n",
200-
" 'has_paid': False,\n",
201-
" 'quality': 16,\n",
202-
" 'result': 'suee',\n",
203-
" 'seek_param': 'start',\n",
204-
" 'seek_type': 'second',\n",
205-
" 'timelength': 15126}"
206-
]
207-
},
208-
"execution_count": 39,
209-
"metadata": {},
210-
"output_type": "execute_result"
211-
}
212-
],
213-
"source": [
214-
"cid2DownUrl(list2Cid(seasonId2List(进击)))"
215-
]
216-
},
217123
{
218124
"cell_type": "markdown",
219125
"metadata": {},
220126
"source": [
221-
"获取Token"
127+
"## 获取Token"
222128
]
223129
},
224130
{
@@ -263,7 +169,7 @@
263169
"cell_type": "markdown",
264170
"metadata": {},
265171
"source": [
266-
"BiliPlus"
172+
"# BiliPlus"
267173
]
268174
},
269175
{
@@ -323,25 +229,194 @@
323229
"# to_para('ca775807bff9cf1eoudanyi6456')"
324230
]
325231
},
232+
{
233+
"cell_type": "markdown",
234+
"metadata": {},
235+
"source": [
236+
"# B站登陆API"
237+
]
238+
},
239+
{
240+
"cell_type": "code",
241+
"execution_count": 9,
242+
"metadata": {},
243+
"outputs": [],
244+
"source": [
245+
"import requests\n",
246+
"url='https://passport.bilibili.com/login'\n",
247+
"def encryptPassword(password):\n",
248+
" from Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5\n",
249+
" import base64\n",
250+
" from Crypto.PublicKey import RSA\n",
251+
" pub_key=requests.get(url,params={'act':'getkey'}).json()\n",
252+
" rsa_key = RSA.importKey(pub_key['key'])\n",
253+
" cipher = Cipher_pkcs1_v1_5.new(rsa_key)\n",
254+
" cipher_text = base64.b64encode(cipher.encrypt((pub_key['hash']+password).encode())) # 通过生成的对象加密message明文,注意,在python3中加密的数据必须是bytes类型的数据,不能是str类型的数据\n",
255+
" return(cipher_text.decode())\n",
256+
"def capcha():\n",
257+
" data=requests.get(url[:-5]+'qrcode/getLoginUrl').json()['data']\n",
258+
" data2=requests.post(url[:-5]+'qrcode/getLoginInfo',data={'oauthKey':data['oauthKey'],'gourl':url[:-5]+'account/security#/home'})\n",
259+
" print(data2)\n",
260+
"res=requests.post(url+'/web/login/v2',data={'username':'brainor','password':encryptPassword('oudanyi6456'),'keep':True,'key':'','goUrl':url[:-5]+'account/security#/home','challenge':'','validate':'','seccode':''})"
261+
]
262+
},
263+
{
264+
"cell_type": "code",
265+
"execution_count": 17,
266+
"metadata": {},
267+
"outputs": [],
268+
"source": [
269+
"data=requests.get(url[:-5]+'qrcode/getLoginUrl')\n",
270+
"data2=requests.post(url[:-5]+'qrcode/getLoginInfo',data={'oauthKey':data.json()['data']['oauthKey'],'gourl':url[:-5]+'account/security#/home'})\n",
271+
"requests.get(url[:-5]+'web/captcha/combine?plat=2').text"
272+
]
273+
},
274+
{
275+
"cell_type": "markdown",
276+
"metadata": {},
277+
"source": [
278+
"B站Android API"
279+
]
280+
},
281+
{
282+
"cell_type": "raw",
283+
"metadata": {},
284+
"source": [
285+
"Device: android\n",
286+
"Description: 普通版\n",
287+
"AppKey: 1d8b6e7d45233436\n",
288+
"SecretKey: 560c52ccd288fed045859ed18bffd973\n",
289+
"\n",
290+
"Device: android_i\n",
291+
"Description: 国际版\n",
292+
"AppKey: bb3101000e232e27\n",
293+
"SecretKey: 36efcfed79309338ced0380abd824ac1\n",
294+
"\n",
295+
"Device: android_b\n",
296+
"Description: 概念版\n",
297+
"AppKey: 07da50c9a0bf829f\n",
298+
"SecretKey: 25bdede4e1581c836cab73a48790ca6e\n",
299+
"\n",
300+
"Device: android_tv\n",
301+
"Description: 电视版\n",
302+
"AppKey: 4409e2ce8ffd12b8\n",
303+
"SecretKey: 59b43e04ad6965f34319062b478f83dd\n",
304+
"\n",
305+
"Device: biliLink\n",
306+
"Description: 直播\n",
307+
"AppKey: 37207f2beaebf8d7\n",
308+
"SecretKey: e988e794d4d4b6dd43bc0e89d6e90c43\n",
309+
"\n",
310+
"视频\n",
311+
"AppKey: iVGUTjsxvpLeuDCf\n",
312+
"SecretKey: aHRmhWMLkdeMuILqORnYZocwMBpMEOdt\n"
313+
]
314+
},
326315
{
327316
"cell_type": "code",
328-
"execution_count": 12,
317+
"execution_count": 15,
318+
"metadata": {},
319+
"outputs": [
320+
{
321+
"name": "stdout",
322+
"output_type": "stream",
323+
"text": [
324+
"{\"ts\":1546418225,\"code\":0,\"data\":{\"status\":0,\"token_info\":{\"mid\":1381806,\"access_token\":\"de6c0d7057f6783d0c081f87aab2b711\",\"refresh_token\":\"5783be144b9a08ea14e82087bc544d11\",\"expires_in\":2592000},\"cookie_info\":{\"cookies\":[{\"name\":\"bili_jct\",\"value\":\"eca499cadf661f9c8e72566326b21ad4\",\"http_only\":0,\"expires\":1549010225},{\"name\":\"DedeUserID\",\"value\":\"1381806\",\"http_only\":0,\"expires\":1549010225},{\"name\":\"DedeUserID__ckMd5\",\"value\":\"357668196c082654\",\"http_only\":0,\"expires\":1549010225},{\"name\":\"sid\",\"value\":\"m3mqmg7t\",\"http_only\":0,\"expires\":1549010225},{\"name\":\"SESSDATA\",\"value\":\"36d625a6%2C1549010225%2C4f9a5611\",\"http_only\":1,\"expires\":1549010225}],\"domains\":[\".bilibili.com\",\".biligame.com\",\".im9.com\",\".bigfunapp.cn\"]},\"sso\":[\"https://passport.bilibili.com/api/v2/sso\",\"https://passport.biligame.com/api/v2/sso\",\"https://passport.im9.com/api/v2/sso\",\"https://passport.bigfunapp.cn/api/v2/sso\"]}}\n"
325+
]
326+
}
327+
],
328+
"source": [
329+
"import requests\n",
330+
"import hashlib\n",
331+
"import time\n",
332+
"from urllib import parse\n",
333+
"#登陆API\n",
334+
"url_login='https://passport.bilibili.com/api/'\n",
335+
"AppKey='1d8b6e7d45233436'\n",
336+
"SecretKey='560c52ccd288fed045859ed18bffd973'\n",
337+
"defaultParam={'build':5350000,'mobi_app':'android','platform':'android'}\n",
338+
"cookies={}\n",
339+
"def getSign(params):\n",
340+
" params.update(appkey=AppKey)\n",
341+
"# params={k: params[k] for k in sorted(params)}\n",
342+
" sign=hashlib.md5((parse.urlencode(sorted(params.items()))+SecretKey).encode()).hexdigest()\n",
343+
" return {**params,'sign':sign}\n",
344+
"def encrypt_pw(pw,headers):\n",
345+
" from Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5\n",
346+
" import base64\n",
347+
" from Crypto.PublicKey import RSA\n",
348+
" req_getKey=requests.post(url_login+'oauth2/getKey',data=getSign(defaultParam))\n",
349+
" cookies['sid']=req_getKey.cookies['sid']\n",
350+
" rsa_key = RSA.importKey(req_getKey.json()['data']['key'])\n",
351+
" cipher = Cipher_pkcs1_v1_5.new(rsa_key)\n",
352+
" cipher_text = base64.b64encode(cipher.encrypt((req_getKey.json()['data']['hash']+pw).encode())) # 通过生成的对象加密message明文,注意,在python3中加密的数据必须是bytes类型的数据,不能是str类型的数据\n",
353+
" return(cipher_text.decode())\n",
354+
"\n",
355+
"res=requests.post(url_login+'v3/oauth2/login',\n",
356+
" data=getSign({'appkey':AppKey,'username':'18910958663',**defaultParam,'password':encrypt_pw('oudanyi6456',cookies),'ts':int(time.time())}),\n",
357+
" headers={'Display-ID': 'FB3E62A0-4621-440A-B1A5-E6EE67E74AD427879infoc-1545829757','Buvid': 'FB3E62A0-4621-440A-B1A5-E6EE67E74AD427879infoc','User-Agent': 'Mozilla/5.0 BiliDroid/5.35.0 ([email protected])','Device-ID': 'RSYQJEYnEiBDekh6BjQGNAZkVDUGYwBlUS1RZ1FpC2oMPAk'},\n",
358+
" cookies=cookies)\n",
359+
"print(res.text)"
360+
]
361+
},
362+
{
363+
"cell_type": "code",
364+
"execution_count": 17,
329365
"metadata": {},
330366
"outputs": [
331367
{
332368
"data": {
333369
"text/plain": [
334-
"{'44': 3, '1': 4}"
370+
"{'accept_format': 'hdflv2,flv,flv720,flv480,mp4',\n",
371+
" 'code': 0,\n",
372+
" 'durl': [{'size': 100477741,\n",
373+
" 'ahead': 'EZA=',\n",
374+
" 'length': 1473171,\n",
375+
" 'vhead': 'AWQAH//hABhnZAAfrNnA2D3n4QAAAwPpAAC7gA8YMZ4BAAVo6bssiw==',\n",
376+
" 'backup_url': ['http://upos-hz-mirrorks3u.acgvideo.com/upgcxcode/49/10/69511049/69511049-1-32.flv?e=ig8euxZM2rNcNbRghwdVhwdlhWNVhwdVhoNvNC8BqJIzNbfqXBvEuENvNC8aNEVEtEvE9IMvXBvE2ENvNCImNEVEIj0Y2J_aug859r1qXg8xNEVE5XREto8GuFGv2U7SuxI72X6fTr859IB_&deadline=1546425971&gen=playurl&nbs=1&oi=2093829167&os=ks3u&platform=android&trid=0cf7fec32b324d2786d4abb189d059b5&uipk=5&upsig=63517ec7795aa8fc5818d3ef1ac85a97',\n",
377+
" 'http://upos-hz-mirrorcos.acgvideo.com/upgcxcode/49/10/69511049/69511049-1-32.flv?um_deadline=1546425971&platform=android&rate=1200000&oi=2093829167&um_sign=9e87f2ebef917cdf22557a288424a8ee&gen=playurl&os=cos&trid=0cf7fec32b324d2786d4abb189d059b5'],\n",
378+
" 'url': 'http://124.202.167.12/upgcxcode/49/10/69511049/69511049-1-32.flv?e=ig8euxZM2rNcNbRghwdVhwdlhWNVhwdVhoNvNC8BqJIzNbfqXBvEuENvNC8aNEVEtEvE9IMvXBvE2ENvNCImNEVEIj0Y2J_aug859r1qXg8xNEVE5XREto8GuFGv2U7SuxI72X6fTr859IB_&deadline=1546425971&gen=playurl&nbs=1&oi=2093829167&os=acache&platform=android&trid=0cf7fec32b324d2786d4abb189d059b5&uipk=5&upsig=543a9a839e6564aa229633da47d4caa6',\n",
379+
" 'order': 1}],\n",
380+
" 'seek_param': 'start',\n",
381+
" 'format': 'flv480',\n",
382+
" 'fnval': 0,\n",
383+
" 'video_project': True,\n",
384+
" 'fnver': 0,\n",
385+
" 'accept_quality': [112, 80, 64, 32, 16],\n",
386+
" 'bp': 0,\n",
387+
" 'quality': 32,\n",
388+
" 'timelength': 1473171,\n",
389+
" 'result': 'suee',\n",
390+
" 'seek_type': 'offset',\n",
391+
" 'has_paid': True,\n",
392+
" 'vip_type': 2,\n",
393+
" 'vip_status': 1,\n",
394+
" 'from': 'local',\n",
395+
" 'video_codecid': 7,\n",
396+
" 'accept_description': ['高清 1080P+',\n",
397+
" '高清 1080P',\n",
398+
" '高清 720P',\n",
399+
" '清晰 480P',\n",
400+
" '流畅 360P'],\n",
401+
" 'status': 13}"
335402
]
336403
},
337-
"execution_count": 12,
404+
"execution_count": 17,
338405
"metadata": {},
339406
"output_type": "execute_result"
340407
}
341408
],
342409
"source": [
343-
"a={'1':4}\n",
344-
"{'44':3,**a}"
410+
"url_down='https://api.bilibili.com/pgc/player/api/playurl'\n",
411+
"params_video={'aid':35822946,'cid':68495959}\n",
412+
"params_video={\"aid\":31861445,\"cid\":55724249}#港台\n",
413+
"params_video={'aid':39564264,'cid':69511049}#会员\n",
414+
"params_user={'mid':1381806,'access_key':'565517dc877bcceae69718005cdebec1'}#我的\n",
415+
"params_user={'mid':17333796,'access_key':'9b278f3465ef1ade1a23bcdbe8560d11'}#会员\n",
416+
"params={'appKey':AppKey,**defaultParam,'buvid':'FB3E62A0-4621-440A-B1A5-E6EE67E74AD427879infoc',\n",
417+
" 'expire':1548421792,'fnval':0,'fnver':0,'module':'bangumi','npcybs':1,'otype':'json','qn':32,'ts':1546410215,\n",
418+
" **params_video,**params_user}\n",
419+
"requests.get(url_down,params=getSign(params)).json()"
345420
]
346421
},
347422
{
@@ -368,7 +443,7 @@
368443
"name": "python",
369444
"nbconvert_exporter": "python",
370445
"pygments_lexer": "ipython3",
371-
"version": "3.7.0"
446+
"version": "3.7.1"
372447
}
373448
},
374449
"nbformat": 4,

0 commit comments

Comments
 (0)