Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Mechanize无法在Google Appengine中自动登录gmail_Python_Google App Engine_Gmail_Mechanize - Fatal编程技术网

Python Mechanize无法在Google Appengine中自动登录gmail

Python Mechanize无法在Google Appengine中自动登录gmail,python,google-app-engine,gmail,mechanize,Python,Google App Engine,Gmail,Mechanize,我使用了mechanize,并在GAE上部署了一个应用程序,效果很好。但是,对于我正在制作的应用程序,我正试图通过mechanize自动登录gmail。它在本地计算机上的开发环境中以及在appengine上部署后都不起作用 我已经能够使用相同的脚本,通过使用PSP的mod_python在我的服务器上运行它 我在这里找到了很多解决方案,但似乎没有一个适合我。以下是我的代码片段: <snip> br = mechanize.Browser() response = br.open("ht

我使用了mechanize,并在GAE上部署了一个应用程序,效果很好。但是,对于我正在制作的应用程序,我正试图通过mechanize自动登录gmail。它在本地计算机上的开发环境中以及在appengine上部署后都不起作用

我已经能够使用相同的脚本,通过使用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>

br=mechanize.Browser()
响应=br.打开(“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.打开(“http://mail.google.com/mail/h/")
结果=response2.read()

当我查看结果时,得到的只是与appengine一起使用时的登录页面。但是,由于mod_python托管在我自己的服务器上,我从用户的收件箱中获取页面。

问题很可能是由于谷歌如何破坏了GAE上的urllib2模块

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

有一种方法可以解决这个问题,但不能使用mechanize。你必须使用自己的Cookie处理器-以下是我采用的基本方法(虽然不完美,但它可以完成任务):

导入urllib、urllib2、Cookie
从google.appengine.api导入urlfetch
从urlparse导入urljoin
导入日志记录
类GAEOpener(对象):
定义初始化(自):
self.cookie=cookie.SimpleCookie()
self.last_响应=无
def open(自身、url、数据=无):
基本url=url
如果数据为无:
method=urlfetch.GET
其他:
方法=urlfetch.POST
虽然url不是“无”:
self.last_response=urlfetch.fetch(url=url,
有效载荷=数据,
方法=方法,
headers=self.\u获取\u头(self.cookie),
allow_truncated=False,
follow_redirects=False,
截止日期=10
)
data=None#下一个请求将是get,因此无需再次发送数据。
method=urlfetch.GET
self.cookie.load(self.last_response.headers.get('set-cookie','')#从响应中加载cookie
url=urljoin(基本url,self.last\u response.headers.get('location'))
如果url==基本url:
url=无
返回self.last\u响应
def_get_头(self,cookie):
标题={
“主持人”:“,
“用户代理”:“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”:自我制作Cookie头(Cookie)
}
返回标题
def_make_cookie_头(self,cookie):
cookie_header=“”
对于cookie.values()中的值:
cookie_头+=%s=%s;“%(value.key,value.value)
返回cookie\u头
def get_cookie_标头(自身):
返回self.\u生成\u cookie\u头(self.cookie)

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

为什么你要尝试从应用程序引擎应用程序自动登录到gmail?你是否知道这明显违反了GMail的服务条款,而且几乎肯定有更好的方式来做你想做的事情?我想从不允许登录谷歌账户的网络上访问我的邮件。所以,我认为刮擦是一个很好的解决办法。你能建议一些更好的方法吗?怎么样?那么,如果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)