#!/usr/bin/env python3
"""
免费代理一键获取和使用脚本
功能：自动获取、验证免费代理，并提供使用示例
"""

import requests
import time
import threading
from concurrent.futures import ThreadPoolExecutor
import json
import os
from fp.fp import FreeProxy

class FreeProxyManager:
    def __init__(self):
        self.working_proxies = []
        self.test_urls = [
            'http://httpbin.org/ip',
            'https://httpbin.org/ip',
            'http://www.google.com',
            'https://www.baidu.com'
        ]
        self.timeout = 8
        self.max_workers = 20
        
    def get_proxy_list(self, count=20):
        """获取代理列表"""
        print("🔍 正在获取免费代理列表...")
        proxies = []
        
        try:
            # 方法1: 使用free-proxy库
            proxy_generator = FreeProxy(rand=True, anonym=True, timeout=1).get_proxy_list()
            for proxy in proxy_generator:
                if len(proxies) >= count * 2:  # 获取双倍数量用于筛选
                    break
                proxies.append(proxy)
                print(f"  找到代理: {proxy}")
        except Exception as e:
            print(f"⚠️  使用free-proxy库时出错: {e}")
        
        # 如果没有获取到足够代理，尝试备用方法
        if len(proxies) < count:
            try:
                # 方法2: 从公开API获取
                backup_proxies = self.get_backup_proxies()
                proxies.extend(backup_proxies)
            except Exception as e:
                print(f"⚠️  获取备用代理时出错: {e}")
        
        return list(set(proxies))[:count]  # 去重并限制数量
    
    def get_backup_proxies(self):
        """备用方法获取代理"""
        backup_proxies = []
        try:
            # 从公开代理API获取
            response = requests.get('https://www.proxy-list.download/api/v1/get?type=http', timeout=10)
            if response.status_code == 200:
                lines = response.text.strip().split('\n')
                backup_proxies = [f"http://{line}" for line in lines if ':' in line]
        except:
            pass
            
        return backup_proxies
    
    def test_single_proxy(self, proxy):
        """测试单个代理的可用性"""
        test_results = []
        
        for test_url in self.test_urls[:2]:  # 只测试前两个URL提高效率
            try:
                start_time = time.time()
                response = requests.get(
                    test_url,
                    proxies={'http': proxy, 'https': proxy},
                    timeout=self.timeout,
                    verify=False
                )
                response_time = round((time.time() - start_time) * 1000, 2)
                
                if response.status_code == 200:
                    test_results.append({
                        'url': test_url,
                        'response_time': response_time,
                        'working': True
                    })
                    break  # 只要有一个测试通过就认为代理可用
            except:
                continue
        
        return proxy, test_results
    
    def validate_proxies(self, proxies):
        """验证代理列表"""
        print("🔧 正在验证代理可用性...")
        working_proxies = []
        
        with ThreadPoolExecutor(max_workers=self.max_workers) as executor:
            results = executor.map(self.test_single_proxy, proxies)
            
            for proxy, test_results in results:
                if test_results and any(result['working'] for result in test_results):
                    avg_time = sum(result['response_time'] for result in test_results) / len(test_results)
                    working_proxies.append({
                        'proxy': proxy,
                        'response_time': avg_time,
                        'test_count': len(test_results)
                    })
                    print(f"  ✅ 代理可用: {proxy} (响应时间: {avg_time}ms)")
        
        # 按响应时间排序
        working_proxies.sort(key=lambda x: x['response_time'])
        return working_proxies
    
    def save_proxies_to_file(self, proxies, filename="working_proxies.json"):
        """保存可用代理到文件"""
        with open(filename, 'w', encoding='utf-8') as f:
            json.dump(proxies, f, indent=2, ensure_ascii=False)
        print(f"💾 可用代理已保存到: {filename}")
    
    def load_proxies_from_file(self, filename="working_proxies.json"):
        """从文件加载代理"""
        if os.path.exists(filename):
            with open(filename, 'r', encoding='utf-8') as f:
                return json.load(f)
        return []
    
    def show_usage_examples(self, best_proxy):
        """显示使用示例"""
        print("\n" + "="*50)
        print("🚀 使用示例")
        print("="*50)
        
        print(f"\n最佳代理: {best_proxy}")
        
        print("\n1. 在Python requests中使用:")
        print(f"""
import requests

proxies = {{
    'http': '{best_proxy}',
    'https': '{best_proxy}'
}}

try:
    response = requests.get('http://httpbin.org/ip', proxies=proxies, timeout=10)
    print(response.json())
except Exception as e:
    print(f"请求失败: {{e}}")
        """)
        
        print("\n2. 在命令行中使用 (curl):")
        print(f"curl -x {best_proxy} http://httpbin.org/ip")
        
        print("\n3. 设置环境变量:")
        print(f"export HTTP_PROXY={best_proxy}")
        print(f"export HTTPS_PROXY={best_proxy}")
        
        print("\n4. 批量测试网站:")
        print(f"""
测试网站列表:
  http://httpbin.org/ip
  https://api.ipify.org?format=json
  http://www.google.com (如可访问)
        """)
    
    def test_with_proxy(self, proxy, test_url="http://httpbin.org/ip"):
        """使用指定代理测试访问"""
        print(f"\n🔍 使用代理 {proxy} 测试访问 {test_url}...")
        try:
            start_time = time.time()
            response = requests.get(
                test_url,
                proxies={'http': proxy, 'https': proxy},
                timeout=10,
                verify=False
            )
            response_time = round((time.time() - start_time) * 1000, 2)
            
            if response.status_code == 200:
                print(f"✅ 测试成功! 响应时间: {response_time}ms")
                print(f"   返回数据: {response.text[:100]}...")
                return True
            else:
                print(f"❌ 请求失败，状态码: {response.status_code}")
                return False
        except Exception as e:
            print(f"❌ 测试失败: {e}")
            return False
    
    def run(self):
        """主运行函数"""
        print("🚀 免费代理一键获取脚本启动!")
        print("="*50)
        
        # 尝试从缓存加载
        cached_proxies = self.load_proxies_from_file()
        if cached_proxies:
            use_cache = input("发现缓存的代理文件，是否使用? (y/n, 默认n): ").lower()
            if use_cache == 'y':
                self.working_proxies = cached_proxies
                print(f"📁 从缓存加载了 {len(self.working_proxies)} 个代理")
        
        # 如果没有缓存或用户选择重新获取
        if not self.working_proxies:
            # 获取代理列表
            raw_proxies = self.get_proxy_list(25)
            print(f"📋 共获取到 {len(raw_proxies)} 个原始代理")
            
            if not raw_proxies:
                print("❌ 无法获取代理列表，请检查网络连接")
                return
            
            # 验证代理
            self.working_proxies = self.validate_proxies(raw_proxies)
            print(f"✅ 验证完成! 找到 {len(self.working_proxies)} 个可用代理")
            
            if self.working_proxies:
                # 保存结果
                self.save_proxies_to_file(self.working_proxies)
        
        if self.working_proxies:
            # 显示结果
            print(f"\n🏆 最佳代理 (前10个):")
            for i, proxy_info in enumerate(self.working_proxies[:10], 1):
                print(f"  {i}. {proxy_info['proxy']} - {proxy_info['response_time']}ms")
            
            # 使用最佳代理进行测试
            best_proxy = self.working_proxies[0]['proxy']
            self.test_with_proxy(best_proxy)
            
            # 显示使用示例
            self.show_usage_examples(best_proxy)
            
            # 提供额外测试选项
            while True:
                print(f"\n🎯 额外选项:")
                print("1. 使用特定代理测试自定义网站")
                print("2. 重新获取代理")
                print("3. 退出")
                
                choice = input("请选择 (1-3, 默认3): ").strip()
                
                if choice == '1':
                    proxy_choice = input(f"输入代理序号 (1-{min(10, len(self.working_proxies)}), 默认1): ").strip()
                    try:
                        proxy_idx = int(proxy_choice) - 1 if proxy_choice else 0
                        selected_proxy = self.working_proxies[proxy_idx]['proxy']
                    except:
                        selected_proxy = best_proxy
                    
                    test_url = input("输入测试URL (默认 http://httpbin.org/ip): ").strip()
                    if not test_url:
                        test_url = "http://httpbin.org/ip"
                    
                    self.test_with_proxy(selected_proxy, test_url)
                
                elif choice == '2':
                    self.working_proxies = []
                    self.run()
                    break
                
                else:
                    print("👋 脚本结束，再见!")
                    break
        else:
            print("❌ 没有找到可用的代理，请稍后重试")

def main():
    """主函数"""
    # 禁用SSL警告
    import urllib3
    urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
    
    manager = FreeProxyManager()
    manager.run()

if __name__ == "__main__":
    main()