分享一個控制檯翻譯工具

用起來長這樣
在這裏插入圖片描述

環境:
VirtualBox+Ubuntu 18.04.02

最近逛Ubuntu應用商店,看到網友做了這麼一個東東,感覺想法挺不錯的。學習Linux經常要閱讀英文文檔,手上有個控制檯輸出的翻譯工具,CTRL-TAB切換到終端,只需敲打相關的命令就可以馬上弄明白詞義。整個過程連鼠標都不用碰,確實會比GUI翻譯工具效率高出不少。
在這裏插入圖片描述

當然也有網友自己寫了個linux終端翻譯神器
,用一個文件來實現這個功能(用了很少的庫),只是輸出格式上還有待考究,而且沒有讀音標註。不過可以當成一個精簡的範例來學習。

這裏說一下yd應用安裝下來是不能使用的,報錯原因是main.py一處語法錯誤(引號不成對),文件目錄顯示2017年之後就沒人維護了。想着源碼都有,乾脆自己動手改。

順便說一下,這是snap商城的東西,安裝目錄都是隻讀的,所以還不能硬上。

環境搭建流程

  1. 將 /snap/yd/2/lib/python2.7/site-packages/youdao/ 這個目錄拷貝到$HOME下。

  2. 把main.py那處語法錯誤改了。

  3. 安裝所需要的庫,必要的時候加上版本號

    pip install termcolor
    pip install requests
    pip install peewee==2.9.1
    pip install bs4
    pip install lxml==3.7.3

  4. main.py中有個和snap相關的目錄要改,並且在這個目錄下創建/dicts空目錄。

    SNAP = ‘/home/USER_NAME/youdao’

  5. 在$HOME/.bashrc中加入自定義命令

    alias yd=‘python /home/USER_NAME/youdao/main.py’

  6. source $HOME/.bashrc

然後就可以盡情地玩耍了。

功能描述

今天看了下代碼,把用到的庫的作用也整明白了(原來這就是爬蟲),剛好看到main.py的幫助文檔是空的。

def show_help():
    desc = '''
    == 說明 ==

    * 功能描述

    獲取查詢結果有兩種方式:
    1. 使用api的方式,直接返回json字符串
    2. 使用頁面方式,則需要借用BeautifulSoup解析返回的html
    PS. 如果以上查詢都失敗(比如給句子加上標點),則使用有道翻譯

    查詢記錄保存在peewee數據庫中,所有基於db的操作都與此有關
    離線字典保存的目錄,由config.config['stardict']指定

    * 可選參數

    -a          使用有道api查詢,參考官網 http://fanyi.youdao.com/openapi?path=data-mode
    -n          不用數據庫中緩存的查詢記錄
    -l          列出查詢記錄及累計次數
    -d [key]    刪除制定文本的查詢記錄,包括髮音文件
    -c          刪除所有的查詢記錄,包括髮音文件
    -v          查詢並播放發音,可使用 yd -v 重複播放上一查詢記錄的發音
    -s [path]   指定離線字典的目錄,默認爲/dicts
    -y          完全的在線查詢。既不使用數據庫查詢記錄,也不使用離線字典
    '''
    print desc

修復get_translation函數

[spider.py]

   def get_translation(self, word):
        """
        通過web版有道翻譯抓取翻譯結果
        :param word:str 關鍵字
        :return:list 翻譯結果
        """
        r = requests.get(self.translation_url+word)
        if r.status_code != requests.codes.ok:
            return None

        pattern = re.compile(r'"translateResult":\[(\[.+\])\]')
        m = pattern.search(r.text)
        result = json.loads(m.group(1))
        return [item['tgt'] for item in result]

可能因爲有道翻譯版本升級過,這裏的get_translation並不好使,輸入以下命名會有tb。

ron@ron-Z68AP-D3:~$ yd 'Judge a book by its cover.'
[Judge a book by its cover.]
有道翻譯:
Traceback (most recent call last):
  File "/home/ron/youdao/main.py", line 236, in <module>
    main()
  File "/home/ron/youdao/main.py", line 233, in main
    query(keyword, use_db, use_api, play_voice, use_dict)
  File "/home/ron/youdao/main.py", line 117, in query
    show_result(result)
  File "/home/ron/youdao/main.py", line 45, in show_result
    print colored('\t'+'\n\t'.join(result['translation']), 'cyan')
TypeError: can only join an iterable

加個標點符號,api和web兩個方式就跪了
在這裏插入圖片描述預期是拿到翻譯’以貌取人’。
在這裏插入圖片描述既然原版的url訪問方式不可行,就自己嘗試實現這個功能好了。

[spider.py]
    translation_url = u'http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule'
    
    def md5(self, str_data):
        """
        md5加密
        """
        md5_obj = hashlib.md5()
        byte_data = str_data.encode('utf-8')
        md5_obj.update(byte_data)
        return md5_obj.hexdigest()

    def get_translation(self, word):
        """
        通過web版有道翻譯抓取翻譯結果
        :param word:str 關鍵字
        :return:list 翻譯結果
        """

        client = 'fanyideskweb'  #判斷是網頁還是客戶端
        
        # 由於網頁是用的js的時間戳(毫秒)跟python(秒)的時間戳不在一個級別,所以需要*1000
        salt = str(int(time.time()*1000))
        
        # 網上不同的攻略取的魔數是不一樣的,可能對應不同的版本吧
        c = "@6f#X3=cCuncYssPsuRUE"
        # c = "rY0D^0'nM0}g5Mm1z%1G4"
        # c = "ebSeFb%=XZ%T[KZ)c(sy!"
        
        # 根據md5的方式:md5(u + d + f + c),拼接字符串生成sign參數。
        sign = self.md5(client + word + salt + c)

        # bv用到瀏覽器的版本編號
        navigatorAppVersion = '5.0 (X11)'
        bv = self.md5(navigatorAppVersion)

        data = {
            'i':word,
            'from':'AUTO',
            'to':'AUTO',            #判斷是自動翻譯還是人工翻譯
            'smartresult':'dict',
            'client':client,
            'salt':salt,               #當前時間戳
            'sign':sign,   #獲取加密串
            'ts':salt,
            'bv':bv,
            'doctype':'json',
            'version':'2.1',
            'keyfrom':'fanyi.web',
            'action':'FY_BY_REALTIME', #判斷按回車提交或者點擊按鈕提交的方式
            'typoResult':'false',
        }

        headers = {    
            'Accept': 'application/json, text/javascript, */*; q=0.01',
            'Accept-Encoding': 'gzip, deflate', #
            'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
            'Connection': 'keep-alive',
            'Content-Length': '259', #
            'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
            'Host': 'fanyi.youdao.com',
            'Origin':'http://fanyi.youdao.com/',  #請求頭最初是從youdao發起的,Origin只用於post請求
            'Referer':'http://fanyi.youdao.com/', #Referer則用於所有類型的請求
            'User-Agent':'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:67.0) Gecko/20100101 Firefox/67.0',
            'X-Requested-With': 'XMLHttpRequest',
        }
        r = requests.post(self.translation_url, headers=headers, data=data)
        pattern = re.compile(r'"translateResult":\[(\[.+\])\]')
        m = pattern.search(r.text)
        result = json.loads(m.group(1))
        return [item['tgt'] for item in result]

效果
在這裏插入圖片描述
參考文獻:

Python網絡爬蟲(八) - 利用有道詞典實現一個簡單翻譯程序
解答了大部分問題,但是我的瀏覽器裏多了兩個參數ts bv。
在這裏插入圖片描述

有道翻譯的爬取
很不爽這裏面沒有說清楚爲什麼替換了url。不過有意思的是itchat這個玩意。
在這裏插入圖片描述破解有道翻譯反爬蟲機制
代碼直接可用,只是加標點會有tb。

ron@ron-Z68AP-D3:~$ python3 test.py 
請輸入Judge a book by its cover. 
判斷一本書的好壞灣。
Traceback (most recent call last):
  File "test.py", line 68, in <module>
    youdao(input("請輸入"))
  File "test.py", line 64, in youdao
    for i in strs_datas['smartResult']['entries']:
KeyError: 'smartResult'
ron@ron-Z68AP-D3:~$ python3 test.py 
請輸入Judge a book by its cover
通過封面來判斷一本書的好壞
以貌取人


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章