因为有时候需要在博客分享一些站外信息,为了让分享的卡片带有一些基本信息且可以具有实时性收集了一些 API ,写文章的时候插入 [share url=""] [/share] 这个短代码实现自动解析的功能。只需要填入分享的网址不需要其他额外信息,非常方便。
游戏信息
Steam 游戏信息
对于 Steam 游戏的分享,最简单的方式就是用 iframe 标签调用官方提供的小组件:
但由于 Steam 处于半墙状态,这东西的加载速度实在是不敢恭维,甚至在某些地方的网络是直接摆烂加载不出来(例如我家😣),同理 Steam 游戏信息的 API https://store.steampowered.com/api/appdetails 受制于加载速度也是不太建议使用的。
顺带一提,小黑盒的 API 返回的价格和折扣均是小黑盒的,并非是 Steam 的价格和折扣。
解析效果如下:
游戏对应平台链接
要想获取平台游戏对应的商店页面链接,就需要直接使用平台自带的 API 了(一般是平台的搜索 API)。
Steam
Steam 平台游戏的链接只需要使用上面小黑盒 API 返回的数据里面的 steam_appid 拼接在 https://store.steampowered.com/app/ 之后即可。
例如胡闹厨房 2 的链接是 https://store.steampowered.com/app/728880。
Switch
Switch 平台的游戏搜索 API 是 https://search.nintendo.jp/nintendo_soft/search.json,这个 API 这里只有一个必要的参数 q ,代表要搜索的游戏名。因为这里使用的是日区的 API,游戏名一般是英文或者日文,如果直接使用中文名字,例如 q=集合啦!动物森友会 这样是获取不到游戏信息的。
例如异度神剑 3(Xenoblade 3)对应的 API 就是 https://search.nintendo.jp/nintendo_soft/search.json?q=Xenoblade3 。
其中将 API 返回的 id 代入 https://store-jp.nintendo.com/list/software/{id}.html 后就可以得到游戏在 Switch 平台的商店页面链接。这里拼接后的链接是 https://store-jp.nintendo.com/list/software/70010000053335.html。
Ubisoft
Ubisoft 平台的游戏搜索 API 是 https://zh-cn.ubisoft.com/news2/search_name,也是只有一个必要的参数 game_keyword,代表要搜索的游戏名(可以是中文)。
例如要获取游戏 碧海黑帆,API 就是 https://zh-cn.ubisoft.com/news2/search_name?game_keyword=碧海黑帆。
拿到返回数据的 gameabb 拼接在 https://zh-cn.ubisoft.com 后即可得到游戏链接。这里拼接后的链接是 https://zh-cn.ubisoft.com/skull_and_bones。
Blizzard
💩 搜索不准确警告: Blizzard 平台的搜索可能会出现不准确的结果,比如搜索 Overwatch 2 (抑或是 Overwatch® 2)返回的第一个结果会是 Overwatch® 2 – Season Three Premium Battle Pass 。
Blizzard 平台的游戏搜索 API 是 https://tw.shop.battle.net/api/search。其中包含两个必要的参数,第一个参数 q 代表要搜索的游戏名;第二个参数 l 似乎代表搜索游戏名的语言,例如使用英文游戏名搜索为 en-us,使用繁体游戏名搜索为 zh-tw。
拿到返回数据的 destination 拼接在 https://tw.shop.battle.net/zh-tw 后即可得到游戏链接。这里拼接后的链接是 https://tw.shop.battle.net/zh-tw/product/warcraft-iii-reforged。
其他平台
Playstation 、Xbox 、iOS 这几个平台没找到对应的 API ,采用爬虫的方式抓取对应的游戏链接。
至于 Epic,搜索 API 有加密参数,并且采用反爬虫策略;Origin 的话是没有相关的 API,所以都是直接返回小黑盒的游戏链接。
Bilibili 信息
视频
与 Steam 游戏卡片分享一样,Bilibili 也可以通过 iframe 标签分享视频信息:
相比于 Steam 的 API ,Bilibili 的视频信息 API 就简单很多,只有一个必要的代表视频的 BV 号/ AV 号参数 bvid/aid 。Like this: https://api.bilibili.com/x/web-interface/view?bvid=1NT411u7n9 。
解析效果如下:
动态
而 Bilibili 的动态也有一个 API ,也是只有一个必要的代表动态的参数 id ,另外还有一个非必要的以分钟为单位的时区偏移量 timezone_offset ,默认值是 -480 。 Like this: https://api.bilibili.com/x/polymer/web-dynamic/v1/detail?id=706453546894098487 。
顺带两提,动态内容的数组
rich_text_nodes会以表情包作为数组的分割线。例如句子 「这是一条文字捏[给心心]更多的文字」在数组里会变成三个元素:这是一条文字捏、[给心心]、更多的文字。所以完整的动态内容需要历遍数组把元素拼合在一起。
弹幕
弹幕的 API 只有一个必要的参数 oid ,也就是视频的 cid ,由上面的视频信息 API 获取。我们可以这样获取 cid 是 834814323 的视频弹幕: https://api.bilibili.com/x/v1/dm/list.so?oid=834814323。API 返回的是一个 XML 格式的数据。
这里有两个需要注意的点:🔔 视频的
cid与视频的 AV/BV 号并不是同一个东西,比如BV 号是 1NT411u7n9 的视频,对应的cid是 834814323。🔔 返回的数据经过 deflate 压缩,需要进行解压,比如 PHP 使用gzinflate()函数等。
这里不介绍如何获取 XML 数据,来关注我们需要的数据:
<maxlimit> 标签包裹的是视频最大的弹幕数量。
<state> 标签包裹的是视频弹幕是否开放,0 表示可以正常发弹幕,1 表示关闭弹幕发送功能。
<d p="114.63900,1,25,16777215,1673445087,0,xxxxxxxx,yyyyyyyyyyyyyyyyyyy,10">压力终于给到了二创</d> 标签包裹的是视频每一条弹幕的具体信息,具体的信息可以在这里看到:bilibili-API-collect 属性 p 。据此可以得出这条内容为压力终于给到了二创的弹幕是在视频第 114.639 秒出现,是一条普通的从右向左滚动的弹幕,字号为标准,字体颜色为白色,在 2023 年 1 月 11 日 21 点 51 分 27 秒发送(时间戳为 1673445087),弹幕池类型是普通弹幕,发送者 mid 的 HASH 为一个 8 位数字字母组合 xxxxxxxx,弹幕 dmid 为一个 19 位纯数字 yyyyyyyyyyyyyyyyyyy,当弹幕屏蔽等级大于 10 时可以屏蔽该弹幕。
Github 仓库信息
同样 Github 仓库信息的 API 也很简单,只需要 https://api.github.com/repos/ 后面接上 {用户名}/{仓库名} 即可。Like this: https://api.github.com/repos/SocialSisterYi/bilibili-API-collect 。
解析效果如下:
博客文章/页面信息
因为 Typecho 升级到了最新的 1.2 版本后原来输出文章信息的插件用不了,所以只能自己上手加一点功能了。
在 Function.php 中加上:
// 获取文章信息
public static function getCustom($uid){
$type = is_numeric($uid) ? 'post' : 'page';
$cidType = $type === "post" ? 'cid' : 'slug';
$f = Typecho_Widget::widget('Widget_Archive@'.$uid,'pageSize=1&type='.$type, $cidType.'='.$uid);
$archive_info = ['title'=> $f->title ,'desc' => $f->description ,'category' => $f->category ,'time' => date('Y.m.d', $f->created)];
return $archive_info;
}然后新建一个独立页面模板,通过获取网址的参数来调用 getCustom() 。
/**
* 文章信息
* @package custom
*/
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
function filter($uid){
preg_match_all("/[a-zA-Z0-9]/",$uid,$a);
return join('',$a[0]);
}
if(!empty(filter($_SERVER["QUERY_STRING"]))){
foreach (explode('&', filter($_SERVER["QUERY_STRING"])) as $value) {
if (strpos($value,'uid')!== false) $uid = explode('=', $value)[1];
}
$returnJson=['state'=>1,'data'=> Func::getCustom($uid)];
echo json_encode($returnJson, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT);
}else{
$returnJson=['state'=>-2,'message'=>"没有有效的 UID 输入"];
echo json_encode($returnJson, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT);
}最后后台增加一个独立页面,模板选文章信息即可。只有一个对应文章 cid 或者页面 slug 的参数 uid ,文章调用如下:https://vinking.top/getInfo.html?uid=67 ,独立页面调用如下:https://vinking.top/getInfo.html?uid=about 。
文章解析效果如下:
页面解析效果如下:
目前就使用了这几个最常用的 API ,更多的站外解析就等到有需要的时候再写吧🙈。
普通网址解析
最近写了个 API 可以解析普通页面,不过有些网址会出现解析不成功的情况,先凑合着用吧...
2022.12.3: 经过优化之后已经大幅提高对不同网站的兼容性。
Title 和 Description 都解析成功
网址 Title 解析失败
以原神官网为例,由下图可以看到,页面的 title 是由名为 config.54af175465c7448a0fa377d065a2d6da.js 的 js 文件动态加载的,所以在页面还没有完全加载完(最原始的静态文件)的状态下,是没有 <title> 标签的,从而导致获取不了页面的标题。但是页面是有关键词 keywords 的,所以当获取不到 <title> 标签时,会匹配 keywords 的第一个值用来作为解析后的标题(一个次要原因是 keywords 的第一个值一般都是页面的标题,另一个原因是除了这个实在找不到什么东西可以代表网站标题的了)。


2023年10月12日 02:46
hi,哔哩哔哩弹幕下面 bilibili-API-collect 属性 p 的链接失效了,可以更换一下吗
2023年05月08日 16:45
这页竟然更新了!
大佬可以研究一下豆瓣的书影音,感觉放文章里也很不戳OωO
2023年03月07日 01:40
如果服务器在国外就没必要用代理才能获取到网页信息了吧
2023年03月07日 01:43
是的
2023年01月03日 11:30
您好,开往的地址已更换为 https://www.travellings.cn/go.html ,相关LOGO图片新地址如下:
gif动图:https://www.travellings.cn/assets/logo.gif
svg:https://www.travellings.cn/assets/logo.svg
请您及时更换相关地址,谢谢配合。
2022年12月17日 14:22
跨域是怎么解决的
2022年12月17日 14:20
b站动态的接口用不了了
2022年12月17日 14:38
我这边试了一下还是可以正常返回数据的
Ps.直接浏览器打开是会报错的,得在后端用 PHP 拿数据
2022年10月21日 14:09
这个页面太丰富了 好看
2022年09月25日 21:11
不错不错,挺有用的|´・ω・)ノ
2022年09月19日 19:03
哇!!!!!大佬每次更新都是干货满满٩(ˊᗜˋ*)و
2022年09月19日 20:36
ヾ(≧∇≦*)ゝ
2022年09月29日 09:44
小黑盒的api是怎么找的,我想看看如何读取ns获其他平台的游戏信息
2022年09月29日 10:03
我晚上帮你找找看有没有,我这边用的是他的网页版的api