这些年我一直跟着维护Pt-Gen以及PTPP、豆瓣搜索大师等公开项目。然而19年起,豆瓣逐渐关闭公开API (豆瓣疑下线所有公开 API),从现有豆瓣APP的 frodo 接口请求相关数据,所需要构造的参数过于麻烦。
所以在这段时间,我们一直使用 https://movie.douban.com/j/subject_suggest 接口来实现搜索功能作为过渡。这个接口构造简单,而且返回的数据直接为JSON格式,但同样存在返回的数据较为简单的问题,例如:
1 | [ |
只返回了img, title, url, type, id(虽然基本够用….)。这主要是因为该接口只是用来搜索建议的,而真正搜索界面的结果隐藏在了subject_search页面的 __DATA__ 对象中。所以我们需要用另外一种方法来破解该对象。
我最早找到的文章来自掘金的这篇 豆瓣读书搜索页的window.__DATA__的解密 ,然而作者的思路是直接扒取豆瓣自带的JS文件(这当然没有问题)。然而作者讲的挺玄乎的: 总之很复杂,这个只能意会不能言传,篇幅有限,也不可能全部一个一个扣出来并和你说怎么改。
正当我以为没有办法,只能复制这位作者成果的时候(毕竟顶层函数有了,而且我也是在 JavaScript 环境中使用,不需要在Python中调用),我检索到了另外一个项目 dli98/Spider,文中作者详细介绍了 window.__data__ 参数破解过程是使用 base64 + xxHash + rc4 + bplist 一整套的思路,并指出 bplist 处理流程有暗改的情况。
但这位作者的结果其实并不对,少了最后一步的映射调整 (见 怎么获取豆瓣评分和投票数的顺序 · Issue #2 · dli98/Spider),所以得到的结果并不对。
所以就干脆直接写个 npm 库算了,之后工程中也能使用。于是你现在可以使用 npm i douban-search-crack来进行安装,其实例代码如下:
1 | import axios from 'axios'; |
函数主流程如下:
1 | export default function decryptDoubanData(dataRawString: string): searchData { |
其中 xxhash 部分直接用库;rc4 因为过于简单,所以方法也直接内置;bplist解密因为豆瓣的暗改,所以不能直接用库,所以也是将库文件修改后内置的(原来想学着用monkeypatch的,然而patch发现还不如直接内置)。
此外,bpList部分,对比库原实现,除调换了objType= 4,5,6的解析方式,还删除了 对库 bigInt 的依赖,以及对header的检查。
而 fixture 模块,主要因为 BpList 返回的值主要为一个list,里面的Object字段基本如下:
1 | {k: [ 40, 27, 35, 50, 52, 44 ] } |
所以我们需要进行修正,其中各数字均表示其在原list中的位置。通过对比 sergiojune 扒出来的代码,形成了矫正的步骤,具体可见 utils/fixture.ts 文件。
那么,自此,你就可以使用 douban-search-crack来在node以及browser环境中来破解豆瓣搜索的DATA数据。与直接扒网页js相比,如果你在node环境中,那么总文件大小 仅 16.0 KB (16,452 字节)。而如果你要在Browser环境中使用,那么也可以直接使用打包好的 dist/bundle.js 文件,其大小为 47.0 KB (48,147 字节),与直接扒拉js的实现大小基本相同。
