zoukankan      html  css  js  c++  java
  • python socket 超时设置 errno10054

    python socket.error: [Errno 10054] 远程主机强迫关闭了一个现有的连接。问题解决方案:

    前几天使用python读取网页。因为对一个网站大量的使用urlopen操作,所以会被那个网站认定为攻击行为。有时就不再允许下载。导致urlopen()后,request.read()一直卡死在那里。最后会抛出errno 10054.

    这 个错误是connection reset by peer.也就是传说的远端主机重置了此连接。原因可能是socket超时时间过长;也可能是request = urllib.request.urlopen(url)之后,没有进行request.close()操作;也可能是没有sleep几秒,导致网站认定 这种行为是攻击。

    具体解决方案如下面的代码:

    import socket  
    import time  
    timeout = 20    
    socket.setdefaulttimeout(timeout)#这里对整个socket层设置超时时间。后续文件中如果再使用到socket,不必再设置  
    sleep_download_time = 10 
    time.sleep(sleep_download_time) #这里时间自己设定  
    request = urllib.request.urlopen(url)#这里是要读取内容的url  
    content = request.read()#读取,一般会在这里报异常  
    request.close()#记得要关闭 
    import socket
    import time
    timeout = 20 
    socket.setdefaulttimeout(timeout)#这里对整个socket层设置超时时间。后续文件中如果再使用到socket,不必再设置
    sleep_download_time = 10
    time.sleep(sleep_download_time) #这里时间自己设定
    request = urllib.request.urlopen(url)#这里是要读取内容的url
    content = request.read()#读取,一般会在这里报异常
    request.close()#记得要关闭

    因为urlopen之后的read()操作其实是调用了socket层的某些函数。所以设置socket缺省超时时间,就可以让网络自己断掉。不必在read()处一直等待。

    当然你也可以再外层再写几个try,except,例如:

    try:  
        time.sleep(self.sleep_download_time)  
        request = urllib.request.urlopen(url)  
        content = request.read()  
        request.close()  
          
    except UnicodeDecodeError as e:  
             
        print('-----UnicodeDecodeErrorurl:',url)  
          
    except urllib.error.URLError as e:  
        print("-----urlErrorurl:",url)  
     
    except socket.timeout as e:  
        print("-----socket timout:",url) 
            try:
                time.sleep(self.sleep_download_time)
                request = urllib.request.urlopen(url)
                content = request.read()
                request.close()
               
            except UnicodeDecodeError as e:
                  
                print('-----UnicodeDecodeErrorurl:',url)
               
            except urllib.error.URLError as e:
                print("-----urlErrorurl:",url)
      
            except socket.timeout as e:
                print("-----socket timout:",url)

    一 般来说就莫有问题了。我测试了几千个网页的下载,然后才说出此话。不过如果是下载成千上万的,我做了下测试,ms还是会跳出这个异常。可能是 time.sleep()的时间太短,也可能是网络突然中断。我使用urllib.request.retrieve()测试了一下,发现不停的下载数 据,总会有失败的情况出现。

    简单的处理方法是:首先参照的我的文章:python检查点简单实现 。先做一个检查点。然后将以上会跑出异常的那段代码while True一下。参见下面的伪代码:

    def Download_auto(downloadlist,fun,sleep_time=15):  
        while True:          
            try: # 外包一层try   
                value = fun(downloadlist,sleep_time) # 这里的fun是你的下载函数,我当函数指针传进来。 
               # 只有正常执行方能退出。  
                if value == Util.SUCCESS:  
                    break 
            except : # 如果发生了10054或者IOError或者XXXError  
                sleep_time += 5 #多睡5秒,重新执行以上的download.因为做了检查点的缘故,上面的程序会从抛出异常的地方继续执行。防止了因为网络连接不稳定带来的程序中断。  
                print('enlarge sleep time:',sleep_time) 
    def Download_auto(downloadlist,fun,sleep_time=15):
        while True:       
            try: # 外包一层try
                value = fun(downloadlist,sleep_time) # 这里的fun是你的下载函数,我当函数指针传进来。
               # 只有正常执行方能退出。
                if value == Util.SUCCESS:
                    break
            except : # 如果发生了10054或者IOError或者XXXError
                sleep_time += 5 #多睡5秒,重新执行以上的download.因为做了检查点的缘故,上面的程序会从抛出异常的地方继续执行。防止了因为网络连接不稳定带来的程序中断。
                print('enlarge sleep time:',sleep_time)

    不过对于找不到相应的网页,又要做另外的一番处理:

    # 打印下载信息  
    def reporthook(blocks_read, block_size, total_size):  
        if not blocks_read:  
            print ('Connection opened')  
        if total_size < 0:  
            print ('Read %d blocks' % blocks_read)  
        else: 
            # 如果找不到,页面不存在,可能totalsize就是0,不能计算百分比  
            print('downloading:%d MB, totalsize:%d MB' % (blocks_read*block_size/1048576.0,total_size/1048576.0))  
            
     
    def Download(path,url): 
    #url = 'http://downloads.sourceforge.net/sourceforge/alliancep2p/Alliance-v1.0.6.jar' 
        #filename = url.rsplit("/")[-1]  
        try: 
        # python自带的下载函数  
            urllib.request.urlretrieve(url, path, reporthook)  
        except IOError as e: # 如果找不到,好像会引发IOError。  
            print("download ",url,"
    error:",e)  
        print("Done:%s
    Copy to:%s" %(url,path)) 
    # 打印下载信息
    def reporthook(blocks_read, block_size, total_size):
        if not blocks_read:
            print ('Connection opened')
        if total_size < 0:
            print ('Read %d blocks' % blocks_read)
        else:
            # 如果找不到,页面不存在,可能totalsize就是0,不能计算百分比
            print('downloading:%d MB, totalsize:%d MB' % (blocks_read*block_size/1048576.0,total_size/1048576.0))
         
    
    def Download(path,url):
    #url = 'http://downloads.sourceforge.net/sourceforge/alliancep2p/Alliance-v1.0.6.jar'
        #filename = url.rsplit("/")[-1]
        try:
        # python自带的下载函数
            urllib.request.urlretrieve(url, path, reporthook)
        except IOError as e: # 如果找不到,好像会引发IOError。
            print("download ",url,"
    error:",e)
        print("Done:%s
    Copy to:%s" %(url,path))

    如果大家还是遇到了问题...请再评论里注上其他解决方案。

    原网址:http://www.cnblogs.com/mmix2009/archive/2013/07/30/3224954.html

  • 相关阅读:
    leetcode Remove Linked List Elements
    leetcode Word Pattern
    leetcode Isomorphic Strings
    leetcode Valid Parentheses
    leetcode Remove Nth Node From End of List
    leetcode Contains Duplicate II
    leetcode Rectangle Area
    leetcode Length of Last Word
    leetcode Valid Sudoku
    leetcode Reverse Bits
  • 原文地址:https://www.cnblogs.com/jmmchina/p/6692734.html
Copyright © 2011-2022 走看看