类爬虫方式利用Microsoft Bing Tranlator进行翻译

需求

最近要处理香港地铁相关的推文。推文中除了英文外还包含中文,日文,泰文等语言,同时一个句子中出现多个语言的情况很常见(比如,I am at 香港站)。

希望可以将其非英文的部分全部转换为英文。

现状

  • 尝试了百度翻译API
    • 优点
      • 免费无限使用
    • 缺点
      • 效果不佳。一些同时包含英文和中文的句子会被识别为英文,然后就没有翻译。
      • 感觉意思翻译的不是很到位。
  • 尝试了微软的Bing Translator API,
    • 优点
      • 翻译效果很好,同时包含英文和其他语言的句子可以只将非英文部分翻译为英文,
      • 意思翻译的很到位。
    • 缺点
      • 官方API免费额度太少,每个月只有两百万的字符(character)的免费翻译额度。(不是很清楚这里的字符是怎么计算的。不过就算是单词,那一条推文50单词左右,一个月只能处理4万条,还是太少了)。
      • 使用官方API需要绑定信用卡,太麻烦了。

思路

于是自然瞄上了微软bing的翻译网站。如果说可以模拟浏览器输入内容,进行翻译,然后提取输出内容,不是很好吗?

初步整体思路还是用selenium模拟浏览器行为,然后获取翻译结果。

当然微软肯定有反爬虫机制的。目前遇到的困难如下

  • 没有翻译按钮,而是输入内容后自动触发翻译
  • 用js直接改变输入框的value来输入值是无法触发翻译的。

不过幸运的是,用selenium第一次打开网页并输入内容的时候是可以触发翻译的。所以目前至少保证可以work的思路就是对每个待翻译的句子,都启动一个浏览器实例,获取到翻译结果后,就立即关闭该浏览器实例。

目前是慢了一些。用百度翻译api每个句子需要0.3秒,而用这个方法每个句子需要3.5秒左右。不过好在需要翻译的句子不是很多,只需要翻译哪些不是纯英文的句子就可以了,所以暂时还可以用,后面有空再钻研。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import time
from selenium import webdriver


bing_tokens = {
"url": "https://www.bing.com/translator",
}


def bing_translate(text: str):
"""目前基于爬虫的方法只支持翻译为英文"""
# 启动无头浏览器
options = webdriver.ChromeOptions()
options.add_argument('headless')
driver = webdriver.Chrome(chrome_options=options)
driver.get(bing_tokens["url"])
# 将单双引号都用反斜杠转义,不然带入js语句时会出错
text = text.replace("'", "\\'")
text = text.replace('"', '\\"')

input_script = """document.getElementById("t_sv").value="{}";""".format(text)
driver.execute_script(input_script)
time.sleep(0.5) # 太快的话翻译结果还没出来浏览器就关闭了
trans_res = driver.execute_script("return document.getElementById('t_tv').value;")
driver.close() # 记得释放资源
return trans_res

参考