1

POST リクエストから Cookie を取得しようとしています。以前は urllib2 を使用していましたが、それでも問題なく動作しますが、より明確なライブラリ python-requests に切り替えたいと考えていました。残念ながら、ページにエラーが表示されます。

リクエストは HTTPS であるため、それらをスニッフィングして違いを見つけることはできません。

urllib2 コード:

NINTENDO_LOGIN_PAGE = "https://id.nintendo.net/oauth/authorize/"
MIIVERSE_CALLBACK_URL = "https://miiverse.nintendo.net/auth/callback"
parameters = {'client_id': 'ead88d8d450f40ada5682060a8885ec0',
              'response_type': 'code',
              'redirect_uri': MIIVERSE_CALLBACK_URL,
              'username': MIIVERSE_USERNAME,
              'password': miiverse_password}

data = urlencode(parameters)
self.logger.debug(data)
req = urllib2.Request(NINTENDO_LOGIN_PAGE, data)
page = urllib2.urlopen(req).read()
self.logger.debug(page)

結果 (良い):

[...]
<div id="main-body">
    <div id="try-miiverse">
        <p class="try-miiverse-catch">A glimpse at some of the posts that are currently popular on Miiverse.</p>
        <h2 class="headline">Miiverse Sampler</h2>
        <div id="slide-post-container" class="list post-list">
        [...]

リクエストコード:

req = requests.post(NINTENDO_LOGIN_PAGE, data=parameters)
self.logger.debug(req.text)

結果 (悪い):

[...]
<div id="main-body">
    <h2 class="headline">Activity Feed</h2>

    <div class="activity-feed content-loading-window">
        <div>
            <img src="https://d13ph7xrk1ee39.cloudfront.net/img/loading-image-green.gif" alt=""></img>
            <p class="tleft"><span>Loading activity feed...</span></p>
        </div>
    </div>
    <div class="activity-feed content-load-error-window none"><div>
    <p>The activity feed could not be loaded. Check your Internet connection, wait a moment and then try reloading.</p>
    <div class="buttons-content"><a href="/" class="button">Reload</a></div>
    </div>
</div>
[...]

これを解決するためのヒントを事前にありがとう。

更新 1:ご回答いただきありがとうございます。

@abarnert の提案に従って、リダイレクトを確認しました。

resp = urllib2.urlopen(req)
print(resp.geturl()) # https://miiverse.nintendo.net/

req = requests.post(NINTENDO_LOGIN_PAGE, data=parameters)
print(req.url) # https://miiverse.nintendo.net/
print(req.history) # (<Response [303]>, <Response [302]>)

どちらもリダイレクトに従ったようですが、最終的に同じ場所にたどり着きました。

@sigmavirus24、とても便利なウェブサイトです。発見させてくれてありがとう。結果は次のとおりです (簡単に比較できるようにパラメーターの順序を編集しました)。

URLlib2:

{
  "args": {},
  "data": "",
  "files": {},
  "form": {
    "client_id": "ead88d8d450f40ada5682060a8885ec0",
    "response_type": "code",
    "redirect_uri": "https://miiverse.nintendo.net/auth/callback",
    "username": "Wiwiweb",
    "password": "password"
  },
  "headers": {
    "Accept-Encoding": "identity",
    "Connection": "close",
    "Content-Length": "170",
    "Content-Type": "application/x-www-form-urlencoded",
    "Host": "httpbin.org",
    "User-Agent": "Python-urllib/2.7"
  },
  "json": null,      
  "origin": "24.85.129.188",
  "url": "http://httpbin.org/post"
}

リクエスト:

{
  "args": {},
  "data": "",
  "files": {},
  "form": {
    "client_id": "ead88d8d450f40ada5682060a8885ec0",
    "response_type": "code",
    "redirect_uri": "https://miiverse.nintendo.net/auth/callback",
    "username": "Wiwiweb",
    "password": "password"
  },
  "headers": {
    "Accept": "*/*",
    "Accept-Encoding": "gzip, deflate, compress",
    "Connection": "close",
    "Content-Length": "170",
    "Content-Type": "application/x-www-form-urlencoded"
    "Host": "httpbin.org",
    "User-Agent": "python-requests/1.2.3 CPython/2.7.5 Windows/7"
  },
  "json": null,
  "origin": "24.85.129.188"
  "url": "http://httpbin.org/post",
}

一部のヘッダーが若干異なるようです。他に考えがないので、urllib2 ヘッダーを完全にコピーしてみることもできます。ユーザーエージェントのなりすましかもしれません。

更新 2:これらのヘッダーを「リクエスト」リクエストに追加しました。

headers = {'User-Agent': 'Python-urllib/2.7',
           'Accept-Encoding': 'identity'}

私はまだ同じ結果を得ています...現在のリクエストの唯一の違いは、「リクエスト」に追加のヘッダーがあることです: "Accept": "*/*". これが問題なのかわかりません。

リダイレクトから来ているのでしょうか?

4

1 に答える 1

0

さて、リダイレクトが異なる「理由」を完全に解決することはできませんでしたが、リクエストを使用して Cookie を取得する場所を見つけました。

2 つのライブラリの違いは、リダイレクトの処理方法に関係があると考えました。そこで、両方のリクエストの履歴を確認しました。「リクエスト」の場合は と同じくらい簡単req.historyですが、urllib2 の場合は、次のコードを使用しました。

class MyHTTPRedirectHandler(urllib2.HTTPRedirectHandler):
    def http_error_302(self, req, fp, code, msg, headers):
        print("New request:")
        print(headers)
        return urllib2.HTTPRedirectHandler.http_error_302(self, req, fp, code, msg, headers)

opener = urllib2.build_opener(MyHTTPRedirectHandler, urllib2.HTTPCookieProcessor())
urllib2.install_opener(opener)

履歴を確認すると、最初のリダイレクト時に「リクエスト」リクエストに「set-cookie」ヘッダーが含まれていることがわかりました (つまり、3 つのうち 2 番目のリクエスト)。私はそれをどこで手に入れることができるかを知っているので、それで十分です:req.history[1].cookies['ms']

興味深いことに、urllib2 リクエストに追加したビットのせいで、「requests」リクエストと同じものが返され始めました! それに変更しても:

class MyHTTPRedirectHandler(urllib2.HTTPRedirectHandler):
    pass

opener = urllib2.build_opener(MyHTTPRedirectHandler, urllib2.HTTPCookieProcessor())
urllib2.install_opener(opener)

ずっと返された同じ「リクエスト」への応答を完全に変更するのに十分です(質問で「悪い」とマークしたそのビット)。

私は困惑していますが、クッキーがどこにあるかを知っていれば十分です。たぶん、好奇心旺盛で退屈している人は、原因を見つけようとすることに興味を持つでしょう.

ご協力ありがとうございました:)

于 2013-09-13T19:43:31.167 に答える