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,繼續去抓ラブリーマイエンジェルあやせたん♪的寫真了嗯哼哼哼