“遇到问题,解决后留笔记。这个习惯多数人都没有,所以这是个坏习惯。”
oneClickDeleteInstagramPost 是一个用于快速删除 Instagram 帖子的 userscript。
这个脚本可以让用户在 PC 端的个人页面直接删除自己的 Post,并且没有 Yes/No 的确认提示框。可以非常快速且直接了当的进行删除。
嘛嘛嘛,文档都已经在 GitHub 和 Greasy Fork 上写好了。这里就只写开发日志。
需求
和之前开发的 一键删除微博 oneClickRemoveWeiboPost 和 一键删除微博粉丝 oneClickRemoveWeiboFans 是相似的功能,不过这回只开发删 Post。Instagram 的垃圾粉举报功能相当有效,用不着开发删粉这种功能。
其实我一开始也没注意到 PC-Web 端已经不能删 Post 了,稀里糊涂给自己的项目加了一个功能特性。
嘛功能就是删删删。你有什么不想让新认识的朋友或未来要认识的朋友知道的照片啊视频啊,删删删。
开发过程
因为已经有了对付微博的思路,所以回来看 Instagram ,很多事情就会更清晰一些。
如何触发删除动作
首先去找 Instagram 自己的 删除Button。之后看这个 Button 上绑定了什么。
结果:只绑定了一个无参数的谈提示框的动作,提示框的确认键只绑定了一个的删除动作,没有参数
结论:删除动作的参数是从 Post页 中的其他地方读取到的。
删除动作都做了什么
删除一张图片,看看发生了啥
结果:发了一条类似 https://www.instagram.com/create/1891287498982886236/delete/
的 POST 请求
结论:中间那串数字就是对应 POST 的 KEY!
如何获取那个 KEY
首先看看这个 KEY 在 POST 详情页的情况
结果:详情页的 Header 中you这么一条 meta:<meta property="al:ios:url" content="instagram://media?id=1881262666259778354">
,同时还发现了另一条 meta <meta property="al:android:url" content="https://www.instagram.com/p/Boblm13nksy/">
,正是这条 POST 的 URL。
结论:这个 KEY 叫 media_id ,而且还跟 ios 上的 APP 相关,而到了 Android 则又使用 Url。不论是使用哪种方式,都能定位到唯一 POST。
考虑
Instagram 不是中国人对付出来骗融资套现跑路而搞出来的产品,而是十几个青年实打实做出来的世界一流产品,所以要在性能优化成本控制上都做出考虑。一个 POST 搞俩 KEY 这种缺心眼的事情绝对不可能。这两个 KEY 一定有什么硬相关的东西,一定可以在无数据库的情况下互相转换。
探寻
到网上搜如何根据 Url 获取 media_id ,多数给出的都是通过 Instagram 的 API 。当然这个正规途径是不适合用在 userscript 的。
有用的是 stackoverflow 上的这个 Where do I find the Instagram media ID of a image ,Anselm 给出了多种方法用来 media_id 与 url 之间的相互转换。
尝试
根据 Anselm 的代码片段,很快就可以理解出:media_id 与 url 之间其实是一种类似 Base64 – Base10 url safe 的关系
很快就写出了 DEMO ,但是运行后发现 url 转换到 media_id 时,一直有 300 以内的误差。Anselm 的代码片段只是概念?实际运行会出错?
于是点进 Anselm 提供的 Slang 的 npm 项目:Instagram Id To URL Segment,不过是 coffee 写的,虽然说 coffee 只是 js 的超集,但有点看不懂。好在其可以再编译成 js 。编译运行后发现并没有精度问题,于是仔细研究他的代码,发现他引入了 bignumber.js ,也就是说这个精度问题原来是 js 引起的。
重新改写了自己的代码,并按照 userscript 的规定,引入了 bignumber.js ,结果一直报错 [BigNumber Error] Base out of range: 64
。明明代码逻辑一模一样,为什么我这就报错了呢?
回头再去检查 Slang 的项目,发现他引入的 bignumber.js 是 2.4.0 ,而我在 jsdelivr 上找到的是 7.2.1 。换到 2.4.0 之后问题就解决了。可能是 bignumber.js 在新版本中改动了什么?暂时没有时间研究。
于是成功从 Url 获得 media_id。
下一步
模拟删除请求,结果被提示 403 。检查字段,csrf_token,加字段,没了。
剩下的
剩下的就是读取每个 POST 的描述,<img>
标签里都有,但是不适用于视频。
Instagram 的 Web 貌似是用 React 写的?所以很多用面向 DOM 的操作都不适用,想启用 userscript 就必须在个人页面刷新,不然就得改 @match
并且不停刷。本身 Ajax 载入我就没搞定,只能做 2 秒一刷,再所有页面都刷就太糟了。
一堆已知问题都暂时无力解决。感觉也是越来越对付了。
近期评论