最近看见这边静态博客浏览量又变高了,感觉需要稍微交代一下。。。
实际上一年以前我就已经重新拥抱Typecho,将博客的内容全部转移到了另一个地方=>CKylin.Site / CKylin.Blog 但是一直没有说,因为不确定这个博客的稳定性,也不知道能不能一直用下来。
不过在这一年里,我为博客优化了很多,并用上了cloudflare CDN,现在那个博客的速度甚至可能比这个静态博客还快(某些情况下是这样),我也就把那边当作自己的主博客了。
这两天整理友链,才看到这边居然还有浏览量增加…所以特别说明一下,我现在已经转移了~
欢迎之前来的朋友们观光哈~
]]>( )
i++
/ ++a
i--
/ --a
*
/
%
+
-
>>
<<
>>>
&
^
|
&&
||
xx ? xx : xx
=
_
、$
。byte
=> 1 byteshort
=> 2 byteint
=> 4 byte 默认整数型long
=> 8 byteL
float
=> 4 bytef
double
=> 8 byte 默认浮点型d
char
=> 2 byteboolean
=> 1 byte暂时无图,过两天补
在一切配置开始之前,首先需要安装几个软件。
VS Code的安装没有什么好说的,MinGW安装的时候需要选择加入环境变量。如果没有的话,需要在下一步配置的时候进行添加。
安装之后运行MinGW你会看到一个英文界面,在右侧勾选所需要的编译器,如果你不知道勾选哪个就全都勾上,点击复选框然后选择“Mark for installation”,最后左上角选择“Installation”,点击“Apply Changes”,接下来会根据网速等5~20分钟不等的时间,之后就算是安装完成了。
需要注意的是,如果你在系统CMD输入gcc提示没有这个命令的话,那么你需要将
<MinGW安装目录>/bin
加入你的系统环境变量中,然后重新打开CMD确认gcc命令。
打开之后左边选择“Extensions”图标(或者按Ctrl+Shift+X
),搜索框搜索chinese
,点击第一项右侧的“Install”按钮,然后在右下角点击“Restart”重启编辑器,这样中文就算是安装完成了。
搜索c
,安装C/C++
扩展,
在课程的前几节课都是单个.c
文件运行,这样的话配置起来相对简单。
新建一个.c
文件并用VS Code打开,选择顶部终端>配置任务>通过模板>Others
,然后在打开的Tasks.json中清空并粘贴下面的内容:
1 | { |
自行替换上面cwd
后面的目录为你刚刚设置环境变量的目录,command
为你的GCC可执行文件路径,注意路径杠号的转义。
接着选择调试>添加配置
,清空launch.json并粘贴下面的内容:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29{
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceRoot}\\${fileBasenameNoExtension}.exe",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": true,
"MIMode": "gdb",
"miDebuggerPath": "E:\\mingw\\bin\\gdb.exe",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
"preLaunchTask": "gcc.exe build active file"
}
]
}
老规矩,自行替换路径,注意转义。
这时候你可以试着开个新的C文件然后编译一下,新建.c文件输入:1
2
3
4
5
6
int main(){
printf("Hello World");
system("pause");
return 0;
}
然后点击F5
,选择刚刚的配置,看看是不是如你所愿的运行了。
其实DevC++就是使用CMake来编译工程的,我们如果需要在VSCode中运行多个C文件的工程也需要CMake的支持。
在刚刚单文件的基础上,我们需要增加安装CMake软件。
Windows win64-x64 Installer: Installer tool has changed. Uninstall CMake 3.4 or lower first!
的一项然后安装。安装好CMake后其实我们是不用再配置这个工具了,剩下的工作都是在VSCode中完成的了。
在VSCode中并不原生支持CMake,我们需要搜索并安装下面几个插件。
安装并激活插件后,需要修改你的全局配置。按下Ctrl+Shift+P
,输入settings
,选择首选项:打开默认设置(JSON)
,在最下面粘贴几项设置:
1 | "cmake.cmakePath": "E:\\CMake\\bin\\cmake.exe", |
和上面一样,修改所有的路径为你实际的安装地址。第一个是CMake的可执行程序,后面的是MinGW的根目录,最后一个请不要改动。
接着,如果你有C语言的项目的话你就可以按文件夹打开了,以前的Makefile会自动读取,如果没有的话右下角会提示你进行创建,你需要输入项目名字(用于生成exe的文件名)并选择类型为executable
可执行程序,接着CMake工具插件会自动配置并生成Makefile。
这一步之后,你还需要做一个配置,你对每一个项目第一次都需要做的配置,在项目文件夹中打开刚刚生成的CMakeLists.txt
文件,修改add_executable...
(大概是第7行),括号格式:
1 | add_executable(项目名字 所有.c文件,空格分隔) |
例如我有main.c
、timer.c
,项目叫做alarm
,那么我的这一行应该是:1
add_executable(alarm main.c timer.c)
然后,你就配置完成了!
点击左侧栏最下面新增的三角形CMake图标,选择右侧栏右上角的锤子按钮(Build),如果你的代码没有问题,那么在你项目目录的build
子目录下会生成一个以你项目名字,命名的exe文件,无论是调试还是运行接下来就看你了。
今天一大早帮朋友下载一个油管上的视频。我想起来我之前旧电脑上有用过一个叫 YouTube Downloader 的软件,而我恰好留了一个安装包。
于是我就开始用这个安装包安装一下,毕竟以前一直用这个软件没出过问题。
安装的时候我发现这不能算是安装包,只能算是个下载器,联网下载了个22MB的安装程序,我没管。
火绒这时候拦截了个病毒,但是类别是代码混淆器。我想着这没准是误拦什么的,毕竟以前也没出过问题,就放行了。
软件安装完界面和功能还是和以前一样,于是我像以前一样,粘贴URL,下载,完成。这时候,开始出现问题了。
整个屏幕上面大概五分之一的空间被霸占,上面是一个浏览器的头部,左边甚至还能选择浏览器。显示是一个Chormium内核的浏览器,叫WebDiscover。
如果要是真的是个简单的浏览器也就算了,问题是它占着我五分之一的屏幕,连桌面图标都推下来了,任何的窗口都不能覆盖其上也不会被遮挡,而是就像任务栏一样被完全隔离。我去任务管理器,发现这货居然杀了进程还会自启。无奈,我找到了这个程序所在目录,用火绒直接文件粉碎了,顺便把万恶之源,那个油管下载器卸载了。重启了一遍电脑,看上去似乎就恢复了。
我以为事情就到此为止了。但是当我回来把电脑从睡眠状态中唤醒的时候,开始出现了新的问题:
命令出错是我后来操作别的时候发现的,wmic是我想到的和WMI最有关的指令。随后还出现了一些驱动上的问题:
重启可以临时解决一些问题,但是WMI报错一直存在,而且很多问题很快又出现了。我怀疑是系统文件损坏了。
百度搜索无果,去谷歌查询,大部分都是XP遇到的,最终找到一个网页:https://www.wandouip.com/t5i312564/
他们提供了一个方法:
先停掉winmgmt服务,然后重命名或者删除C:\Windows\System32\wbem\Repository文件夹,最后再启动服务,执行
1 | winmgmt /resetRepository |
最后重启电脑。最终问题解决,没有再出现任何WMI报错,而且命令也已经恢复正常。
]]>这个博客之前打理的比较少,所以之前七牛说是要停用测试域名的时候我没处理,以至于现在博客上的图片全部死掉了。最近刚好得空,所以来看看有没有七牛云的替代品。
不过,似乎上来就出了个问题。我没有真正备过案的域名,以至于我不可以用网页来下载我以前的那些图片了。
虽然说这里只是不能下载外链,但是确实我选择文件之后点击下载按钮没有任何反应了。
而在百度以后,我得知,可以用命令行工具来下载自己的Bucket中的文件。我最先看的是七牛云测试域名失效导致图片外链失效的解决办法 - chensonglu的博客 - CSDN博客这篇文档,使用qrsctl.exe
来下载。
确实,它能访问到我的Bucket,但是却出了个奇怪的问题:无法列出文件:
marker下面什么都没有。不过,虽然没有列出来,但是我强行下载还是能下载下来的。
(灵魂打码最为致命。)
嗯,文件算是下下来了,那七牛空间对我就没什么意义了,里面的文件我就全都删掉了。所以接下来的问题是,我该把文件存在哪呢?
我先是试了试云之幻的Picture Share,但是上传文件总是半途出错。最后,我想起来,我貌似还有个腾讯云的对象存储可以用来着。于是,现在博客的所有图片就全部寄存在腾讯云的免费对象存储里了。
先试一段时间,没问题就先用腾讯的了。
]]>20
,松手刹猛起步。20
,可保持状态并松手刹起步。多图预警
皮皮虾预警
本文主要介绍Chrome浏览器方面的操作。其他浏览器(如火狐)也可以起到相同效果,操作细节略有不同,建议百度。另外本篇文章不讲解过多的js,有需要请看另一篇文章(常用JS)。本文对于没有HTML基础或者代码恐惧症以及密集恐惧症患者可能会有不适,且本人文笔并不好,所以各位多包涵着。
chrome浏览器或者chrome浏览器相同内核的一些国产浏览器都有一个功能,这个功能在右键菜单中叫做“检查”。为了调用这个功能,我们需要先有一个支持此功能的浏览器。
在继续看如何下载浏览器之前,请尝试按下F12
或者Ctrl
+Shift
+i
按键查看是否有个如下图的窗口蹦出来了,有的话请跳过此章节。
看到这里的时候你肯定是没成功。不用着急,问题不大。你可以直接去百度里搜索”chrome”,然后点击普通下载。没有看到普通下载按钮的朋友,可以直接去Chrome 官网下载。下载后双击打开一个exe文件,然后稍等片刻,浏览器便会自动打开全程十分干净无捆绑,教程结束。
开玩笑,工具刚刚装好。
我没有仔细了解过那个窗口到底官方怎么叫,姑且就叫它开发人员窗口。这个窗口具备很多的功能,而对于本文来讲,我们只介绍其中的几个功能(其他的功能如果你用得上,那自然会知道对吧~)。
打开方法很简单,如果你在之前下载那一节按照我说的做了,那么你现在屏幕上这个窗口应该还在(没在就再点一次)。或者,右键点检查:
现在,如最上面那幅图一样的窗口应该出来了吧?我再放一次图(我真的没在水字数):
首先顶上那一行(“Elements/Console/Sources…”)是一些功能,暂时用得上前两个。第二个是js命令窗口。那第一个是什么?往下看~
第一个ELements是展示页面元素的,也是咱们的主战场。随便打开个网页再打开这个窗口,鼠标划过这些代码,你的网页上会自动用方块显示出对应的元素:
很神奇,对吧?
还有更神奇的。注意开发窗格左上角。
这是两个按钮。左侧第一个按钮,戳一下可以问神奇海螺很多事情。
开玩笑。那个按钮按一下会变成蓝色。而且这个时候鼠标划过页面,自动高亮了鼠标指向的整个元素。是不是很棒?
好了,现在你可以按下鼠标左键了。这样你选择的元素就会在右侧高亮并且关闭这个鼠标选择模式。
视线回到左侧。每当悬停选择一个元素的时候,除了为元素上色,上面其实还有一个浮动窗口:
上面有丰富多彩的英文字对吧?好了,现在简单介绍一下这几个英文字。
还是这张图。
首先看图上有的。
紫色的是TagName,标签名。标签是什么?比如你看本文,<p>这句话</p>
中的<p></p>
就是标签,p
就是标签名。标签一般都成对出现,常见标签有:div p h1 h2 h3 b header nav等等。(具体是做什么用的?这个不属于本文涉猎范围内,因为如果不会代码,这东西解释起来怕是要头疼的。)。上图tagname就是h2。
接下来就是蓝色的class。一个元素可能有多个class也有可能没有,每个class在显示的时候都会在前面加“.
“点号来表示。class用人话来说就是设置一个规则,大家都来遵守。在一个css样式表里设定了之后,指定调用这个class的元素都会遵从那一套规则<p class="papapa">这句话</p>
中的papapa
就是class,显示出来就是.papapa
。上图class是post-title
。
最后一项一般咱们用不到,前端的朋友会用得到,告诉你元素多大。
Emmmm好像少了什么…
(Pia的一拍脑袋)对了!…没有说ID对吧?
(揉揉脑袋)刚刚那个元素没有ID,看我给它加一个ID:
这次多了一个黄色的字,#hello
,这就是元素ID。元素只能有一个ID,而且在整个网页里面唯一,一般会在前面加上“#
“来显示。<p id="rua">这句话</p>
中的rua
就是这个元素的ID。id就像是你的身份证号,因为是唯一的,所以通过身份证号可以找到你这个人。上图里的ID就是hello
。
一个元素是可以同时存在ID和CLASS的。如:<p id="rua" class="papapa">这句话</p>
,两个属性没有先后之分。但是如果你有单独设置样式,那就是后来者居上,覆盖前者的样式了。
很多网站的电脑视图和手机视图是不一样的,应用的规则也不太一样。为了能让我们在Chrome电脑版调试手机页面,我们还需要一点准备。
还记得那两个按钮吗?
刚刚说了第一个按钮,现在用的是第二个按钮。点一下,视图会变成这样:
这显然不是手机页面。不过看到页面顶上的Responsive了嘛?戳一下:
这次就有手机了。我一般习惯用Galaxy S5来调试。点一下就好了:
这个设置点一次就可以了,以后只要打开开发窗口就会自动变成这样。当然关掉的话再点一下刚刚两个按钮的第二个就好了。
在酷安帮别人鼓捣FA的网页的时候最常遇到的就是去除留白和去掉元素。去除留白其实是相对简单的,毕竟去除元素多一半删广告,某毒的广告,弄过的都懂,还有一些页面用js动态加固广告。
还是这张图
你看,“常用JS”上下各有一行黄色,那个就是边距中的外边距。你选中一个元素,并且在元素右侧或者下侧的样式设定中,滚动到最下面,就能看到有关边距的设定图:
将颜色和这个进行比对,外边距就很容易知道是margin
而且数值是20(px)。
上图有几种边距,最外侧position是位置,代表与网页的绝对位置,一般是浮动元素用的。继续是margin,外边距,一般是元素外侧的空白,大部分的去除留白请求也是这个。再往里是border,这个算是边框。再往里是padding,内边距,一般是设置子元素距离元素边的距离。中心是元素大小。这些东西简单点理解,就是:margin是你外面衣服多厚,padding就是你有多少肉,border的话就是你的皮…皮皮虾!
以下网页来自酷狗。m.kugou.com,本文仅仅拿来做演示,侵删。
现在是正题了。切换到手机视图。打开酷狗。
然后现在已经去掉去掉了顶栏(去除方法参见隔壁文章”常用JS”,顶栏id#topFixed),可是我们看到上面有一大片空白。这肯定不是我们想要的。现在根据上文说的,首先用鼠标悬停在空白上,看看到底谁的额头这么大:
可以看到对应元素是<div class="bd js-bd-box" id="bd">...</div>
,点击左键确定元素,然后查看右侧样式:
看到了嘛?特别明显,在bd类下有个padding-top。刚刚说过,padding是内边距,而padding-top的意思是顶部边距。我们把鼠标悬停在这一项上,会在前面出现复选框。反选padding-top一项的复选框,相当于取消这一样式,现在查看效果:
可以看到,这次效果就对了。也就是说,我们只需要去除这个padding-top即可。将复选框勾选回来。
我们接下来使用JS来针对性的去除padding-top效果。这里只简单讲下,具体的用法看隔壁常用JS文章。
我们首先看到这个元素拥有一个ID叫做bd,那么选取元素就很简单。1
document.getElementById("bd")
这半句js便可以选取这个元素。这个元素下有一个专门放各种样式的object,就是style。在style下,所有的css样式使用驼峰命名法在这里列出。根据驼峰命名法,padding-top就是paddingTop。于是,我们可以直接给这个样式赋值。直接给0是清除最简单的方法。1
document.getElementById("bd").style.paddingTop=0;
这句js构造好了,切换到Console标签,输入,回车。可以看到效果已经完美了。这句js就可以放进FusionApp里了。
这篇简单教学就到这里了。文笔不好多多包涵,而且之前也很少写教程相关的东西,如果有哪里不清楚,欢迎在酷安找我@Cansll蚕食。
]]>总结的是原生JS,通用于各个网站
以下语句从头开始或从上一个语句的”;”后开始,index值为整数值。
1 | document.getElementById("元素ID") |
1 | document.getElementsByClassName("class名")[index] |
1 | document.getElementsByTagName("标签名")[index] |
标签名:直接写标签名
class名:.class名
ID:#id
使用时可以三项结合。另外特殊属性可以在上述元素后加[属性名]或[属性名=属性值]方法选择
兼容css语法如:空格” “,”>”,逗号”,”,具体含义请百度
CSS选择器参考网址: CSS选择器参考手册>>
1 | document.querySelector("选择器") |
1 | document.querySelectorAll("选择器") |
以下字符需要拼接在上面选择器的后面组成js语句。
1 | .childNodes[index] |
1 | .firstChild |
1 | .lastChild |
1 | .firstElementChild |
1 | .lastElementChild |
1 | .nextSibling |
1 | .previousSibling |
1 | .nextElementSibling |
1 | .previousElementSibling |
以下字符需要写在上面选择字符的后面拼合js语句。
此类操作会修改dom,请不要再循环中直接使用。
1 | .remove(); |
偶尔有些时候删除特殊的类名就可以让多余的设置消失。
1 | .className |
1 | .classList |
1 | .className=""; |
1 | .className="指定class,空格分割"; |
1 | .classList.remove("类名"); |
1 | .classList.add("类名"); |
此类操作可以在属性值后加”!important”提高属性值的优先级。
1 | .style.display="none"; |
1 | .style.opacity="0"; |
此步骤需要分两步。下面两行每行都需要组合一次选择元素的语句。1
2.style.position="fixed";
.style.left="-1000px";
1 | .style.padding="0"; |
但是大部分情况下只需要调整一侧的留白:
上:1
.style.paddingTop="0";
下:1
.style.paddingBottom="0";
左1
.style.paddingLeft="0";
右:1
.style.paddingRight="0";
1 | .style.margin="0"; |
但是大部分情况下只需要调整一侧的留白:
上:1
.style.marginTop="0";
下:1
.style.marginBottom="0";
左:1
.style.marginLeft="0";
右:1
.style.marginRight="0";
删除一个id为abc
的元素1
document.getElementById("abc").remove();
隐藏一个属性dpr
为1
的ul
元素1
document.querySelector("ul[dpr=1]").style.display="none";
下载地址:bilibiliSmartSearch_1.2.zip
安装方法:
bilibiliSmartSearch_1.2.zip
,解压出文件 bilibiliSmartSearch_1.2.crx
chrome://extensions
页面bilibiliSmartSearch_1.2.crx
拖到页面中,安装。下载地址:bilibiliSmartSearch_1.0.zip
安装方法:
bilibiliSmartSearch_1.0.zip
,解压出文件 bilibiliSmartSearch_1.0.crx
chrome://extensions
页面bilibiliSmartSearch_1.0.crx
拖到页面中,安装。1 | value = prompt('哔哩哔哩智能搜索\n\n输入你想搜索或跳转的位置:', '', 'AV号/ANIME号/EP号/UID号/视频关键词'); |
基本功能就是判断是否是AV号(视频)、EP号(动漫剧集)、ANIME号(番剧页面)、UID号(用户页面)、LIVE号(直播间),如果是直接跳转相关页面,不是的话跳入b站搜索页面。如果时以上特殊号码,请确保前缀是相关的字母(如直播间号码前缀加live)。
哔哩哔哩智能搜索(拖动到书签栏,点击书签栏中的此链接,输入AV号/ANIME号/EP号/UID号/视频关键词直达)
这个功能抽空合并到ViaIndex中。我注意到ViaIndex的新闻源挂了,酷狗音乐API也只能搜索不能播放了,抽空还得弄一下。新闻可能就移除了,音乐搜索API直接转成音乐搜索快捷方式。
]]>当设置参数“titlemode”不为“TIPS”时标题切换到“基本时间”模式,默认为问候语模式。code
将x0popup更换为原作者的新作品Windowise。code
使用一言网的API添加了一言卡片。可以自行控制开启和关闭以及分类。code
现在可以动态创建新的卡片而不需要在主页创建静态的卡片占位了。code
版本号进1.6
现在ViaIndex会自动判断是开发测试模式还是发布模式
会自动设定当前页面变量。后面会有一些显示只在开发测试模式中。code
使用大谷哥API添加了新闻卡片,可以点开查看简短的介绍,可选择分类。code
将主页的页脚中作者博客更新为现在的地址。code
设置卡片仍在规划阶段,一个小的DEMO已经添加到了ViaIndex中,但仍然有BUG。code
My own via index
一个给自己胡乱写的手机浏览器主页
叫ViaIndex原因是一开始是为Via浏览器做的自用开始页面
仅支持竖屏手机。
同学在实际使用的时候由于我文件名写死在程序内所以需要每次下载完文件后手动修改文件名。而且由于我班同学注册喜马拉雅的用户名并不一定是真名注册(emmm我也不是…真名注册的心也太大了…)所以交作业的时候还得知道每个人的用户名是什么,改成对应人名。好的,需求来了:
(大概以上两点实现以后基本上就不用反复修改文件名了)
想法是这样的:新建一个配置文件和字典文件,用简单的key=value
格式。
配置文件可以放文件名格式,字典文件放每个同学的名字对应关系。
放上两个文件创建和读取的方法:
1 | function readDict(){ |
因为懒么,所以把首次创建和读取写在一起,虽然这样会导致每次下载都会读取一遍,但是因为每个链接都是单次输入的,因为读取两个小文件导致的延误不会太高,所以一次读取的事情放到下次更新。
先判断文件是否存在,不存在就创建并写入默认内容。如果是配置文件,则顺便输出一下相关的变量。
(autoConvert参数是一个正在实现的功能,见下文)
这里使用file()
函数把所有文件按行读取,然后逐行判断。如果是空行就跳过,然后分割=
,等号前面是key
,等号后面是value
,然后把结果直接放进配置数组中。这里暂时还是缺少一些安全判断的。
由于按照行读取会把行尾换行符一并读上,所以分割之前要把换行符替换掉。
然后就是字典匹配人名,一个很简单的函数:
1 | function getName($name){ |
首先读取字典,然后判断是否有指定的名字,然后直接读取值返回。
之后是获取文件名:
1 | function getFileName($r){ |
这里将之前$r
也就是获取到的api数据传入以便获得所有需要的数据。我将所有定义的变量对应了值放在一个数组中,读取配置。如果配置中有设置文件名,那么就使用设定的文件名,否则使用预设的文件名。然后再把文件名中的所用变量替换成对应值。注意这里依然缺少两个安全判断,一个是文件名格式,一个是变量的格式,如果格式不正确也是不能正确创建文件的,这个我以后更新。因为之前看到一片文章说strtr
替换速度比str_replace
快4倍,所以这里用strtr。(其实还是懒,虽然差不了几个字母…)。最后拼上.m4a
后缀。
最后插入到主线程。打开程序时自动创建文件,就先读取一次所有配置就好了:1
2
3
4
5
6
7
8
9......
output($copyright."\n\n".$logo);
//init config
output();
readConfig();
readDict();
//UI MODE
output("\n\n[*] 欢迎使用喜马拉雅FM音频下载工具!");
......
然后是获取文件名这里直接换掉:1
2
3
4
5
6......
// $filename = "$user-$title-$album-$time-$ran.m4a";
$filename = getFileName($r);
raw_output(t("\n\n[*] 准备下载...")."($filename)");
$path = dirname(__FILE__) . DIRECTORY_SEPARATOR . "audios" . DIRECTORY_SEPARATOR;
......
我顺便把后面的路径中的分隔符换了一下。
关于之间说的MP3和M4A格式转换的问题,有两个方案。一个是放一个ffmpeg什么的调用转换,使用exec()
命令调用就行。另一个是我无意中发现的另一个api,从喜马拉雅后台揪出来的api:
1 | http://www.ximalaya.com/center/voice/download?trackId= |
这条API会下载原始大小的MP3(说起来我上传的是wav来着)虽然还是转码过的但是已经是mp3了,大小很可观。而且…
emmmmm…再看看吧…
本次更新 commit:
添加功能 · Cansll/XiMaLaYa-Get@ab5c14b
2017年9月18日
CKylinMC
一键复制网页信息(拖动到书签栏,在需要分享页面点击即可复制内容)
蓝墨云班课 PDF 下载(拖动到书签栏,打开资源中的PDF,然后点击书签栏中的此链接)
B站快速访问(拖动到书签栏,点击书签栏中的此链接,输入av号跳转)
哔哩哔哩智能搜索(拖动到书签栏,点击书签栏中的此链接,输入AV号/ANIME号/EP号/UID号/视频关键词直达)
哔哩哔哩智能搜索已经升级为Chrome扩展,书签版本不再维护更新!
特殊跳转链接(拖动到书签栏,点击书签栏中的此链接,输入特殊协议链接跳转)
此书签用于测试。比如一些特殊协议的app链接”ms-settings”之类的。
获取AV号(拖动到书签栏,点击书签栏中的此链接,即可获取av号)
获取AV号格式链接(拖动到书签栏,点击书签栏中的此链接,即可获取av号格式链接)
链接甚至可以获取番剧的视频AV号!
获取B站带时间视频连接(拖动到书签栏,点击书签栏中的此链接,输入特殊协议链接跳转)
(或复制:1
javascript:if(location.href.indexOf("https://www.bilibili.com/video/av")===0){var a=document.querySelector(".bilibili-player-video-time-now").innerText.split(":");prompt("URL:",location.origin+location.pathname+"?t="+(a[0]*60+parseInt(a[1])));}else alert("只支持Bilibili视频");
到一个新的书签的网址栏即可。)
]]>获得打开链接自动跳转到对应时间并开始播放的分享地址
由于我目前掌握的相对好一点的就是JS和PHP,为了后面能够方便设计界面我优先选择的是JS。网页方面用的就是我之前自己写的KyMD作为样式,虽然简陋但是够用。网页很简单,就加了一个输入框,一个按钮还有一个文本域用于存放结果。
为了能够确认输入的是我需要的音频页面链接,我首先对传入的URL进行判断。1
2
3
4
5
6
7
8
9
10function checkIsTrackUrl(url){
if(!url) return false;
var a = document.createElement("a");
a.href = url;
if(!a.hostname=="www.ximalaya.com") return false;
if(a.pathname.indexOf("/sound/")===-1) return false;
var start = a.pathname.indexOf("/sound/")+7;
var track = a.pathname.slice(start).replace(/\//,"");
return track;
}
如果为空直接返回false。
喜马拉雅音频页面的链接结构大概是 http://www.ximalaya.com/XXXXXXXX/sound/XXXXXXXX/
最后那一串XXXXXXXX便是我需要的音频ID。
然后创建一个a元素,把url穿进去,这样就可以直接获取到url的各部分结构了。先查域名是不是喜马拉雅的域名,如果不是返回false,然后判断路径中是否存在 /sound/
这段字符,如果出现则代表是喜马拉雅音频的链接,否则其他的专辑页面啊什么的全都返回false。
最后,取出 /sound
后面的字符。我先获取到 /sound/
的字符位置,然后+7跳过 /sound/
,这样就能获取到最后的几位数字了。为了确保链接最后不会多出一个路径符号,我这里再次的替换一次,确保取出来的只是音频ID不是其他的什么东西。
之后就可以进入另一个函数了1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33function getTrackDownUrl(url){
var track = checkIsTrackUrl(url);
if(track===false){
dialog.setTitle("Track 地址无效").setContent("请输入正确的Track地址! (地址格式验证不通过,请确保地址全部小写且合法)").show();
return false;
}
console.debug("Track ID Get: "+track);
var apiPath = "http://www.ximalaya.com/tracks/"+track+".json";
$.getJSON(apiPath,function (r,s){
if(s!==200){
dialog.setTitle("获取信息时出现错误").setContent("获取信息时出现错误: HTTP "+s+" ERROR").show();
return;
}
var id = r.id,
download = r.play_path_64,
duration = r.duration,
title = r.title,
user = r.nickname,
album = r.album_title,
info = r.intro,
time = r.time_until_now;
var audiolength = duration / 60;
dialog.setTitle("来自"+user+"的音频").setContent(
"<b>音频:</b> "+title +"<br>"+
"<b>长度:</b> "+audiolength+"<br>"+
"<b>专辑:</b> "+album+"<br>"+
"<b>上传时间:</b> "+time+"<br>"+
"<b>介绍:</b> "+info+"<br>"+
"<b>下载地址:</b> "+download+"<br>"
).show();
document.getElementById("result").value = download;
});
}
先判断 checkIsTrackUrl
函数的返回,若是false则url没通过检查,直接弹出错误然后返回。这里 dialog
是我二次封装的一个 dialog-polyfill
对话框。这些代码都在我的 KyMD
中。
之后拼接api地址,使用jquery的获取json方式获得结果。
如上方法在实际测试时,发现出现了跨站的问题,所以就只能舍弃用户界面,换成php语言重写成命令行程序。
我直接使用了Minecraft游戏服务器的 PHP7 运行环境,无需配置就可以使用。
由于是命令行程序,所以我先写了3个用于命令行输入输出的函数:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22function output($out)
{
$out = t($out);
fwrite(STDOUT, "\n$out");
}
function raw_output($out)
{
// $out = t($out);
fwrite(STDOUT, "\n$out");
}
function ask($out)
{
output($out);
return trim(fgets(STDIN));
}
function t($t)
{
return iconv("UTF-8","GBK",$t);
}
由于我的目标是windows系统,所以这里所有的中文字符均需要转码。output函数会在每一次输出前转码,但是如果我需要输出已经转好的文字,则不能使用output,于是我单独写了一个raw_output用于直接输出。ask函数很简单,就是先输出一段字,然后等待输入。1
2
3
4
5
6
7
8
9
10
11
12
13while (true) {
output("\n\n>[ 新的下载任务 ]----------------------\n");
$res = ask("[?] 输入一个音频链接: ");
if (empty($res)) {
output("[!] 请输入一个链接!!");
continue;
}
if ($res == "exit") {
output("\n[!] 退出.");
break;
}
......
我把所有主程序代码放在了一个循环里,这样可以在执行完一次下载后立刻准备好下一次下载。
我首先输出“请输入一个音频链接”,提示输入一个完整音频链接,然后判断用户输入是否为空,空则直接提示“输入一个链接”然后继续循环,开始下一次接受输入。如果用户输入的是 exit
,则直接跳出循环。循环外没有单独的代码,所以跳出循环意味着结束程序。1
2
3
4
5
6
7......
$urlinfos = parse_url($res);
$track = getTrack($urlinfos);
if ($track === false) continue;
$track = str_replace("/", "", $track);
output("\n[+] Track ID: $track \n[*] 正在获取信息...");
......
这里调用了一下 parse_url
代替js中的创建a标间方式来解析URL。解析的结果交给函数处理,和js版本一样,如果解析成功返回音频ID,否则返回false:
1 | function getTrack($info) |
在处理音频ID时同样是多替换一次路径符号。1
2
3
4
5
6
7
8
9 ......
$api = "http://www.ximalaya.com/tracks/$track.json";
// $httpinfo;
// $res = http_get($api, $httpinfo);
// if ($httpinfo['response_code'] != "200") {
// output("HTTP " . $httpinfo['response_code'] . " ERROR. JSON data get failed.");
// continue;
// }
......
拼接api。本想使用http_get函数直接完成获取操作,但是发现http_get要求额外的php扩展,而这个扩展恰好我没有装…
由于CURL还不是很熟,以前都是很简单的文件获取直接用 file_get_content
了,所以这次就直接找了一个cUrl的封装函数,修改到适合直接用了…
1 | function cUrl($url, $header = null, $data = null) |
然后直接调用。。
1 | ...... |
先判断json的解析结果。如果是空的,则解析出错。
1 | ...... |
这里是获取音频信息并打印在屏幕上。我从官方API中摘出大概对下载音频时标注和区分每个人音频的大概就是这些了。检查res是否存在是为了如果音频不存在,那么依然会返回json但是不存在res键值。这种情况一般意味着输入的链接有问题。
1 | ...... |
这一部分时我拼接输出文件路径的地方。直接输出在php文件的audios子目录下。文件名格式就是”用户名-音频标题-音频专辑-时间-随机数.m4a”。我习惯在输出文件时在文件名后加随机数避免重复。这个时间我用的是官方API中的”time_until_now”。
1 | ...... |
这一部分就是写文件和获取文件的地方了。
我先尝试连接喜马拉雅的m4a文件。(后来想想其实应该先打开本地文件的…),如果打不开则代表无法找到远程文件。如果打开了,就继续尝试打开本地的目标输出文件。本地的文件如果打不开,则代表缺少写权限等问题,关闭远程连接,抛出问题然后继续循环。如果两个连接都没有问题,那么OK,可以开始下载了。
下载之后关闭两个连接,输出下载成功消息以及文件位置,以及文件大小。1
2
3
4
5
6function getSizeT($file){
$fs = filesize($file);
if($fs===false) return "UNKNOW";
$size = round(($fs/1024)/1024,2)."MB";
return $size;
}
到此整个程序完成,试着跑了一下,效果还是不错的。
这个项目作为一次练手也作为帮别人写的一个工具,以后不会再更新。本文写的时候有一些新的改动并没有同步到gh中,可以以本文为准。
喜马拉雅音频获取工具 Github
CKylinMC
2017年9月13日
之前因为没有资金所以只能使用GH Pages这种简单的静态网页托管方式,由于懒所以总想找一个有可视化编辑的静态网页编辑器,然后就看见了hubpress。起初hubpress给我的印象非常好,但是慢慢的,很多问题暴露出来,比如连接慢和软件不成熟,最后不得不停止使用hubpress。然而我因为本地没有一个完美的markdown编辑器,所以还是想找一个带在线编辑器的博客程序,然后就看见了hexo。hexo有一个拓展叫hexo-admin,也是一个简单的在线管理的插件,正好电脑上有nodejs的环境就部署了。感觉还不错的,尤其是优雅的NexT主题。
所以这次应该不会变了!
2017.09.16
CKylinMC