2016年04月25日

pythonのrequestsでリトライとプロキシを設定

requestsを使ってAPIからデータ取ろうと思った時に調べたこと。

まずはリトライ設定をしつつAPIの内容をローカルファイルにダウンロードする処理。リトライについてはAdapterを使うらしい。下記を参考にした。

http://www.mobify.com/blog/http-requests-are-hard/

ダウンロードする方法として、下記Stackoverflowのページを参考にした。requests.getにstream=Trueを設定することでファイルサイズが大きくてもメモリサイズを食わずにダウンロードできる。

http://stackoverflow.com/questions/16694907/how-to-download-large-file-in-python-with-requests-py

import requests

def download(url, output_path, retry=1):
    # retry設定
    session = requests.Session()
    session.mount("http://", requests.adapters.HTTPAdapter(max_retries=retry))
    session.mount("https://", requests.adapters.HTTPAdapter(max_retries=retry))

    # connect timeoutを10秒, read timeoutを30秒に設定
    response = session.get(url=url, stream=True, timeout=(10.0, 30.0))

    # 404等のhttp status errorの場合はraise
    response.raise_for_status()

    # ファイル出力
    with open(output_path, 'wb') as f:
        for chunk in response.iter_content(chunk_size=1024): 
            if chunk:
                f.write(chunk)

# 呼び出してみる
download('http://www.mwsoft.jp/', 'foo.html', retry=2)

上記のような書き方でだいたいの用は済ませられそう。

次にプロキシの設定。

公式のドキュメントによると、おとなしく実行前にexportしておいても良いよと書いてあった。

$ export HTTP_PROXY="http://proxy_host:8080"
$ export HTTPS_PROXY="http://proxy_host:8080"

request.getの際に渡すことも可能。

proxies = {
  'http': 'http://proxy_host:8080',
  'https': 'http://proxy_host:8080',
}
requests.get('http://www.mwsoft.jp/', proxies=proxies)

socksプロキシを通す場合はPySocksを使うといいとStackoverflowに書いてあった。

pip3 install PySocks
import socks
import socket
import requests

socks.set_default_proxy(socks.SOCKS5, "localhost", 1080)
socket.socket = socks.socksocket
requests.get('http://www.mwsoft.jp/')