簡體   English   中英

從urllib2切換到請求,具有相同參數的結果卻奇怪地不同

[英]Switching from urllib2 to requests, strangely different results with the same parameters

我正在嘗試從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": "*/*" 我不確定這是問題所在。

可能來自重定向嗎?

好吧,我並沒有完全解決“為什么”重定向不同的問題,但是我發現了使用請求從哪里獲取我的cookie。

我發現這兩個庫之間的差異與它們處理重定向的方式有關。 因此,我檢查了兩個請求的歷史記錄。 對於“請求”,就像執行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”標頭(因此,第二個請求中有三個),但在最后沒有。 這對我來說已經足夠了,因為我知道現在從哪里獲得: req.history[1].cookies['ms']

奇怪的是,由於我添加到urllib2請求中,因此它開始返回與“請求”請求相同的內容! 甚至將其更改為:

class MyHTTPRedirectHandler(urllib2.HTTPRedirectHandler):
    pass

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

足以使其完全改變其對始終返回的“請求”的響應(這一點我在問題中被標記為“不好”)。

我很困惑,但是知道在哪里可以找到Cookie對我來說已經足夠了。 也許好奇和無聊的人會對嘗試找到原因感興趣。

謝謝大家的幫助 :)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM