为什么我无法连接代理?

时间:2019-09-15 16:57:54

标签: python-3.x proxy python-asyncio aiohttp

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

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,消息=“无效的常量字符串”   parallel.futures._base.TimeoutError

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

但是,如果您这样做:

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

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

1 个答案:

答案 0 :(得分:2)

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

  1. 您永远不应更改要使用的集合。
  2. 如果您有代码并行更改共享资源,则需要使用mutual exclusion使其具有线程安全性。您可以使用"Lock" in python 3.7.