Python: [Errno 10054] 远程主机强制关闭了一个已经存在的连接

75

我正在使用Twitter-py编写Python代码爬取Twitter空间。我已经设置了爬虫在向api.twitter.com发送每个请求之间暂停一段时间(2秒)。然而,在运行一段时间后(大约1次),即使Twitter的速率限制尚未超过,我也会收到此错误。

[Errno 10054] An existing connection was forcibly closed by the remote host.

这个问题可能的原因有哪些,如何解决?

我搜索过后发现,可能是Twitter服务器由于请求过多而强制关闭了连接。

非常感谢您提前的帮助。


你解决了吗? - f_s
6个回答

27

这可能是由于连接中的两端在keepalive期间是否超时发生分歧所致。(您的代码试图在服务器由于闲置时间过长而关闭连接时重用该连接。)您应该基本上通过新连接重试操作。(我很惊讶您的库没有自动执行此操作。)


2
我有同样的问题。使用bottle库,并使用httplib发送请求。我无法重试发送,因为原始调用已经在服务器上执行。当我尝试读取响应数据时,连接已关闭。这种情况并不总是发生,通常只在我向服务器发送大量请求时才会出现。您知道我可以调整哪些参数以使通信更稳定吗? - Roman Hwang
1
@RomanHwang 要么你需要一种检查上一个操作而不重复它的方法,要么你需要使你的操作具有idempotent属性。 - David Schwartz
2
谢谢你的提示。我也找到了我经常出错的原因。这是因为bottle默认开发服务器的实现方式。它是单线程的,不适合同时处理太多请求。 - Roman Hwang

15

我知道这是一个非常老的问题,但可能是因为您需要设置请求头。 这对我解决了问题。

例如'user-agent','accept'等。 这里是使用user-agent的示例:

url = 'your-url-here'
headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36'}
r = requests.get(url, headers=headers)

2
你能添加一些细节吗? - Don
4
想象一下编写一个爬虫程序来轮询Twitter,由于这个爬虫不是一个浏览器,所以默认情况下它没有用户代理。因此,网站会提示:请欺骗我们,让我们认为你正在使用一个已经设定了用户代理设置的真实浏览器,比如Mozilla、AppleWebKit、Chrome等浏览器。 - Jeremy Thompson

14

有许多可能的原因,例如:

  • 服务器和客户端之间的网络链接可能暂时中断了。
  • 系统资源不足。
  • 发送了格式不正确的数据。

要详细检查问题,您可以使用Wireshark。

或者您可以重新请求或重新连接。


4

在使用websocket-client连接同一主机的多个线程时,我遇到了相同的错误信息:([WinError 10054] 远程主机强制关闭了一个现有的连接)。这是在设置ping_interval = 2后使用websocket.run_forever()时发生的。

ping_interval = 10ping_timeout = 9解决了这个问题。也许您需要减少请求量,并且停止使主机繁忙,否则您将被强制断开连接。


2

我遇到了这个问题是在尝试连接SAP Hana数据库时。当我得到这个错误时,

OperationalError: Lost connection to HANA server (ConnectionResetError(10054, 'An existing connection was forcibly closed by the remote host', None, 10054, None))

我尝试再次运行下面提到的连接代码,它创建了那个错误,然后它成功了。

    import pyhdb
    connection = pyhdb.connect(host="example.com",port=30015,user="user",password="secret")
    cursor = connection.cursor()
    cursor.execute("SELECT 'Hello Python World' FROM DUMMY")
    cursor.fetchone()
    connection.close()

这是因为服务器拒绝连接。可能需要等待一段时间再次尝试。尝试通过注销并重新登录关闭Hana Studio。多次运行代码。


请问另一个问题。你知道Windows10存储连接字符串的位置吗?我认为它应该在C:\Users\User-Name\AppData\Roaming\Microsoft\MicrosoftSQL_Server\110\Tools\Shell\RegServer.xml中(当然,这是针对SQL Server的)。 - MSIS

2

我用 while try 循环修复了它,等待响应以设置变量以便退出循环。

当连接出现异常时,它会等待五秒钟,并继续寻找连接的响应。

我的修复前的代码,包括失败的响应HTTPSConnectionPool(host='etc.com', port=443): Max retries exceeded with url: / (Caused by ConnectTimeoutError(<urllib3.connection.HTTPSConnection object at 0x000001E9955A2050>, 'Connection to example.net timed out. (connect timeout=None)'))

 

from __future__ import print_function
import sys
import requests


def condition_questions(**kwargs):
    proxies = {'https': 'example.com', 'http': 'example.com:3128'}
    print(kwargs, file=sys.stdout)
    headers = {'etc':'etc',}
    body = f'''<etc>
                </etc>'''

    try:
        response_xml = requests.post('https://example.com', data=body, headers=headers, proxies=proxies)
    except Exception as ex:
        print("exception", ex, file=sys.stdout)
        log.exception(ex)
    finally:
        print("response_xml", response_xml, file=sys.stdout)
        return response_xml

修复后,成功响应为 response_xml <Response [200]>:

import time
...

response_xml = ''
    while response_xml == '':
        try:
            response_xml = requests.post('https://example.com', data=body, headers=headers, proxies=proxies)
            break
        except Exception as ex:
            print("exception", ex, file=sys.stdout)
            log.exception(ex)
            time.sleep(5)
            continue
        finally:
            print("response_xml", response_xml, file=sys.stdout)
            return response_xml

基于Jatin在这里的回答 --“只需这样做,

import time

page = ''
while page == '':
    try:
        page = requests.get(url)
        break
    except:
        print("Connection refused by the server..")
        print("Let me sleep for 5 seconds")
        print("ZZzzzz...")
        time.sleep(5)
        print("Was a nice sleep, now let me continue...")
        continue

不用谢 :)"


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接