7
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Pythonでプロキシ設定取得あれこれ(Windows)

7
Last updated at Posted at 2019-09-25

注意 : 本記事はWindows向けです。

プロキシ設定は面倒

こんにちは、キャベツレタスです。
突然ですが、皆さんはプロキシに対してどういった印象をお持ちですか?
ちなみに僕は「嫌い」です。
プロキシに対する不満を全て書けるほど人間の寿命は長くないので割愛しますが、要約すると、

  • プロキシ設定がめんどくさい(いちいちコマンドに --proxy とつけるのが面倒)
  • プロキシ設定のあるアプリ・ソフトウェアが少ない(スマホ版LINE等プロキシ非対応のものが多い)
  • 仮にプロキシ設定ができても訳わかめなエラーを吐く(npm,apt等)

です。
こんなプロキシ設定ですが、システムからプロキシ設定を取得する方法は色々あります。
以下、例を示していきたいと思います。

プロキシ設定の取得

以下の例では、プロキシの形式を

global_proxy = {
    "http": "http://host:port/",
    "https": "https://host:port/",
}

とします。
requestsモジュールで使える形式にしました。

コマンドライン引数から取得

恐らく最もポピュラーだと思われます。
コンソールアプリを作るなら必須とも言えます。
sys.argv を使ってコマンドライン引数を取得します。

if "--proxy" in argv:
    try:
        p = argv[argv.index("--proxy") + 1]
        global_proxy = {
            "http": p,
            "https": p
        }
    except IndexError:
        print("警告: \"--proxy\"オプションが指定されましたが、アドレスが指定されなかったため"
            "プロキシを無効にしました。")
else:
    global_proxy = None

環境変数から取得

環境変数を取得する方法はいくつかありますが、今回は os.environ を使います。

if "http_proxy" in [x.lower() for x in list(environ.keys())] or "https_proxy" in [x.lower() for x in list(environ.keys())]:
    global_proxy = {
        "http": environ["http_proxy"].replace("http://", "").replace("/", "")
    }
    if "https_proxy" in [x.lower() for x in list(environ.keys())]:
        global_proxy["https"] = environ["https_proxy"].replace("https://", "").replace("/", "")
    else:
        global_proxy["https"] = environ["http_proxy"].replace("https://", "").replace("/", "")
else:
    global_proxy = None

requestsモジュールではプロキシに http:/// が入っているとエラーを吐くので、 .replace("http://", "").replace("/", "") を使って取り除きます。

「設定」アプリ(レジストリ)から取得

「設定」アプリで変更されたプロキシ設定はレジストリに記録されます。
winregモジュールを使って、その設定を取り出しましょう。

import winreg
path = r"Software\Microsoft\Windows\CurrentVersion\Internet Settings"
key = winreg.OpenKeyEx(winreg.HKEY_CURRENT_USER, path)
p, regtype = winreg.QueryValueEx(key, 'ProxyServer')
e, regtype = winreg.QueryValueEx(key, 'ProxyEnable')
try:
    s, regtype = winreg.QueryValueEx(key, 'AutoConfigURL')
except FileNotFoundError:
    s = None
e = bool(e)
winreg.CloseKey(key)
if bool(e):
    global_proxy = {
        "http": p,
        "https": p
    }
elif s is not None:
    global_proxy = {
        "http": s,
        "https": s
    }
else:
    global_proxy = None

まとめました

上の3つをまとめたGistを公開しました。
Windowsのプロキシ設定を取得する関数
実行すると、返り値としてrequests形式のプロキシを返します。

最後に

今回この記事を書いて、意外とプロキシ設定の取得方法があることに少し驚きました。
今後は、

  • プロキシ設定の自動構成スクリプト( *.pac )の解析方法
  • インターネットオプションのプロキシ設定(下記)
    proxy.PNG

等、調べていけたらと思っています。
上記設定をPythonで取得する方法をご存じの方いらっしゃいましたら、コメント欄の方で教えていただけたら幸いです。

追記

2019/12/02

プロキシ設定の自動構成スクリプト( *.pac )は、こちらの記事を参考に、以下のようにしました。

global_proxy = {
    "http":"http://proxypachost/proxy.pac",
    "https":"http://proxypachost/proxy.pac"
}

また、インターネットオプションのプロキシ設定は設定アプリ(レジストリ)と連携しているので不要です。

7
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?