Discuz在X3中增加了防采集功能,具体见Discuz x3.0防采集设置图文教程

开启防采集后,访问DZ站点的伪静态链接如http://www.discuz.net/thread-3275423-1-1.html后面会跟上一个?_dsign=xxxxxx,正常链接如http://www.discuz.net/forum.php?mod=viewthread&tid=3305274会加上&_dsign=xxxxxx。这让人很不爽 (o#゜ 曲゜)o

使用httplib2访问原帖子页面(下面以http://www.dz.net/forum.php?mod=viewthread&tid=768为例),返回的是一段混淆过的js,如:

显然这样人类是无法理解的……不过使用notepad++的JSFormat插件格式化后还是能看懂的嗯-v-

实际上这是一个字符串替换然后重定向的脚本,生成原理如下(不完全按照上面的例子):

  • 原始字符串为location.href=forum.php?mod=viewthread&tid=768&_dsign=6f979101
  • 随机分割这个这个串,如分成l, oc, a, tio, n., ……
  • 对每一个子串替换成一个随机命名的函数,如l替换成_Oc9S(),则在脚本里加一句function _Oc9S(){return ‘l’;}以此类推
  • 每个function都可能加入奇怪的例如’return l;’这样毫无意义的混淆
  • 最后在末尾加上window.href=yyy,yyy为取forum.php?mod=viewthread&tid=768&_dsign=6f979101的前x个字符后得到一个子串

我大概写得不清楚……就……这么个意思……

毫无疑问要使用PyV8了,本来想自己写个解释器,但是算法太渣只能呜呼哀哉QAQ
这里有个问题,PyV8只是一个js解释器的包装,不是浏览器的js运行时,因此location啊window啊都是undefined的,所以要手动把这些都去掉。(有一点要说明,就是由于js很骚,location.href有时会被写成location[‘href’],或者用location.assign或者location.replace,而assign和replace都可能被一个随机命名的变量替换掉了)

直接看代码吧

这样就得到了包含dsign的新url,可以继续爬了

最后对DZ的防采集再说几句

  1. 防采集是对IP不对用户的
  2. 而且要看站长的设置,有可能只对帖子或日志等开启;你们可以到Discuz x3.0防采集设置图文教程感受一下
  3. _dsign的值是固定的,计算完一次js后可以考虑保存起来,以后可以直接访问加上_dsign的url
  4. 防采集是针对不支持js的机器人的,如果用python直接控制浏览器的话,可以无视之
  5. 如果mechanize和PyV8能合体那该多好~ o(* ̄▽ ̄*)o

Done,继续去抓ラブリーマイエンジェルあやせたん♪的写真了嗯哼哼哼