pythonでhttp/https通信を実現する方法のひとつである、pycurlの使い方をまとめました。
Table of Contents
1 pycurlとは
pythonからlibcurlを呼ぶインターフェースを提供するライブラリです。
curlコマンドと同様に、HTML取得等のhttp/https通信することができます。
2 HTMLボディを取得
curl.setopt(pycurl.[項目], [値])で各種パラメータを設定します。
リクエストヘッダのUser-Agentフィールドを適切に設定しないとアクセスを拒否されるサイトが多いので、pycurl.USERAGENTで設定しています(ブラウザ種別などの詳細な設定はUser-Agent一覧を記載したページを参照してください)。
pycurl.PROXYに設定する値は"192.168.0.1:80"の形式の文字列です。
レスポンスコードはcurl.getinfo(pycurl.HTTP_CODE)を呼ぶと、200、404、503等の整数値が返ってきます。
import pycurl k_curl_timeout = 6 # 6sec. k_curl_agent = 'Mozilla/5.0' def get_html_body(url, proxy=""): b = BytesIO() curl = pycurl.Curl() curl.setopt(pycurl.URL, url) curl.setopt(pycurl.TIMEOUT, k_curl_timeout) curl.setopt(pycurl.USERAGENT, k_curl_agent) curl.setopt(pycurl.WRITEFUNCTION, b.write) curl.setopt(pycurl.PROXY, proxy) try: curl.perform() http_code = curl.getinfo(pycurl.HTTP_CODE) if http_code == 200: retval = b.getvalue() else: retval = str(http_code) except Exception as e: retval = str(e) curl.close() return retval
なお、BytesIOのgetvalueメソッドで取得する値のデコードが必要になるかもしれません(windows-13jやcp932なページ)。
レスポンスのHTTPヘッダのcharsetを取得するか、以下の様なコードでgetvalueメソッドの戻り値をデコードすると良いでしょう。
k_charset = ['iso-8859-1', 'utf-8', 'shift-jis', 'euc-jp', 'cp932'] def decode(value): for charset in k_charset: try: decoded = value.decode(charset) return decoded except: pass return value
3 ファイルを取得
BytesIOのwriteメソッドではなく、ファイルオブジェクトのwriteメソッドをpycurl.WRITEFUNCTIONに設定します。
def get_file(url, name, proxy=""): with open(name, 'wb') as f: curl = pycurl.Curl() curl.setopt(pycurl.URL, url) curl.setopt(pycurl.TIMEOUT, k_curl_timeout) curl.setopt(pycurl.USERAGENT, k_curl_agent) curl.setopt(pycurl.WRITEFUNCTION, f.write) curl.setopt(pycurl.PROXY, proxy) try: curl.perform() http_code = curl.getinfo(pycurl.HTTP_CODE) if http_code == 200: retval = True else: retval = False except: retval = False curl.close() return retval
4 HTMLヘッダを取得
HTMLヘッダのみを取得する為にpycurl.HEADERとpycurl.NOBODYを1にします。
def get_html_header(url, proxy=""): b = BytesIO() curl = pycurl.Curl() curl.setopt(pycurl.URL, url) curl.setopt(pycurl.TIMEOUT, k_curl_timeout) curl.setopt(pycurl.USERAGENT, k_curl_agent) curl.setopt(pycurl.HEADER, 1) curl.setopt(pycurl.NOBODY, 1) curl.setopt(pycurl.WRITEFUNCTION, b.write) curl.setopt(pycurl.PROXY, proxy) try: curl.perform() http_code = curl.getinfo(pycurl.HTTP_CODE) if http_code == 200: retval = b.getvalue() else: retval = str(http_code) except Exception as e: retval = str(e) curl.close() return retval