#### 获取国际地区代码
GET
http://passport.bilibili.com/web/generic/country/list
**json回复:**
根对象:
| 字段 | 类型 | 内容 | 备注 |
| ---- | ---- | -------- | ------- |
| code | num | 返回值 | 0:成功 |
| data | obj | 数据本体 | |
data
对象:
| 字段 | 类型 | 内容 | 备注 |
| ------ | ----- | -------------- | ---- |
| common | array | 常用国家或地区 | |
| others | array | 其他国家或地区 | |
data
中的common
和others
数组:
| 项 | 类型 | 内容 | 备注 |
| ---- | ---- | --------------- | ---- |
| 0 | obj | 国家或地区1 | |
| n | obj | 国家或地区(n+1) | |
| …… | obj | …… | …… |
common
和others
数组中的对象:
| 字段 | 类型 | 内容 | 备注 |
| ---------- | ---- | -------------- | ---- |
| id | num | 国际代码值 | |
| cname | str | 国家或地区名 | |
| country_id | str | 国家或地区区号 | |
#### 发送短信验证码
POST
http://passport.bilibili.com/x/passport-login/web/sms/send
**正文参数( application/x-www-form-urlencoded ):**
| 参数名 | 类型 | 内容 | 必要性 | 备注 |
| --------- | ---- | ------------------------- | ------ | ------------ |
| tel | num | 手机号码 | 必要 | |
| cid | num | 国际地区代码 | 必要 | |
| source | str | 固定为main_web
| 必要 | |
| token | str | 在获取gt,challenge处url有 | 必要 | |
| challenge | str | 极验challenge | 必要 | 从B站API获取 |
| validate | str | 极验结果 | 必要 | 从极验获取 |
| seccode | str | 极验结果+ | jordan | 必要 |
**json回复:**
根对象:
| 字段 | 类型 | 内容 | 备注 |
| ------------------------------------------------------------ | ---- | -------- | --------------- |
| code | num | 返回值 | 0:成功 |
| -400:请求错误 | | | |
| 1002:手机号格式错误 | | | |
| 86203:短信发送次数已达上限 | | | |
| 1003:验证码已经发送 | | | |
| 1025:该手机号在哔哩哔哩有过永久封禁记录,无法再次注册或绑定新账号 | | | |
| 2400:登录秘钥错误 | | | |
| 2406:验证极验服务出错 | | | |
| message | str | 错误信息 | 成功为0 |
| data | obj | 数据 | 内含captcha_key |
captcha_key
在下方传参时需要,请备用.
#### 使用短信验证码登录
验证登录成功后会进行设置以下cookie项:
DedeUserID
DedeUserID__ckMd5
SESSDATA
bili_jct
**正文参数( application/x-www-form-urlencoded ):**
| 参数名 | 类型 | 内容 | 必要性 | 备注 |
| ----------- | ---- | ------------------------------ | ------ | ----------------------------------------------------------- |
| cid | num | 国际地区代码 | 必要 | |
| tel | num | 手机号码 | 必要 | |
| code | num | 短信验证码 | 必要 | 超时时间为5min |
| source | str | 固定为main_web
| 必要 | |
| captcha_key | str | 上方发送短信验证码时的一个参数 | 必要 | |
| go_url | str | 跳转url | 非必要 | 默认为[https://www.bilibili.com](https://www.bilibili.com/) |
| keep | str | 未知 | 非必要 | 默认为true |
**json回复:**
根对象:
| 字段 | 类型 | 内容 | 备注 |
| ---------------------------- | ---- | -------- | ------- |
| code | num | 返回值 | 0:成功 |
| -400:请求错误 | | | |
| 1006:请输入正确的短信验证码 | | | |
| 1007:短信验证码已过期 | | | |
| message | str | 错误信息 | |
| data | obj | 信息本体 | |
data
对象:
| 字段 | 类型 | 内容 | 备注 |
| ------ | ---- | ------- | ----------------------------------------------------------- |
| is_new | bool | false | 未知,估计是未注册时自动注册新用户 |
| status | num | 0 | 未知,可能0就是成功吧 |
| url | str | 跳转url | 默认为[https://www.bilibili.com](https://www.bilibili.com/) |
[该部分API文档](https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/login/login_action/SMS.md)
## 获取下载视频URL
[获取视频详情(CID分P)](https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/video/videostream_url.md)->[获取视频流URL](https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/video/videostream_url.md)
这里就不过多赘述了,有兴趣的可以去看看
# 喜闻乐见的代码环节
登录
```java
package me.heartalborada.bilidownloader.utils;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import javafx.scene.control.Alert;
import me.heartalborada.bilidownloader.main;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.cookie.Cookie;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import static me.heartalborada.bilidownloader.utils.internet.sendPost;
public class login {
public static boolean checkIsLogin(){
String data= null;
try {
data = new internet().getWithCookie(
http://api.bilibili.com/x/web-interface/nav,
SESSDATA=+ main.SESSDATA+; bili_jct=+main.bili_jct
);
} catch (IOException e) {
e.printStackTrace();
}
if (data != null) {
if(JsonParser.parseString(data).getAsJsonObject().get(code).getAsInt()==0){
return true;
}
}
return false;
}
public static class password{
private static String key=;
private static String encrypt(String str) {
//base64编码的公钥
byte[] decoded = org.apache.commons.codec.binary.Base64.decodeBase64(key);
RSAPublicKey pubKey = null;
String outStr = null;
try {
pubKey = (RSAPublicKey) KeyFactory.getInstance(RSA).generatePublic(new X509EncodedKeySpec(decoded));
Cipher cipher = Cipher.getInstance(RSA);
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
outStr = Base64.encodeBase64String(cipher.doFinal(str.getBytes(StandardCharsets.UTF_8)));
} catch (InvalidKeySpecException | BadPaddingException | IllegalBlockSizeException | InvalidKeyException | NoSuchPaddingException | NoSuchAlgorithmException e) {
e.printStackTrace();
}
//RSA加密
return outStr;
}
private static String getHashAndKey(){
String data = null;
try {
data=new internet().Eget(http://passport.bilibili.com/login?act=getkey);
} catch (Exception e) {
e.printStackTrace();
}
key=JsonParser.parseString(data).getAsJsonObject().get(key).getAsString().replace(-----BEGIN PUBLIC KEY-----,).replace(-----END PUBLIC KEY-----,).replace(\n,);
return JsonParser.parseString(data).getAsJsonObject().get(hash).getAsString();
}
public static String[] getCaptcha(){
String data = null;
try {
data=new internet().Eget(https://passport.bilibili.com/web/captcha/combine?plat=6);
} catch (Exception e) {
e.printStackTrace();
}
JsonObject json = JsonParser.parseString(data).getAsJsonObject();
if(json.get(code).getAsInt()==0) {
json=json.getAsJsonObject(data).getAsJsonObject(result);
return new String[]{
json.get(gt).getAsString(),
json.get(challenge).getAsString(),
json.get(key).getAsString()
};
}
return null;
}
public static String getPw(String pw){
String pw1= getHashAndKey()+pw;
String tmp=null;
try {
tmp=encrypt(pw1);
} catch (Exception e) {
e.printStackTrace();
}
return tmp;
}
public static void doLogin(String acc, String pw, String[] captcha) {
HashMap<String,Object> map=new HashMap<>();
map.put(captchaType,6);
map.put(username, acc);
map.put(password, pw);
map.put(keep,true);
map.put(key,captcha[0]);
map.put(challenge,captcha[1]);
map.put(validate,captcha[2]);
map.put(seccode,captcha[3]);
try {
Object[] data=internet.sendPost(http://passport.bilibili.com/web/login/v2,map);
if (data != null) {
if(JsonParser.parseString(String.valueOf(data[0])).getAsJsonObject().get(code).getAsInt()==0){
JsonObject json=new JsonObject();
@SuppressWarnings(unchecked)
List<Cookie> list= (List<Cookie>) data[1];
for(Cookie cookie:list){
if(cookie.getName().equals(SESSDATA)){
json.addProperty(SESSDATA,cookie.getValue());
}
if(cookie.getName().equals(bili_jct)){
json.addProperty(bili_jct,cookie.getValue());
}
}
//new file().write(main.cookie_file_dir,json.toString());
//登录成功信息
} else {
int code=JsonParser.parseString(String.valueOf(data[0])).getAsJsonObject().get(code).getAsInt();
switch (code){
//检测是否登录
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static class sms{
public static LinkedHashMap<String,Integer> getSmsLocationMap(){
String data= null;
try {
data = new internet().Eget(http://passport.bilibili.com/web/generic/country/list);
} catch (Exception e) {
e.printStackTrace();
}
JsonObject json= JsonParser.parseString(data).getAsJsonObject().get(data).getAsJsonObject();
LinkedHashMap<String,Integer> map=new LinkedHashMap<>();
JsonArray array=json.get(common).getAsJsonArray();
for(JsonElement o:array){
JsonObject json1= o.getAsJsonObject();
map.put(json1.get(cname).getAsString(),json1.get(country_id).getAsInt());
}
array=json.get(others).getAsJsonArray();
for(JsonElement o:array){
JsonObject json1= o.getAsJsonObject();
map.put(json1.get(cname).getAsString(),json1.get(country_id).getAsInt());
}
return map;
}
public static String[] getCaptcha(){
String data = null;
try {
data=new internet().Eget(https://passport.bilibili.com/x/passport-login/captcha?source=main_web);
} catch (Exception e) {
e.printStackTrace();
}
JsonObject json = JsonParser.parseString(data).getAsJsonObject();
if(json.get(code).getAsInt()==0) {
JsonObject res=json.getAsJsonObject(data);
return new String[]{
res.getAsJsonObject(geetest).get(gt).getAsString(),
res.getAsJsonObject(geetest).get(challenge).getAsString(),
res.get(token).getAsString()
};
}
return null;
}
public static String SendSmsCaptcha(long phone_num, int cid, String[] captcha){
HashMap<String,Object> map=new HashMap<>();
map.put(tel,phone_num);
map.put(cid,cid);
map.put(source,main_web);
map.put(token,captcha[0]);
map.put(challenge,captcha[1]);
map.put(validate,captcha[2]);
map.put(seccode,captcha[3]);
Object[] data=sendPost(http://passport.bilibili.com/x/passport-login/web/sms/send,map);
JsonObject json= JsonParser.parseString(String.valueOf(data[0])).getAsJsonObject();
if(json.get(code).getAsInt()==0){
//提示信息
return json.getAsJsonObject(data).get(captcha_key).getAsString();
} else {
int code=json.get(code).getAsInt();
switch (code){
//检测是否登录
}
}
return ;
}
public static void doLogin(int cid, long phone_num, long sms_code,String captcha_key){
HashMap<String,Object> map=new HashMap<>();
map.put(cid,cid);
map.put(tel,phone_num);
map.put(code,sms_code);
map.put(captcha_key,captcha_key);
map.put(source,main_web);
try {
Object[] data=internet.sendPost(https://passport.bilibili.com/x/passport-login/web/login/sms,map);
if (data != null) {
if(JsonParser.parseString(String.valueOf(data[0])).getAsJsonObject().get(code).getAsInt()==0){
JsonObject json=new JsonObject();
@SuppressWarnings(unchecked)
List<Cookie> list= (List<Cookie>) data[1];
for(Cookie cookie:list){
if(cookie.getName().equals(SESSDATA)){
json.addProperty(SESSDATA,cookie.getValue());
}
if(cookie.getName().equals(bili_jct)){
json.addProperty(bili_jct,cookie.getValue());
}
}
new file().write(main.cookie_file_dir,json.toString());
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.titleProperty().set(信息);
alert.setHeaderText(登录成功);
alert.showAndWait();
me.heartalborada.bilidownloader.gui.login.close();
me.heartalborada.bilidownloader.gui.captcha.close();
} else {
int code=JsonParser.parseString(String.valueOf(data[0])).getAsJsonObject().get(code).getAsInt();
switch (code){
//检测是否登录
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static class qr{
public static String getOauthKey(){
String data= null;
try {
data = new internet().Eget(http://passport.bilibili.com/qrcode/getLoginUrl);
} catch (Exception e) {
e.printStackTrace();
}
return JsonParser.parseString(data).getAsJsonObject().getAsJsonObject(data).get(oauthKey).getAsString();
}
public static String[] IsLogin(String OauthKey) throws IOException {
HashMap<String,Object> map=new HashMap<>();
map.put(oauthKey,OauthKey);
Object[] data=sendPost(http://passport.bilibili.com/qrcode/getLoginInfo,map);
JsonObject json=JsonParser.parseString(String.valueOf(data[0])).getAsJsonObject();
if(!json.get(status).getAsBoolean()){
if(json.get(data).getAsInt()==-4){
return new String[]{0,未扫描};
}
if(json.get(data).getAsInt()==-5){
return new String[]{0,已扫描, 但未确认};
}
}
if(json.get(status).getAsBoolean()){
JsonObject json1=new JsonObject();
@SuppressWarnings(unchecked)
List<Cookie> list= (List<Cookie>) data[1];
for(Cookie cookie:list){
if(cookie.getName().equals(SESSDATA)){
json1.addProperty(SESSDATA,cookie.getValue());
}
if(cookie.getName().equals(bili_jct)){
json1.addProperty(bili_jct,cookie.getValue());
}
}
new file().write(main.cookie_file_dir,json1.toString());
//检测是否登录
return new String[]{1,json.getAsJsonObject(data).get(url).getAsString()};
}
return new String[]{0,未知错误, 错误代码+json.get(data).getAsInt()};
}
}
}
```
获取视频URL:
```java
package me.heartalborada.bilidownloader.utils;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import me.heartalborada.bilidownloader.main;
import java.math.BigDecimal;
import java.util.LinkedHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class video {
public static LinkedHashMap<String, Long> getCidList(String aid){
LinkedHashMap<String,Long> map=new LinkedHashMap<String,Long>();
String data=null;
try {
data=new internet().Eget(https://api.bilibili.com/x/web-interface/view?aid=+aid);
} catch (Exception e) {
e.printStackTrace();
}
JsonObject json= JsonParser.parseString(data).getAsJsonObject();
if(json.get(code).getAsInt()==0) {
JsonArray pages=json.get(data).getAsJsonObject().get(pages).getAsJsonArray();
int i=0;
for (JsonElement o : pages) {
map.put(P+i+ +o.getAsJsonObject().get(part).getAsString(),o.getAsJsonObject().get(cid).getAsLong());
i++;
}
}
return map;
}
public static String BVidToAid(String BVid){
String data=null;
try {
data=new internet().Eget(https://api.bilibili.com/x/web-interface/view?bvid=+BVid);
} catch (Exception e) {
e.printStackTrace();
}
JsonObject json=JsonParser.parseString(data).getAsJsonObject();
if(json.get(code).getAsInt()==0) {
return json.get(data).getAsJsonObject().get(aid).getAsString();
}
return 404;
}
private static JsonObject json;
public String getVideoUrl(String aid, long cid, int qn1){
String data=null;
try {
data=new internet().getWithCookie(
https://api.bilibili.com/x/player/playurl?avid=+aid+&cid=+cid+&fourk=1&qn=+qn1,
SESSDATA=+ main.SESSDATA+; bili_jct=+main.bili_jct
);
} catch (Exception e) {
e.printStackTrace();
}
json=JsonParser.parseString(data).getAsJsonObject();
System.out.println(json);
if(json.get(code).getAsInt()==0){
return json.getAsJsonObject(data).get(durl).getAsJsonArray().get(0).getAsJsonObject().get(url).getAsString();
}
return 404;
}
public static LinkedHashMap<String,Integer> getQuality(String aid, long cid){
LinkedHashMap<String,Integer>map= new LinkedHashMap<>();
String data=null;
try {
data=new internet().Eget(https://api.bilibili.com/x/player/playurl?avid=+aid+&cid=+cid+&fourk=1);
} catch (Exception e) {
e.printStackTrace();
}
JsonObject json=JsonParser.parseString(data).getAsJsonObject();
if(json.get(code).getAsInt()==0){
JsonArray description= json.get(data).getAsJsonObject().get(accept_description).getAsJsonArray();
JsonArray quality= json.get(data).getAsJsonObject().get(accept_quality).getAsJsonArray();
for(int i=0;i<description.size();i++){
map.put(description.get(i).getAsString(),quality.get(i).getAsInt());
}
}
return map;
}
public static JsonObject getVideoJson(String aid){
String data=null;
try {
data = new internet().Eget(https://api.bilibili.com/x/web-interface/view?aid= + aid);
} catch (Exception e) {
e.printStackTrace();
}
return JsonParser.parseString(data).getAsJsonObject();
}
public static String getVideoPic(JsonObject json){
return json.getAsJsonObject(data).get(pic).getAsString();
}
}
```
Comments 2 条评论
博主 龙头桑
?∠( ᐛ 」∠)_
博主 Liu
tql