代码改变世界

关于谷歌翻译爬虫

2017-02-27 21:50  kopo_C  阅读(140)  评论(0)    收藏  举报

周一总是让人郁闷,好不容易还有一个小时下班,主管突然跑过来让我用python写一个程序,要求能够出现谷歌翻译的英汉互译。

第一时间,我想到了爬虫。设想很简单,通过程序员编辑模式,查找数据源的url以及需要提交的东西。一开始很顺利,而且可以通过url就可以看出搜索的内容以及要求翻译的语言。当我直接变换url最后的原语句,转至该url时,却发现出现了404。后来我又仔细了看了一下生成的url,发现中间有一长串属性为tk的编码。我怀疑这就是问题的关键:根据时间戳或者其他什么相关因素得到一个序列,才能进行提交。而这个计算方法(或者合成request url的参数)是隐藏在之前的js文件中。这个工程量比较大,而且谷歌的反爬虫机制不可能让你这么轻易找到的。

之后,我又想用最简单最暴力的方法:使用selenium+PhantomJS来模拟人类登录查询。这个可行性也不是很高,因为不知道为何PhantomJS对很多操作都无能为力。之前我做的很多动态网页爬取基本上都是通过Firefox来实现。对于主管让我提交的一个简单的python接口查询Google明显划不来。

最后实在没办法,我在网上百度一下有没有大牛抓去过翻译的。看了前几个,都是14年的,大概看了一下代码,没有我需要的tk值得求法。在我快绝望的时候发现一篇16年的博客,里面给出了tk值得方法。在这里我没有深究具体计算过程(好吧主要不会js……),直接通过爬取博主最后给出这个网站的页面来间接获取相关的内容。相关代码如下# -*- coding: utf-8 -*-


import re, urllib.parse, urllib.request, http.cookiejar
from lxml import etree

class translate(object):
    def __init__(self):
        cj = http.cookiejar.LWPCookieJar()
        cookie_support = urllib.request.HTTPCookieProcessor(cj)
        opener = urllib.request.build_opener(cookie_support, urllib.request.HTTPHandler)
        urllib.request.install_opener(opener)
        self._url = ""
        self._question = ""
        self._sl = 'en'
        self._tl = 'zh-CN'
        self.method = "get"
        self.page = ""
        self._headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20100101 Firefox/23.0'}
    
    def changeLanguage(self):
        temp = self._sl
        self._sl = self._tl
        self._tl = temp
        
    def createURL(self):
        self._url = "http://www.liuxiatool.com/t.php?sl=" \
        + self._sl+"&tl=" + self._tl + "&q=" + self._question + \
        "&p=1&method=" + self.method + "&type=output&tijioao=submit"
    
    def createQuestion(self, text):
        self._question = text.replace(" ", "+")
        
    def en2zh(self, text):
        if self._sl == 'zh-CN':
            self.changeLanguage()
        self.createQuestion(text)
        self.createURL()
        self.getData()
        self.extractInfo()
    
    def zh2en(self, text):
        if self._sl == 'en':
            self.changeLanguage()
        self._question = token2utf(text)
        self.createURL()
        self.getData()
        self.extractInfo()

    def getData(self):
        request = urllib.request.Request(url = self._url, headers = self._headers)
        response = urllib.request.urlopen(request)
        self.page = response.read().decode('utf-8')
        
    def extractInfo(self):
        selector = etree.HTML(self.page)
        links = selector.xpath("/html/body/p[2]/span/text()")
        self._translate = str(links[0])
        print(self._translate)

def token2utf(res):
    res = res.encode('utf-8')
    res = str(res)[2:-1]
res = res.replace("\\x", "%") #res
= '%' + '%'.join(filter(lambda x:x, res.split('\\x'))) return res

在这里只需要使用这个类,之后根据需要(汉译英或者英译汉)选择函数,直接返回谷歌翻译后的结果。