ken0zero/japanese-proxy
0
1from flask import Flask, jsonify, request2from playwright.sync_api import sync_playwright3from urllib.parse import urlparse4import logging5import time6import requests7from bs4 import BeautifulSoup8import random9 10app = Flask(__name__)11 12# ログ設定13logging.basicConfig(level=logging.INFO)14logger = logging.getLogger(__name__)15 16FREE_PROXY_LIST_URL = "https://www.cybersyndrome.net/search.cgi?q=JP" # プロキシリストの取得元URL17proxies = [] # グローバルなプロキシリスト18 19def fetch_proxies():20 """プロキシリストをウェブページから取得して解析する"""21 global proxies22 try:23 with sync_playwright() as p:24 browser = p.chromium.launch(headless=True)25 page = browser.new_page()26 page.goto(FREE_PROXY_LIST_URL)27 time.sleep(5) # JavaScriptの実行を待つために5秒待機28 page_source = page.content()29 soup = BeautifulSoup(page_source, "html.parser")30 proxy_table = soup.find("table", {"border": "1", "cellspacing": "0", "cellpadding": "3"})31 if not proxy_table:32 raise ValueError("No proxy table found in the HTML.")33 proxy_cells = proxy_table.find_all("td", id=lambda x: x and x.startswith("n"))34 if not proxy_cells:35 raise ValueError("No proxy cells found in the HTML.")36 proxies = [cell.text.strip() for cell in proxy_cells]37 logger.info(f"Fetched proxies: {proxies}") # 取得したプロキシをログに出力38 browser.close()39 except Exception as e:40 logger.error(f"Error fetching proxy list: {e}") # エラーログを出力41 raise RuntimeError(f"Error fetching proxy list: {e}")42 43def is_valid_proxy(proxy):44 """プロキシURLの妥当性を検証する"""45 try:46 result = urlparse(f"http://{proxy}") # プロトコルを付加して解析47 return all([result.scheme, result.netloc])48 except Exception:49 return False50 51def ensure_http_scheme(url):52 """URLにスキーマを追加する"""53 if not urlparse(url).scheme:54 return f"http://{url}"55 return url56 57def test_proxy(proxy):58 """指定されたプロキシが有効かどうかをテストする"""59 proxies_dict = {60 "http": f"http://{proxy}",61 "https": f"http://{proxy}",62 }63 try:64 # タイムアウトを設定65 response = requests.get("http://httpbin.org/ip", proxies=proxies_dict, timeout=5)66 return response.ok67 except requests.exceptions.ProxyError as e:68 logger.error(f"Proxy {proxy} failed: {e}")69 return False70 except requests.exceptions.SSLError as e:71 logger.error(f"SSL Error with proxy {proxy}: {e}")72 return False73 except Exception as e:74 logger.error(f"Proxy {proxy} failed: {e}")75 return False76 77@app.route("/")78def index():79 """プロキシリストを取得して有効なものを返す"""80 try:81 fetch_proxies() # プロキシリストを取得82 valid_proxies = [proxy for proxy in proxies if is_valid_proxy(proxy) and test_proxy(proxy)]83 if not valid_proxies:84 return jsonify({"error": "No valid proxies found."}), 50085 return jsonify({"valid_proxies": valid_proxies})86 except Exception as e:87 logger.error(f"Error in index route: {e}") # エラーログを出力88 return jsonify({"error": str(e)}), 50089 90@app.route("/proxy", methods=["GET", "POST"])91def proxy():92 """プロキシを使用して指定されたURLにGETまたはPOSTリクエストを送信する"""93 94 # プロキシリストが空なら取得95 if not proxies:96 fetch_proxies() 97 98 valid_proxies = [proxy for proxy in proxies if is_valid_proxy(proxy)]99 if not valid_proxies:100 return jsonify({"error": "No valid proxies found."}), 500101 102 if request.method == "GET":103 url = request.args.get("url")104 if not url:105 return jsonify({"error": "URL is required."}), 400106 107 url = ensure_http_scheme(url) # スキーマを追加108 109 # 有効なプロキシからランダムに選択110 for proxy in random.sample(valid_proxies, len(valid_proxies)):111 proxy_dict = {112 "http": f"http://{proxy}",113 "https": f"http://{proxy}",114 }115 116 try:117 response = requests.get(url, proxies=proxy_dict, timeout=5)118 return (response.content, response.status_code, response.headers.items())119 except Exception as e:120 logger.error(f"Error fetching {url} through proxy {proxy}: {e}")121 122 return jsonify({"error": "All proxies failed."}), 500123 124 elif request.method == "POST":125 url = request.json.get("url")126 data = request.json.get("data")127 if not url:128 return jsonify({"error": "URL is required."}), 400129 130 url = ensure_http_scheme(url) # スキーマを追加131 132 # 有効なプロキシからランダムに選択133 for proxy in random.sample(valid_proxies, len(valid_proxies)):134 proxy_dict = {135 "http": f"http://{proxy}",136 "https": f"http://{proxy}",137 }138 139 try:140 response = requests.post(url, json=data, proxies=proxy_dict, timeout=5)141 return (response.content, response.status_code, response.headers.items())142 except Exception as e:143 logger.error(f"Error posting to {url} through proxy {proxy}: {e}")144 145 return jsonify({"error": "All proxies failed."}), 500146 147if __name__ == "__main__":148 app.run(host="0.0.0.0", port=7860)149 