之前用python寫了個發(fā)表說說的爬蟲,但最近發(fā)現(xiàn)在post數(shù)據(jù)時返回不對,不能用了,抓包后發(fā)現(xiàn)需要添加一個qzonetoken的字符串,這個token并不在cookie里。聯(lián)想到以前爬貼吧時也有個類似的token,貼吧的token是放在html里的,并且是明文。查看html,果然有個window.g_qzonetoken的值,同樣是明文,于是愉快的提取出來,然后post,成功。 過幾天后,代碼又不能用了,還是qzonetoken不對,抓包后發(fā)現(xiàn)這個token不再是明文了,變成了這個樣子
<script type="text/javascript"> window.g_qzonetoken = (function(){ try{return (+[]+[])+(!+[]+!![]+!![]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+[])+([]+{})[!+[]+!![]]+(!+[]+!![]+!![]+!![]+!![]+[])+([]+{})[!+[]+!![]]+(![]+[])[+[]]+([][[]]+[])[!+[]+!![]]+([][[]]+[])[!+[]+!![]]+(+!![]+[])+(+!![]+[])+(+!![]+[])+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!+[]+!![]+[])+(![]+[])[+[]]+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+[])+([]+{})[!+[]+!![]]+([][[]]+[])[!+[]+!![]]+(![]+[])[+[]]+(![]+[])[+[]]+(+{}+[])[+!![]]+(![]+[])[+[]]+(![]+[])[+[]]+(!+[]+!![]+!![]+!![]+[])+(+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+[])+(+!![]+[])+(!+[]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+[])+(![]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(![]+[])[+[]]+(!+[]+!![]+!![]+!![]+[])+([]+[][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+(![]+[])[!+[]+!![]]+([]+{})[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+(!![]+[])[+[]]+([][[]]+[])[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]])())[+[]]+([][[]]+[])[!+[]+!![]]+(+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+[])+(!+[]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+[])+(!+[]+!![]+!![]+[])+(!+[]+!![]+[])+(+!![]+[])+([][[]]+[])[!+[]+!![]+!![]]+([][[]]+[])[!+[]+!![]+!![]]+([]+{})[!+[]+!![]]+([]+{})[!+[]+!![]]+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+[])+(+!![]+[])+(+{}+[])[+!![]]+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+[])+(+[]+[])+(!+[]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+[])+([][[]]+[])[!+[]+!![]+!![]]+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+[])+(+[]+[])+(!+[]+!![]+!![]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+[])+(+{}+[])[+!![]]+(!+[]+!![]+!![]+!![]+!![]+[])+([][[]]+[])[!+[]+!![]+!![]]+(![]+[])[+[]]+(+{}+[])[+!![]]+([][[]]+[])[!+[]+!![]]+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+[])+(+!![]+[])+(!+[]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+[])+(+[]+[])+(+{}+[])[+!![]]+(!+[]+!![]+[])+(!+[]+!![]+!![]+[])+(+!![]+[])+(+!![]+[])+([]+{})[!+[]+!![]+!![]+!![]+!![]]+([][[]]+[])[!+[]+!![]+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+(![]+[])[+[]]+(!+[]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+[])+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+[])+(+{}+[])[+!![]]+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+[])+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(![]+[])[+[]]+([][[]]+[])[!+[]+!![]]+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+[])+([]+{})[!+[]+!![]]+(!+[]+!![]+!![]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+[]);} catch(e) {var xhr = new xmlHttPRequest();xhr.withCredentials = true;xhr.open('post', '//h5.qzone.QQ.com/log/post/error/qzonetoken', true);xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');xhr.send(e);}})();</script>`“這什么鬼!” 我第一反應。立馬聯(lián)想到以前看過的一道js題,就是這個樣子的,但是不知道這叫什么!還好百度是強大的,了解到這叫jother編碼,原來還能這么玩! 然后搜索如何在python中執(zhí)行js,安裝execjs模塊,代碼是這樣的
ctx = execjs.compile('''function qzonetoken(){return %s}'''% jother) print ctx.call("qzonetoken")將js腳本中的那一串jother編碼帶入,高興得跑起來!然后報錯了!
raise exceptions.ProgramError(e)execjs._exceptions.ProgramError: ReferenceError: location is not defined ( @ 2 : 7 ) -> return location提示說location沒有定義,我覺得奇怪,我將這段js放到瀏覽器consle中都能正常運行,為什么python中就不行呢!然后懷疑這個execjs模塊有問題,還費勁地安裝了pyv8,還是得到同樣結(jié)果,報錯:location無定義。一番搜索后,解釋是:execjs只是純粹的js運行環(huán)境,沒有dom結(jié)構(gòu),而這個location就是dom中的一個對象。又碰巧在jother編碼工具 這個網(wǎng)站中發(fā)現(xiàn)了這樣一段話
[]['sort']['constructor']('return location')();可以返回當前的url地址location沒有定義 ,不會就是這個吧? 既然沒有解析dom,那我就聲明一個location對象,賦值為url地址,試試看。代碼改為這樣
ctx = execjs.compile('''function qzonetoken(){ location = 'http://user.qzone.qq.com/%s'; return %s}'''% (qqnum,jother)) return ctx.call("qzonetoken")成功運行,得到了類似這樣的token:
82dafbd6f5d1f1606458c68ee54c14aa222ecc81351491a0104e43831c1cfb2e7cc82dbfcd3ffd1b33a031d97de9f8804b8f0c489將這個與瀏覽器consle中得到的結(jié)果比對,是相同的,再帶入post測試,成功! 總結(jié):查這個問題,就吃虧在不懂js,不明白location是什么!計多不壓身呀,多學點總沒壞處!最后,寫這段js代碼的程序員贊,是一位有情懷的工程師!
新聞熱點
疑難解答