python - Mechanize 不适用于在 Google Appengine 中自动登录 gmail

标签 python google-app-engine gmail mechanize

我已经使用 mechanize 并在 GAE 上部署了一个应用程序,它运行良好。但是,对于我正在制作的应用程序,我正在尝试通过 Mechanize 自动登录到 gmail。它在本地机器的开发环境中以及在应用引擎上部署后都不起作用。

我已经能够使用相同的脚本通过使用 PSP 的 mod_python 在我的服务器上运行它。

我在这里找到了很多解决方案,但似乎没有一个适合我。这是我的代码片段:

<snip>
br = mechanize.Browser()
response = br.open("http://www.gmail.com")
loginForm = br.forms().next()
loginForm["Email"] = self.request.get('user')
loginForm["Passwd"] = self.request.get('password')
response = br.open(loginForm.click())
response2 = br.open("http://mail.google.com/mail/h/")
result = response2.read()
<snip>

当我查看结果时,我得到的只是与 appengine 一起使用时的登录页面。但是通过在我自己的服务器上托管的 mod_python,我得到了包含用户收件箱的页面。

最佳答案

这个问题很可能是由于 Google 如何削弱了 GAE 上的 urllib2 模块。

在内部,它现在使用 urlfetch 模块(这是 Google 编写的东西)并且他们已经完全删除了 HTTPCookieProcessor() 功能 - 这意味着,cookie 不会在请求之间持续存在,这是以编程方式自动登录站点时的关键部分.

有一种解决方法,但不是使用 Mechanize 。您必须推出自己的 Cookie 处理器 - 这是我采用的基本方法(不完美,但可以完成工作):

import urllib, urllib2, Cookie
from google.appengine.api import urlfetch
from urlparse import urljoin
import logging

class GAEOpener(object):
    def __init__(self):
        self.cookie = Cookie.SimpleCookie()
        self.last_response = None

    def open(self, url, data = None):
        base_url = url
        if data is None:
            method = urlfetch.GET
        else:
            method = urlfetch.POST
        while url is not None:
            self.last_response = urlfetch.fetch(url = url,
                payload = data,
                method = method,
                headers = self._get_headers(self.cookie),
                allow_truncated = False,
                follow_redirects = False,
                deadline = 10
                )
            data = None # Next request will be a get, so no need to send the data again. 
            method = urlfetch.GET
            self.cookie.load(self.last_response.headers.get('set-cookie', '')) # Load the cookies from the response
            url = urljoin(base_url, self.last_response.headers.get('location'))
            if url == base_url:
                url = None
        return self.last_response

    def _get_headers(self, cookie):
        headers = {
            'Host' : '<ENTER HOST NAME HERE>',
            'User-Agent' : 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2 (.NET CLR 3.5.30729)',
            'Cookie' : self._make_cookie_header(cookie)
             }
        return headers

    def _make_cookie_header(self, cookie):
        cookie_header = ""
        for value in cookie.values():
            cookie_header += "%s=%s; " % (value.key, value.value)
        return cookie_header

    def get_cookie_header(self):
        return self._make_cookie_header(self.cookie)

您可以像使用 urllib2.urlopen 一样使用它,除了您使用的方法只是“打开”。

关于python - Mechanize 不适用于在 Google Appengine 中自动登录 gmail,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5633702/

相关文章:

Python数据框值插入到数据库表列

python - weasyprint 与 django 将数字渲染为图像

html - Gmail 正在删除我的 HTML 电子邮件模板中某些图像的 src 属性

python - 如何将项目输入 Google AppEngine 数据存储区?

android - 以对话框形式发送电子邮件 Intent

gmail - Google Drive使用Google Drive Viewer下载整个文件夹内容(Google Apps脚本)

python - 如何为变量设置动态值并将其用于机器人框架中的其他测试?

python - 由于 PySide2 和 Matplotlib,Travis-CI 无法构建

java - Google App Engine Query Execute 只接受 3 个参数

python - jinja2 的 autoescape 扩展和 markupsafe 库的区别