未末 - 2019年8月
type: channel
link: https://blog.weimo.info/2019/08
description: Find You
items: 爱奇艺vf算法player_v2版本——基于Nodejs（转载）
items: VSCode配置pylint语法检查插件
items: 从thinkcentral的swf中提取书籍——旁门邪道
items: 博客迁移记录——2019/8/11
items: 爱奇艺vf算法player_v1版本——JavaScript版
items: 近期

爱奇艺vf算法player_v2版本——基于Nodejs（转载）
type: item
date: 2019-08-24T02:32:22-04:00
description: 具体分析参见原作者博客下面是具体js代码，使用nodejs运行： global.document = { domain: "iqiyi.com", body: { clientWidth: 1901, clientHeight: 4159, }, }; global.window = { document: document, currentScript: {src: ' '}, history: {length: 4}, navigator: {userAgent: " "}, screen: { height: 1920, width: 1080 }, location: { host: '', hostname: 'www.iqiyi.com' }, }; window.window = window; global.self = window; build_cmd5x = function(module, exports, __webpack_require__) { var _qdb = function(e, t) { var n, r = _qda[e -= 0]; void 0 === _qdb.BeEAsi && ((n = function() { var e; try { e = Function('return (function() {}.constructor("return this")( ));')() } catch (t) { e = window } return e }()).atob || (n.atob = function(e) { for (var t, n, r = String(e).replace(/=+$/, ""), i = 0, o = 0, a = ""; n = r.charAt(o++); ~n && (t = i % 4 ? 64 * t + n : n, i++ % 4) ? a += String.fromCharCode(255 & t >> (-2 * i & 6)) : 0) n = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".indexOf(n); return a } ), _qdb.CrWsXc = function(e) { for (var t = atob(e), n = [], r = 0, i = t.length; r < i; r++) n += "%" + ("00" + t.charCodeAt(r).toString(16)).slice(-2); return decodeURIComponent(n) } , _qdb.uNcQSs = {}, _qdb.BeEAsi = !0); var i = _qdb.uNcQSs[e]; return void 0 === i ? (r = _qdb.CrWsXc(r), _qdb.uNcQSs[e] = r) : r = i, r }; function _qd_az() { var aA = function(e) { for (var t in e) if (e['hasOwnProperty'](t)) return !1; return !0 } , aD = function(aE) { return eval(aE) } , aF = function(e) { // console.log('start'); if ('mwlCr' !== 'UdOHx') return typeof ArrayBuffer === 'undefined' ? 'iloveiqiyi' : aU['ccall']('cmd5x', 'string', ['string'], [e]); b[na >> 2] = ma, ma = 0 | b[15], ma ? (w = ma + 4 | 0, b[na + 4 >> 2] = b[w >> 2], oa = w) : (b[na + 4 >> 2] = na, oa = 60), b[oa >> 2] = na } , aI = function() { var e = {}; e['qd_v'] = 2, e.tm = (new Date)['getTime'](); var t = window; for (var n in typeof t['navigator'] === 'undefined' ? e['qdy'] = "u" : e['qdy'] = 'function%20javaEnabled%28%29%20%7B%20…

VSCode配置pylint语法检查插件
type: item
date: 2019-08-23T02:11:00-04:00
description: 新版的VSCode的设置视图默认是将workbench.settings.useSplitJSON关闭的，然后新手（比如我）发现网上很多教程都是编辑一个json配置文件，有时候搜半天不知道在哪儿...所以先在设置搜索workbench.settings.useSplitJSON，将它勾上然后再搜索python.linting.pylint，点击右上角右起第三个图标打开设置就可以编辑配置文件了下面是我的语法检查设定，具体含义可以对应官方文档查看（主要是懒得写）python.linting.pylintArgs主要是可以用来关闭一些不必要的提示，否则全屏幕都是各种警告（毕竟代码渣）{ "python.linting.pylintArgs": [ "--extension-pkg-whitelist=PyQt5", "--disable=W0612,W0631,W0703,W0621,W0613,W0611,W1308,C0411,C0111,C0103,C0301,C0304,C0305,E1101,R0913,R0914,R0915,R0903" , ], }

从thinkcentral的swf中提取书籍——旁门邪道
type: item
date: 2019-08-18T12:18:00-04:00
description: [dplayer url="http://pan.iqiyi.com/ext/paopao/?token=eJxjYGBgmBQtsZUBBGZOWAkAFbIDjQ.mp4" pic="http://pan.iqiyi.com/ext/paopao/?token=eJxjYGBgmBQtsZUBBGZO0QIAFTsDEg.jpg" autoplay="true"/]操作视频预览如上（不知道能不能看）。总的来说就是：python通过selenium库控制Chrome类的浏览器执行打印页面的操作，涉及到的问题如下：swf转pdf，很特定的情况下才有方法。单页是swf，新版本Chrome无法在headless情况下打开flash。就算默认打开flash（注册表的方式），然而Chrome会直接下载swf文件，而不是加载。360极速浏览器可以加载swf并打印页面，但没找到用selenium控制它的方法。这网站swf链接规律有坑，需最后还是用接口拼接的链接。...还有很多要写的，但是今天太晚了...最后发现360安全浏览器可以满足要求。最终得到的pdf清晰度很好。暂时写到这里，有空再补充，毕竟踩了很多坑。————2019/08/19 15:40————(手机码字ing，有些没记住)起因一个朋友截图谷歌搜索Storytown pdf，说想要这个书的电子版，不过谷歌到的只有一点残缺的pdf，没有完整的，当然亚马逊是有卖的←_←不过呢，最后还是在(rasd)上面找到了，不过这个网站像是套了一层，实际来源是thinkcentral，不过thinkcentral这个网站得有账号，普通用户注册不了。这不重要，反正目前这个网站能在线看书，准确说是一个互动式的学习，但它是基于swf的。怎么弄下来呢？F12一看，分页是单独的swf，那可以把swf下载来了然后反编译提取图片即可！下载了一个swf，用FFDec反编译，有一个frame就是一个单页：导出为png，打开一看清晰度还可以(那后面拼图做成pdf就好了，心想……)。————2019/08/19 16:50————那快速自动化的流程就是下载swf，反编译，导出图片，按顺序合成……然后我试着用python来做反编译这个事情，幸运的是网络上有一个可参考的例子，通过一个库(pyswf)，能解析swf的结构，解压资源。不过我发现对于我来说有点复杂了，等我把swf解压这步理解清楚就不知道何年何月了。。然后又找到一个工具swftools，不过它是各种转为swf，而不是swf转回。不过呢它在某个情况下可以复原pdf，然而！它是基于python2的(？？？)。遂放弃反编译swf←_←接着我想找现成工具解压swf内资源，然后我再合成图片，反编译的swf内文字部分其实是可以拿到文本的，不过它是位图，背景是另一个图(其实还是卡在解压资源)，提这个是因为我想在pdf能复制到文本。我还是图样图森破。另外在打开单个swf的时候，通过放大可以发现很清晰，所以位图没错了。接着，就是在放大的时候，右键的打印选项提醒了我，于是打印了单页的swf，发现质量非常好，清晰度也棒！终于到正题了，那我可以打印得到单页pdf，最后合成。话不多说开始做，通过搜索，可以知道打印这个操作是可以用python通过selenium库办到的(面向google写代码)。这里引出了几个问题：一是单个swf打开会缺少一些东西，比如播放音频的按钮，部分单词选中颜色效果以及一些动画效果，因为这些是外部嵌套的swf完成的，好在需要的是书，这些部分可有可无(不过呢，音频的位置好像在一个接口里面有，有精力的话倒是可以试试把音频内容也添加到pdf里面，pdf应该是支持音频的)。二是谷歌浏览器对swf不友好，链接以swf结尾会背直接下载文件，而我需要的是网页加载完毕的效果后打印，解决方法是写一个HTML文件，里面引用swf的链接，打开HTML文件后会加载。不过得手动允许flash才能加载，好在网上说能修改注册表让chrome默认允许flash，但我尝试用selenium控制chrome，没有成功，最终放弃。我打开flash链接看加载效果是用的360极速浏览器，360极速内核还是基于chrome(的开源版本？)然后想应该也能用selenium操作，搜了下貌似真的可以。不过在我N次尝试后，发现并不能，遂改用网络教程中的360安全浏览器，果然成了！关键的打印swf一步解决了。最开始看了下swf的链接还是有规律组成的，就手动跳到最后几页观察了一下，然后就开始跑代码了，最开始一切正常。后来出现chapter首字母在第一章后变成大写……后来出现数字四位补0……后来出现新章节处有a/b这样的附加字符……后来发现自己的代码逻辑有问题……于是乎，改用从接口获取拼接的后部分，这才稳定了下来！打印的时…

博客迁移记录——2019/8/11
type: item
date: 2019-08-11T07:32:00-04:00
description: ————2019/08/18————修改typecho配置 后台ip显示为正常ip而非cdn的ip————2019/08/17————恢复了share站点。其他待处理事项：使用cdn后，后台ip不是真实ip问题。share的数据库看起来有很多问题，可能需要重新导出整理。检视typecho在大量文章下的使用情况。————2019/08/13————增加了评论邮件提醒功能。使用的插件是LoveKKComment更改原bootcss的js/css地址为jsdelivr，jsdelivr用到的js/css如下： 注释掉了X.js中InstantClick的部分，这看起来是原作者没有写完，这样console暂时不会报错Uncaught ReferenceError: InstantClick is not defined。——————————————————下午倒腾了几个小时，终于把博客重新迁移到新的服务器上了。遇到几个问题，在此记录一下。域名变更为了平滑过渡（我也不知是不是这样想的）？然后就弄了个临时域名，然后搭好配置了一些基本的东西，隔了几天（即今天）才把之前的文章恢复上来。然后typecho告诉我你这几天写的会被直接清除覆盖。还好看到了，要不然手快就把这两天的删掉了。然后没找到什么好办法能同时保留已有文章同时恢复之前的文章，就手动备份，Ctrl C + Ctrl V就简单做了下。。主要是比较少，就两三篇，另外想到的方法就是插入数据库，不过这很不划算。跑偏了，回到域名变更的问题上来，临时域名这些步骤操作完了，那就要切回到正式的blog域名啊，结果DNS解析改完之后居然登录不了后台，一直提示“密码或用户名无效”，这我就怪了，我就改了域名呐。。搜了下似乎也没有人说出来这个是为啥不行，清一色的phpMyAdmin改密码...不行不行，改个密码还要安装phpMyAdmin那可太费时间了（主要是不熟悉），那就直接命令行mysql改呗！然后找到这篇博客，下面是更改的方法，贴一下（主要是怕原博客挂了...）由于我用浏览器保存了密码，每次登录都是自动填写，老域名到期换了新域名，浏览器就不认网站了。试了好多次才成功，记下来。在数据库中执行以下语句用户ID如有需要记得改UPDATE `typecho_users` SET `PASSWORD` = '$P$BfpuGkuI0iIH/4/eLbkYXcRpWyN0Je0' WHERE `uid` = 1; UPDATE `typecho_users` SET `authcode` = 'ff576420bcabf63885dd553174dbaa77ef2f641e' WHERE `uid` = 1;执行完毕后相关UID的用户密码就是123456了不过我有点不放心，所以就想知道数据库表结构，然后突然发现自己好久没用过mysql了，命令几乎全部GG。不过最终还是查到命令了（就当复习一下），那么下面是整个修改数据库用户信息所执行的命令。mysql -u yourusername -p yourpassword mysql> SHOW DATABASES; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | typecho | +--------------------+ mysql> select table_name from information_schema.tables where table_schema="typecho"; +-----------------------+ | table_name | +-----------------------+ | typecho_comments | | typecho_contents | | typecho_exsearch | | typecho_fields | | typecho_links | | typecho_metas | | typecho_options | | typecho_relationships | | typecho_users | +-----------------------+ mysql> use typecho; mysql> select * from typecho_users; +-----+-------+------------------------------------+------------------+------------------------+------------+------------+-…

爱奇艺vf算法player_v1版本——JavaScript版
type: item
date: 2019-08-11T05:00:19-04:00
description: player_v1版似乎近期会被替换掉，仅作记录。function cmd5x(b) { R = new ArrayBuffer(16 * 1024); pt = 321 * 16; Rp = new Int32Array(R); Rq = new Uint8Array(R); a = new Int8Array(R); c = new Int32Array(R); Rp[0] = 255; i = 1760; m = 0; n = 0; o = 0; p = 0; s = 0; t = 0; u = 0; v = 0; w = 0; x = 0; y = 0; z = 0; A = 0; B = 0; C = 0; D = 0; E = 0; F = 0; G = 0; H = 0; I = 0; J = 0; K = 0; L = Math.floor; M = Math.abs; Z = Math.imul; _ = Math.min; ua = 0; var ut = 0; for (var ui = 0; ui < b.length; ++ui) { var u = b.charCodeAt(ui); if (u >= 55296 && u <= 57343) u = 65536 + ((u & 1023) << 10) | b.charCodeAt(++ui) & 1023; if (u <= 127) { ++ut } else if (u <= 2047) { ut += 2 } else if (u <= 65535) { ut += 3 } else if (u <= 2097151) { ut += 4 } else if (u <= 67108863) { ut += 5 } else { ut += 6 } } var ps = new Array(ut + 1); var po = 0, pn = 0; Rp[51] = 3920; Rp[54] = 8328; var pm = pn + ut; for (var ui = 0; ui < b.length; ++ui) { var u = b.charCodeAt(ui); if (u >= 55296 && u <= 57343) u = 65536 + ((u & 1023) << 10) | b.charCodeAt(++ui) & 1023; if (u <= 127) { if (pn >= pm) break; ps[pn++] = u } else if (u <= 2047) { if (pn + 1 >= pm) break; ps[pn++] = 192 | u >> 6; ps[pn++] = 128 | u & 63 } else if (u <= 65535) { if (pn + 2 >= pm) break; ps[pn++] = 224 | u >> 12; ps[pn++] = 128 | u >> 6 & 63; ps[pn++] = 128 | u & 63 } else if (u <= 2097151) { if (pn + 3 >= pm) break; ps[pn++] = 240 | u >> 18; ps[pn++] = 128 | u >> 12 & 63; ps[pn++] = 128 | u >> 6 & 63; ps[pn++] = 128 | u & 63 } else if (u <= 67108863) { if (pn + 4 >= pm) break; ps[pn++] = 248 | u >> 24; ps[pn++] = 128 | u >> 18 & 63; ps[pn++] = 128 | u >> 12 & 63; ps[pn++] = 128 | u >> 6 & 63; ps[pn++] = 128 | u & 63 } else { if (pn + 5 >= pm) break; ps[pn++] = 252 | u >> 30; ps[pn++] = 128 | u >> 24 & 63; ps[pn++] = 128 | u >> 18 & 63; ps[pn++] = 128 | u >> 12 & 63; ps[pn++] = 128 | u >> 6 & 63; ps[pn++] = 128 | u & 63 } } ps[pn] = 0; Rq.set(ps, pt); b = pt; var d = 0, e = 0, f = 0, g = 0, h = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p …

近期
type: item
date: 2019-08-05T10:57:00-04:00
description: ---2019/08/05---本来准备写一长篇关于近期的文章，不过今天又由于种种原因没有时间了...不过多少还是要开一个头的。