python httplib的各种超时

python httplib的各种超时,python,settimeout,httplib,Python,Settimeout,Httplib,我正在实现一个从各种服务器获取网页的小服务。我需要能够配置不同类型的超时。我尝试过使用sockets的settimeout方法,但这并不是我想要的。问题就在这里 我需要为初始DNS查找指定超时。我知道这是在我开始实例化HTTPConnection时完成的 我的代码是这样编写的:我首先。读取一块数据(大约10 MB),如果整个有效负载都符合这个要求,我就转到代码的其他部分。如果它不适合这种情况,我直接将有效负载流式输出到文件中,而不是内存中。当这种情况发生时,我执行一个无界的.read()来获取数

我正在实现一个从各种服务器获取网页的小服务。我需要能够配置不同类型的超时。我尝试过使用sockets的
settimeout
方法,但这并不是我想要的。问题就在这里

  • 我需要为初始DNS查找指定超时。我知道这是在我开始实例化
    HTTPConnection
    时完成的

  • 我的代码是这样编写的:我首先
    。读取
    一块数据(大约10 MB),如果整个有效负载都符合这个要求,我就转到代码的其他部分。如果它不适合这种情况,我直接将有效负载流式输出到文件中,而不是内存中。当这种情况发生时,我执行一个无界的
    .read()
    来获取数据,如果远程端每秒向我发送一个字节的数据,那么连接只会一直等待每秒接收一个字节。我希望能够与“你花的时间太长”断开连接。基于线程的解决方案将是最后的选择


  • httplib
    就是要直接找到你想要的东西

    我建议你去看看这个选项

    这个选项听起来也很有趣:

    考虑使用c-ares支持构建libcurl,以启用异步DNS查找,从而在没有信号的情况下实现名称解析的良好超时

    你试过了吗

    您可以方便地设置超时

    编辑: 我错过了问题的第二部分。为此,您可以使用以下方法:

    import sys
    import signal
    import requests
    
    class TimeoutException(Exception): 
        pass 
    
    def get_timeout(url, dns_timeout=10, load_timeout=60):
        def timeout_handler(signum, frame):
            raise TimeoutException()
    
        signal.signal(signal.SIGALRM, timeout_handler) 
        signal.alarm(load_timeout)  # triger alarm in seconds
    
        try: 
            response = requests.get(url, timeout=dns_timeout)
        except TimeoutException:
            return "you're taking too long"
        return response
    
    在代码中使用
    get\u timeout
    功能

    如果您需要超时以用于其他函数,您可以创建一个装饰器。
    上面的代码来自。

    ,这样就行了。不过这是我最后的选择,因为我希望尽可能避免外部依赖(尤其是C依赖)。@NoufalIbrahim:它非常清楚地表明(就在链接之后),超时仅用于连接过程,而不是获取有效负载。这就是我的问题。而且,这并不能解决DNS查找的问题。很抱歉,我忽略了你的问题。你是对的,我也编辑了答案来尝试解决问题的第2部分。当有多个线程用于此过程时,这可能不起作用。在这种情况下,基于信号的超时是有风险的。@NoufalIbrahim:
    请求
    超时
    选项仅限制单个
    套接字
    操作(最新版本允许将连接超时与读取超时分开指定,并明确指出这些超时不是总超时,即连接和读取阶段都可能涉及多个套接字操作,因此总超时可能更大)。
    import sys
    import signal
    import requests
    
    class TimeoutException(Exception): 
        pass 
    
    def get_timeout(url, dns_timeout=10, load_timeout=60):
        def timeout_handler(signum, frame):
            raise TimeoutException()
    
        signal.signal(signal.SIGALRM, timeout_handler) 
        signal.alarm(load_timeout)  # triger alarm in seconds
    
        try: 
            response = requests.get(url, timeout=dns_timeout)
        except TimeoutException:
            return "you're taking too long"
        return response