首页 > 解决方案 > 为什么我无法连接代理?

问题描述

我写了一个小脚本来检查代理:

async def proxy_check(session, proxy):
    global good_proxies
    proxy_str = f'http://{proxy}'
    async with semaphore:
        try:
            async with session.get(host, proxy=proxy_str, timeout=10) as r:
                if r.status == 200:
                    resp = await r.json()
                    if resp['ip'] == proxy:
                        good_proxies.append(proxy)
                        proxies.remove(proxy)
        except Exception:
            logging.exception(proxy)
            proxies.remove(proxy)


async def main():
    async with aiohttp.ClientSession() as session:
        tasks = []
        for proxy in proxies:
            tasks.append(asyncio.create_task(proxy_check(session, proxy)))
        await asyncio.gather(*tasks)  

但是当我运行它时,我得到了以下错误之一:

aiohttp.http_exceptions.BadHttpMessage: 400, message='无效的常量字符串' aiohttp.client_exceptions.ClientResponseError: 400, message='无效的常量字符串' concurrent.futures._base.TimeoutError

我的列表中有近 20,000 个代理,并且此脚本无法通过所有这些代理进行连接。没有一个代理在此脚本中不起作用。

但如果你这样做:

proxy = {'http': f'http://{proxy}'}
r = requests.get(url, proxies=proxy)

一切正常。许多代理工作。我做错了什么?

标签: python-3.xproxypython-asyncioaiohttp

解决方案


该集合proxies在您的主要方法中进行迭代。它是由多个任务并行处理的元素。到目前为止这很好,但在处理功能中,您正在更改您正在处理的集合。这会导致竞争条件导致您正在迭代的集合损坏。

  1. 你永远不应该改变你正在处理的收藏。
  2. 如果您有代码并行更改共享资源,则需要使用互斥来使其线程安全。您可以在 python 3.7 中使用“锁定”。

推荐阅读