python的代理访问便利库

python的代理访问便利库

浮梦 142 2024-03-14
import requests
import json


def fetch_new_proxy_from_file():
    try:
        with open('proxy.json', 'r') as file:
            data = json.load(file)

            # 确保数据格式正确,提取http代理部分
            http_proxy = data.get('http')

            if http_proxy:
                ip, port = http_proxy.split('//')[-1].split(':')
                proxy_dict = {'http': f'http://{ip}:{port}', 'https': f'http://{ip}:{port}'}
                return proxy_dict
            else:
                print("代理信息在proxy.json中不存在或格式不正确")
                return None

    except Exception:
        print("proxy.json文件未找到")
        return None


def fetch_new_proxy_from_api():
    # 原始的API获取代理部分保留不变
    api_response = requests.get(
        '获取IP代理的API地址,一条TXT格式')
    raw_proxy = api_response.text.strip()  # 去除两端空白字符

    ip, port = raw_proxy.split(':')

    proxy_dict = {'http': f'http://{ip}:{port}', 'https': f'http://{ip}:{port}'}
    with open("proxy.json", "w") as f:
        f.write(json.dumps(proxy_dict))
        f.close()

    return proxy_dict


def fetch_new_proxy():
    proxy = fetch_new_proxy_from_file()

    if proxy:
        return proxy
    else:
        return fetch_new_proxy_from_api()


def fetch_url_with_dynamic_proxy(url):
    proxy = fetch_new_proxy()
    while True:

        try:
            response = requests.get(url, proxies=proxy, timeout=5)

            # 如果请求成功(HTTP 200系列状态码),则返回结果
            if response.status_code >= 200 and response.status_code < 300:
                return response

        except (requests.exceptions.Timeout, requests.exceptions.ConnectionError) as e:
            print(f"使用代理 {proxy} 访问 {url} 失败,原因:{e}")

            # 在请求失败后,先判断是否已从本地文件获取过代理,如果已获取过,则尝试从API获取新的代理
            if proxy is None or proxy == fetch_new_proxy_from_file():
                proxy = fetch_new_proxy_from_api()

    # 同样,由于理论上总是能够获取到至少一个代理,所以实际上不会无限循环
    # 但可以根据实际情况在此处增加退出条件或异常处理

# 使用示例
url = "https://chaipip.com/"
response = fetch_url_with_dynamic_proxy(url)
print(response.text)