有道詞典提供了柯林斯和朗文辭典,加上最近在背單詞且Mac版的屏幕取詞也夠用了,爲了雲單詞本的同步,決定拋棄Mac上的歐路詞典。單詞歐路上的單詞本也存了一百多個單詞。怎樣遷移到有道呢?node
關鍵詞:node.js csv http charles nginx
有道的Mac版和PC版都不支持導入歐路的單詞本文件(csv格式,是個好東西)。npm
若是是高中時的我,我會猜有道有一個本地的單詞本文件。我能夠把歐路導出的單詞複製粘貼到該文件(假設有道也採用csv格式,那麼就複製粘貼)。現是計算機科班出身,我想到的思路有:數組
1.OC語言的消息機制或許可讓我有可能調用到有道詞典運行時的函數;服務器
2.網絡接口(假若有道沒有對該API加密,那麼就能夠抓包而後仿照)。cookie
最近又恰好搞了點node.js,初嘗腳本語言的輕。不須要集成開發工具,Sublime Text + Terminal就夠了。網絡
POST ...(路徑) HTTP/1.1 | |
Host | dict.youdao.com |
Accept | */* |
Content-Type | application/x-www-form-urlencoded |
Connection | keep-alive |
Cookie | ...(Cookie) |
User-Agent | YoudaoDict/139 CFNetwork/760.6.3 Darwin/15.6.0 (x86_64) |
Accept-Language | en-us |
Accept-Encoding | gzip, deflate |
Content-Length | 984 |
data | <?xml version="1.0" encoding="utf-8"?>併發 <request> |
version | 2 |
這個接口沒有加密。分析抓到的Post請求,請求路徑和Cookie都是在一段時間內不會變化的。主要是其中的時間戳,單詞和釋義。函數
下邊是終端的命令行和控制檯輸出。AddAWord.js仿照上邊分析的請求,運行後返回的響應是200。下邊的亂碼是因爲返回的響應體是gzip壓縮過的,在這裏沒有進行解壓。看到狀態碼是200,有道里的單詞本已經多了「aWord」和「aaaa」。說明這個思路可行。
MBP:csv studio MacbookPro$ node AddAWord.js Status: 200 headers: {"server":"nginx","date":"Mon, 02 Jan 2017 08:16:52 GMT","content-type":"text/xml;charset=UTF-8","transfer-encoding":"chunked","connection":"keep-alive","vary":"Accept-Encoding","content-language":"en-US","content-encoding":"gzip"} body分隔線--------------------------------- u��� ��x �}C�[<T|�m/`\���`ʢ^�B��/��>�}0�V\�r��m���w���:��� <��ـ�e;�C�đѭ#2��Y��u�9���<N2P3�я?z���J��K.�J� 6�0ͦcFnH��U��l��TRĺ�~fJ�( body分隔線---------------------------------
node.js社區沒有讓我失望,很快我就找到了解析csv的模塊及其示例代碼。接下來的事情就簡單了,建立讀取csv文件的流,解析流中獲取的字符串,得到單詞列表數組,遍歷數組發送請求。
不過,當我用併發的形式發送全部單詞到服務器時,結果只是添加了一個或兩個單詞,我猜測的緣由是服務器對待這些請求是排隊的,因爲對時間戳的限制,幾乎全部請求餓死了。這時候須要用到同步請求。
Node.js原生沒有同步請求。npm上有不少可以實現同步請求的模塊,可是爲了保持單詞的順序,回調+遞歸會比較適合。關鍵代碼以下:
1 readerStream.on('end',function(){ 2 //把文本文件轉化爲字符串 3 var input = data; 4 parse(input, {comment: '#'}, function(err, output){ 5 //字符串解析爲對象以後,下邊發送調用網頁的API 6 //node.js原生不支持發送同步請求,同時爲了保持單詞的順序,直接採用回調遞歸 7 addToWordBook(output, output.length-1); 8 }); 9 });
全部單詞添加完畢。
後記:這個方法並不能廣泛化,由於須要抓包拿到token,cookie等數據,若要廣泛化,有一個思路是實現用賬號密碼登陸,用代碼取得token等數據,而不是經過抓包。