今回はPythonとはまた違った件かもしれないが、備忘録として残しておく。
目的
urllib.requestはプロキシを使用してリクエストを投げることができるが、そのテストをしようとしてもプロキシサーバを所持していなかった。
ので、無料のプロキシを利用してテストすることにした。
まずは使用できる無料プロキシ(Free Proxy List)を引っこ抜いてくるプログラムを作る。
注意
無料プロキシは基本的に
リクエストの内容は全て盗まれている
と考えたほうが良い。
無料プロキシを使って何かにログインしたり、個人情報を入力したりしてPOSTするとそれは流出すると思ってもらってよい。
ので、こういったフリープロキシを使用する際は単純なGET(WEBスクレイピングとか)で使用するか、盗まれても良い検証用のリクエストを投げるときに利用するように。
手段
無料のプロキシリストを管理するサイトは複数存在するが、今回は
https://www.proxyscan.io
を使用させていただく。
このサイト、無料プロキシデータを管理するサイトには珍しく、APIが用意されており、
簡単にjson形式でプロキシサーバの情報を取得することができる。
例
https://www.proxyscan.io/api/proxy?last_check=9800&uptime=50&ping=500&limit=10&type=https
みたいなリクエストをGETで投げると、
- 最終チェック:9800秒前まで
- uptime:50%以上
- ping:500ms以下
- プロトコル:https
- 最大10件取得
でjson形式のプロキシデータが返ってくる。
コード
実際に書いてみた
# coding:utf-8
#==========================
# インポートモジュール
#==========================
import urllib.request
import json
import socket
import time
import sys
#==========================
# グローバル変数
#==========================
args = sys.argv
PROXY_LIST_URL = 'https://www.proxyscan.io/api/proxy'
#==========================
# 関数
#==========================
## プロキシリストをJSON形式で取得する
# (ex)https://www.proxyscan.io/api/proxy?last_check=9800&uptime=50&ping=500&limit=10&type=https
def getProxyJson(_type):
# 引数が正しいかどうかのチェック
if _type != 'http' and _type != 'https':
print('Args Error.')
return []
apiUrl = PROXY_LIST_URL + '?last_check=3600&uptime=75&limit=10&type=' + _type + '&ping='
# ping を段階的に上げていく。もし1つでも返ったらbreak
for i in range(4):
pingCount = str((i + 1) * 300)
reqApi = apiUrl + pingCount
with urllib.request.urlopen(reqApi) as res:
j = res.read().decode('utf-8')
resJson = json.loads(j)
if len(resJson) != 0:
return resJson
else:
print('Pxy is Null.')
continue
time.sleep(10)
# あんまり連続でアクセスすると攻撃っぽくなるのでSleep処理
## プロキシが正常に使用できるかをチェックする
def checkServerPort(_ip, _port):
ipAddr = _ip
port = _port
print('Port Check pxy... [IPADDR]' + ipAddr + ' [PORT]' + str(port))
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(10) # タイムアウトの指定
return_code = sock.connect_ex((ipAddr, port))
sock.close()
# もしきちんと空いているならTrueを返す
if return_code == 0:
print('[OK]', ipAddr + ':' + str(port))
return True
else:
print('[NG]', ipAddr + ':' + str(port))
return False
## プロキシリストを返却する
#PROXIES = {
# 'http': 'http://100.0.0.1:80',
# 'https': 'https://100.0.0.2:3128'
#} って言う感じの辞書型
def getProxyList():
resProxies = {}
httpJsons = getProxyJson('http')
for httpjs in httpJsons:
ipAddr = httpjs['Ip']
port = httpjs['Port']
# もしきちんと空いているなら辞書型変数に追加
if checkServerPort(ipAddr, port):
resProxies['http'] = 'http://' + ipAddr + ':' + str(port)
break
httpsJsons = getProxyJson('https')
for httpsjs in httpsJsons:
ipAddr = httpsjs['Ip']
port = httpsjs['Port']
# もしきちんと空いているなら辞書型変数に追加
if checkServerPort(ipAddr, port):
resProxies['https'] = 'https://' + ipAddr + ':' + str(port)
break
return resProxies
#==========================
# MAIN関数
#==========================
def main():
print(" ---- Exec " + args[0] + " python program ---- ")
print(getProxyList())
if __name__ == "__main__":
main()
流れ的には
- APIを叩いてjsonを取得
- jsonに記載のあるプロキシサーバが使用できる状態かどうかをポートチェック
- 実際にurllib.requestで使用できるような辞書型変数として返す
って感じ。
最終的なアウトプットがhttpとhttpsそれぞれ1つずつにしているので、そのあたりは改良の余地があるかもしれない。
というか、jsonで取れるからあとはどうとでもなる
最後に
もう1回注意しておくが、無料プロキシは非常に危険な存在であることを留意して使用すること。
これによって個人情報を抜かれて被害を被っても責任はとれないので注意。
コメント