# B 站网页版怎么看 B 站港澳台
# 浏览器安装 TamperMonkey 插件
推荐使用 Windows 自带的 Microsoft Edge。因为不需要翻墙即可访问。
# TamperMonkey 插件安装解除 B 站区域限制脚本
打开 [解除 B 站区域限制](解除 B 站区域限制 (greasyfork.org)) 链接点击安装此脚本
# 配置脚本代理服务器
公共解析服务器 选一个用于解析,建议自行搭建一个用,一个月使用量不高是免费的,还安全不会意外挂掉,速度非常 nice 。
- 打开一个港澳台才能播放的番剧,下滑到评论区,这时网页右下角多了个几个方块
- 点击最下面一个方块打开配置页面
- 复制链接到自定义(首选服务器)处
- 关闭界面,刷新,虽然集数上还是显示受限但可以点击播放了。
配置图
下面这张操作过程 gif 图 11MB 。
# 使用函数计算自行搭建代理服务器
这节就不配动态操作图了,除了脱敏麻烦,前面那张图就用了 11MB 。太耗流量了。
不论阿里云或者腾讯都有函数计算,有免费额度
- 登录或者注册一个阿里云账号
- 打开函授计算
- 创建服务
- 创建完后点击这条记录操作项中的 函数管理 进入函数管理界面。再点击创建函数
- 填写如下信息点击创建
- 创建后会进入如下界面,也可在函数管理列表中某列点击函数详情进入
- 将 index.php 文件内容替换如下。替换完后点击 部署代码 按钮完成部署
<?php | |
use RingCentral\Psr7\Response; | |
/* | |
To enable the initializer feature (https://help.aliyun.com/document_detail/89029.html) | |
please implement the initializer function as below: | |
function initializer($context) { | |
echo 'initializing' . PHP_EOL; | |
} | |
*/ | |
function handler($request, $context): Response | |
{ | |
/* | |
$body = $request->getBody()->getContents(); | |
$queries = $request->getQueryParams(); | |
$method = $request->getMethod(); | |
$headers = $request->getHeaders(); | |
$path = $request->getAttribute('path'); | |
$requestURI = $request->getAttribute('requestURI'); | |
$clientIP = $request->getAttribute('clientIP'); | |
*/ | |
/* Config */ | |
$upstream_pc_url = 'https://api.bilibili.com/pgc/player/web/playurl'; | |
$upstream_app_url = 'https://api.bilibili.com/pgc/player/api/playurl'; | |
$upstream_pc_search_url = 'https://api.bilibili.com/x/web-interface/search/type'; | |
$timeout = 5; // seconds | |
/* Read incoming request */ | |
$request_method = $request->getMethod(); | |
$request_query = stristr($request->getAttribute("requestURI"), '?'); | |
$req_referer = $request->getHeaderLine('referer');; | |
$request_headers = $request->getHeaders(); | |
$request_body = $request->getBody()->getContents(); | |
$request_uri = $request->getAttribute('requestURI'); | |
/* Forward request */ | |
$ch = curl_init(); | |
// 处理请求相关 header | |
$request_headers = array_remove_by_key($request_headers,'Host'); | |
$request_headers = array_remove_by_key($request_headers,'X-Forwarded-For'); | |
// 配置 body 压缩方式 | |
$request_headers = array_remove_by_key($request_headers,'Accept-Encoding'); | |
curl_setopt($ch, CURLOPT_ENCODING, "identity");// 好像 b 站只有 br 压缩 | |
$headers = array(); | |
foreach ($request_headers as $key => $value) { | |
$headers[] = $key . ": " .implode($value); | |
} | |
// 判断请求接口 | |
if(substr_count($request_uri,'/search/type')!=0){ | |
$url = $upstream_pc_search_url . '?' .$request_query; | |
curl_setopt($ch, CURLOPT_REFERER, $req_referer); | |
}elseif (substr_count($request_uri,'playurl')!=0){ | |
// 判断使用的那个 pc 还是 app 接口 | |
if(substr_count($request_query,'platform=android')!=0){ | |
$url = $upstream_app_url . '?' .$request_query; | |
curl_setopt($ch, CURLOPT_USERAGENT, 'Bilibili Freedoooooom/MarkII'); | |
}else{ | |
$url = $upstream_pc_url . '?' .$request_query; | |
curl_setopt($ch, CURLOPT_REFERER, $req_referer); | |
} | |
}else{ | |
$header['Content-Type'] = 'text/plain'; | |
return new Response( | |
502, | |
$header, | |
'Failed to match interface.' | |
); | |
} | |
//curl 配置 | |
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); | |
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $request_method); | |
curl_setopt($ch, CURLOPT_URL, $url); | |
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); | |
curl_setopt($ch, CURLOPT_POSTFIELDS, $request_body); | |
curl_setopt($ch, CURLOPT_HEADER, true); | |
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false); | |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); | |
$response = curl_exec($ch); | |
$header = array(); | |
if ($response === false) { | |
$header['Content-Type'] = 'text/plain'; | |
return new Response( | |
502, | |
$header, | |
'Upstream host did not respond.' | |
); | |
} else { | |
$header_length = curl_getinfo($ch, CURLINFO_HEADER_SIZE); | |
$response_headers = explode("\n", substr($response, 0, $header_length)); | |
$response_body = substr($response, $header_length); | |
// 处理返回相关 header | |
foreach ($response_headers as $n => $response_header) { | |
// 配置返回的 body 压缩方式 | |
if (strpos($response_header, "Content-Encoding") !== false) { | |
$response_headers[$n] = "Content-Encoding: identity\n"; | |
} | |
// 删除 B 站返回的 Content-Length, 防止浏览器只读取 Content-Length 长度的数据,造成 json 不完整 | |
if (strpos($response_header, "Content-Length") !== false) { | |
unset($response_headers[$n]); | |
} | |
// 阿里云函数好像会自己添加 Access-Control-Allow-Credentials 头,删除 b 站返回的 | |
if (strpos($response_header, "Access-Control-Allow-Credentials") !== false) { | |
unset($response_headers[$n]); | |
} | |
} | |
unset($response_header); | |
//response_headers 数组转成 key=>value 形式 | |
foreach ($response_headers as $header_string) { | |
$header_tmp = explode(': ', $header_string, 2); | |
if (count($header_tmp) == 2) { | |
$header[$header_tmp[0]] = trim($header_tmp[1]); | |
} | |
} | |
curl_close($ch); | |
// 这行用于调试请求信息 | |
// return new Response(200, array(), json_encode(array('header' => $header, 'body' => $response_body, 'url' => $url, 'response'=>$response, 'curl_headers'=>$curl_response_headers))); | |
return new Response( | |
200, | |
$header, | |
$response_body | |
); | |
} | |
} | |
/*tool*/ | |
// 某个字符串在另一个字符串第 N 此出现的下标 | |
function str_n_pos($str, $find, $n) | |
{ | |
$pos_val = 0; | |
for ($i = 1; $i <= $n; $i++) { | |
$pos = strpos($str, $find); | |
$str = substr($str, $pos + 1); | |
$pos_val = $pos + $pos_val + 1; | |
} | |
$count = $pos_val - 1; | |
return $count; | |
} | |
function array_remove_by_key($arr, $key) | |
{ | |
if(!array_key_exists($key, $arr)){ | |
return $arr; | |
} | |
$keys = array_keys($arr); | |
$index = array_search($key, $keys); | |
if($index !== FALSE){ | |
array_splice($arr, $index, 1); | |
} | |
return $arr; | |
} |
- 复制地址。
- 在地址后面 +/playurl 字符串就可以使用了。将拼装后字符串放到自定义(首选服务器)处。就可以看了。
看一集用一次,这是阿里云这边的免费额度,可以自己查看。一个月一个人用肯定是足够的。
# 总结
一个人就好,不要常在河边走。