3

根据GAE 获取文档,cookie 不通过重定向处理:

重定向时不处理 Cookie。如果需要 cookie 处理,请将 follow_redirects 设置为 False 并手动处理 cookie 和重定向。

所以,我正在尝试实施手动解决方案:

page = urlfetch.Fetch(
    url = url,
    payload = form_data,
    method = urlfetch.POST,
    headers = headers,
    follow_redirects = False,
    deadline = 60)
cookies = ''
while page.status_code == 302:
    url = page.headers.get('location')
    if page.headers.get('set-cookie'):
        cookies = page.headers.get('set-cookie')
        headers['cookie'] = cookies
    page = urlfetch.Fetch(
        url = url,
        method = urlfetch.GET,
        headers = headers,
        follow_redirects = False,
        deadline = 60)
if page.status_code == 200 and page.content:
    self.response.out.write(page.content)

但它没有按预期工作。看起来我缺少一些 cookie

header_msg 包含响应标头的 httplib.HTTPMessage 实例。如果可能有多个具有相同名称的标头(例如 Set-Cookie 标头),请调用 header_msg.get_headers(header_name) 以将值作为列表检索。

但是我应该如何使用那个header_msg

4

1 回答 1

6

如果我理解这个问题,您想从每个响应中收集(并累积传递)cookie,但是带有 follow_redirects=True 的 URLFetch 仅返回来自最后一个响应的 cookie。此外,默认行为不会实现 cookie jar,这将导致后面的请求使用与先前响应Cookie中的 s 相对应的正确标头发送。Set-Cookie大概最初的 POST 是一个登录表单,它重定向到一个需要 cookie 的页面,这个方案不能满足这些限制。

为此,您的代码已关闭,但cookies = page.headers.get('set-cookie')会在每次请求后清除以前收集的 cookie。这应该会更好:

page = urlfetch.Fetch(
  url = url,
  headers = headers,
  follow_redirects = False)
cookies = []
while page.status_code == 302:
  url = page.headers.get('location')
  if page.headers.get('set-cookie'):
    cookies.extend(page.header_msg.getheaders('set-cookie'))
  headers['cookie'] = '; '.join(cookies)
  page = urlfetch.Fetch(
    url = url,
    method = urlfetch.GET,
    headers = headers,
    follow_redirects = False)
if page.status_code == 200 and page.content:
  self.response.out.write(page.content)

一些警告:

  • 如果Location是相对路径,则需要修复url.
  • 如果任何Set-Cookie标头不只是键=值(例如,它有一个过期),您需要解析标头值,以便您可以只发送键/值对。有关解析的帮助,请参阅Cookie库。
  • Set-Cookie如果针对特定键看到多个 cookie,则此代码将愉快地发送重复的 cookie 。
  • 如果重定向在一个单独的域上结束,这将错误地从原始域发送 cookie。这可能是一个安全问题。正确的 cookie jar 实现可以推断域和路径限制,以确定何时接受和发出 cookie。您可能想要合并cookielib.CookieJar库。如果您希望请求序列位于同一个域上,那么如果您检测到切换,则中止可能就足够了。
于 2012-10-18T00:06:17.770 回答