web-dev-qa-db-ja.com

pythonリクエストモジュールを使用してプロキシ認証を渡す(ダイジェスト認証が必要)方法

しばらく前にMechanizeモジュールを使用していたのですが、今度はRequestsモジュールを使用してみます。
HTTPSおよびプロキシ認証が必要な場合、Python mechanizeは機能しません

インターネットにアクセスするとき、プロキシサーバーを経由する必要があります。
プロキシサーバーには認証が必要です。以下のコードを書きました。

import requests
from requests.auth import HTTPProxyAuth

proxies = {"http":"192.168.20.130:8080"}
auth = HTTPProxyAuth("username", "password")

r = requests.get("http://www.google.co.jp/", proxies=proxies, auth=auth)

上記のコードは、プロキシサーバーで基本認証が必要な場合に適切に機能します。
今、私はプロキシサーバーがダイジェスト認証を必要とするとき私がしなければならないことを知りたいです。
HTTPProxyAuthはダイジェスト認証では効果がないようです(r.status_codeは407を返します)。

17
yutaka2487

(ダイジェスト認証に基づく)プロキシ認証で使用できるクラスを作成しました。
requests.auth.HTTPDigestAuthからほぼすべてのコードを借用しました。

import requests
import requests.auth

class HTTPProxyDigestAuth(requests.auth.HTTPDigestAuth):
    def handle_407(self, r):
        """Takes the given response and tries digest-auth, if needed."""

        num_407_calls = r.request.hooks['response'].count(self.handle_407)

        s_auth = r.headers.get('Proxy-authenticate', '')

        if 'digest' in s_auth.lower() and num_407_calls < 2:

            self.chal = requests.auth.parse_dict_header(s_auth.replace('Digest ', ''))

            # Consume content and release the original connection
            # to allow our new request to reuse the same one.
            r.content
            r.raw.release_conn()

            r.request.headers['Authorization'] = self.build_digest_header(r.request.method, r.request.url)
            r.request.send(anyway=True)
            _r = r.request.response
            _r.history.append(r)

            return _r

        return r

    def __call__(self, r):
        if self.last_nonce:
            r.headers['Proxy-Authorization'] = self.build_digest_header(r.method, r.url)
        r.register_hook('response', self.handle_407)
        return r

使用法:

proxies = {
    "http" :"192.168.20.130:8080",
    "https":"192.168.20.130:8080",
}
auth = HTTPProxyDigestAuth("username", "password")

# HTTP
r = requests.get("http://www.google.co.jp/", proxies=proxies, auth=auth)
r.status_code # 200 OK

# HTTPS
r = requests.get("https://www.google.co.jp/", proxies=proxies, auth=auth)
r.status_code # 200 OK
10
yutaka2487

独自に実装する必要はありません!ほとんどの場合

リクエストには、基本認証のためのプロキシのサポートが組み込まれています。

proxies = { 'https' : 'https://user:password@proxyip:port' } 
r = requests.get('https://url', proxies=proxies) 

docs の詳細をご覧ください

または、ダイジェスト認証が必要な場合は、HTTPDigestAuthが役立ちます。
または、yutaka2487が怒鳴ったように、拡張する必要があるかもしれません。

注:名前ではなくプロキシサーバーのIPを使用する必要があります!

17
eusoubrasileiro
import requests
import os


# in my case I had to add my local domain
proxies = {
  'http': 'proxy.myagency.com:8080',
  'https': 'user@localdomain:[email protected]:8080',
}


r=requests.get('https://api.github.com/events', proxies=proxies)
print(r.text)
1
Odysseus Ithaca

まだここに残っている皆さんのために、requests-toolbeltと呼ばれるプロジェクトがあるようです。これには、これに加えて、リクエストの一般的な機能が組み込まれていません。

https://toolbelt.readthedocs.org/en/latest/authentication.html#httpproxydigestauth

1
pcreech

requests.auth.HTTPDigestAuthの代わりにrequests.auth.HTTPProxyAuthを使用して、ダイジェスト認証を使用できます。

0
barracel

これは、http基本認証ではない回答です。たとえば、組織内の透過プロキシなどです。

import requests

url      = 'https://someaddress-behindproxy.com'
params   = {'apikey': '123456789'}                     #if you need params
proxies  = {'https': 'https://proxyaddress.com:3128'}  #or some other port
response = requests.get(url, proxies=proxies, params=params)

これが誰かのお役に立てば幸いです。

0
Belial

私はPythonモジュール(利用可能 ここ )と記述しました。これにより、ダイジェストスキームを使用してHTTPプロキシで認証できるようになります。HTTPSWebサイトに接続すると機能します(モンキーパッチを介して)、Webサイトでも認証できるようにします。これは、最新のrequestsライブラリでPython 2と3の両方で動作するはずです。

次の例は、ユーザー名1.2.3.4:8080とパスワードuser1を使用したHTTPダイジェスト認証を必要とするHTTPプロキシpassword1を介して、ウェブページ https://httpbin.org/ip をフェッチします。 :

import requests
from requests_digest_proxy import HTTPProxyDigestAuth

s = requests.Session()
s.proxies = {
        'http': 'http://1.2.3.4:8080/',
        'https': 'http://1.2.3.4:8080/'
}
s.auth = HTTPProxyDigestAuth(('user1', 'password1'))

print(s.get('https://httpbin.org/ip').text)

Webサイトが何らかのHTTP認証を必要とする場合、これをHTTPProxyDigestAuthコンストラクターに次のように指定できます。

# HTTP Basic authentication for website
s.auth = HTTPProxyDigestAuth(('user1', 'password1'),
        auth=requests.auth.HTTPBasicAuth('user1', 'password0'))
print(s.get('https://httpbin.org/basic-auth/user1/password0').text))

# HTTP Digest authentication for website
s.auth = HTTPProxyDigestAuth(('user1', 'password1'),,
        auth=requests.auth.HTTPDigestAuth('user1', 'password0'))
print(s.get('https://httpbin.org/digest-auth/auth/user1/password0').text)
0
Tey'