python WinError 1005 - 4通过exchangelib下载outlook电子邮件时,远程主机错误强制关闭了现有连接

jaql4c8m  于 2023-05-21  发布在  Python
关注(0)|答案(1)|浏览(147)

我正在尝试运行一个Python脚本来从Outlook收件箱下载电子邮件。然而,每次在第100封电子邮件时,连接都被终止,我得到以下错误:

> Account ------------@------.com: Exception in _get_elements: Traceback (most recent call last):
> File "C:\Program Files\Python38\lib\site-packages\urllib3\connectionpool.py", line 665, in urlopen
> httplib_response = self._make_request(
> File "C:\Program Files\Python38\lib\site-packages\urllib3\connectionpool.py", line 421, in _make_request
> six.raise_from(e, None)
> File "<string>", line 3, in raise_from
> File "C:\Program Files\Python38\lib\site-packages\urllib3\connectionpool.py", line 416, in _make_request
> httplib_response = conn.getresponse()
> File "C:\Program Files\Python38\lib\http\client.py", line 1322, in getresponse
> response.begin()
> File "C:\Program Files\Python38\lib\http\client.py", line 303, in begin
> version, status, reason = self._read_status()
> File "C:\Program Files\Python38\lib\http\client.py", line 264, in _read_status
> line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
> File "C:\Program Files\Python38\lib\socket.py", line 669, in readinto
> return self._sock.recv_into(b)
> File "C:\Program Files\Python38\lib\ssl.py", line 1241, in recv_into
> return self.read(nbytes, buffer)
> File "C:\Program Files\Python38\lib\ssl.py", line 1099, in read
> return self._sslobj.read(len, buffer)
> ConnectionResetError: [WinError 10054] An existing connection was forcibly closed by the remote host
> 
> During handling of the above exception, another exception occurred:
> 
> Traceback (most recent call last):
> File "C:\Program Files\Python38\lib\site-packages\requests\adapters.py", line 439, in send
> resp = conn.urlopen(
> File "C:\Program Files\Python38\lib\site-packages\urllib3\connectionpool.py", line 719, in urlopen
> retries = retries.increment(
> File "C:\Program Files\Python38\lib\site-packages\urllib3\util\retry.py", line 400, in increment
> raise six.reraise(type(error), error, _stacktrace)
> File "C:\Program Files\Python38\lib\site-packages\urllib3\packages\six.py", line 734, in reraise
> raise value.with_traceback(tb)
> File "C:\Program Files\Python38\lib\site-packages\urllib3\connectionpool.py", line 665, in urlopen
> httplib_response = self._make_request(
> File "C:\Program Files\Python38\lib\site-packages\urllib3\connectionpool.py", line 421, in _make_request
> six.raise_from(e, None)
> File "<string>", line 3, in raise_from
> File "C:\Program Files\Python38\lib\site-packages\urllib3\connectionpool.py", line 416, in _make_request
> httplib_response = conn.getresponse()
> File "C:\Program Files\Python38\lib\http\client.py", line 1322, in getresponse
> response.begin()
> File "C:\Program Files\Python38\lib\http\client.py", line 303, in begin
> version, status, reason = self._read_status()
> File "C:\Program Files\Python38\lib\http\client.py", line 264, in _read_status
> line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
> File "C:\Program Files\Python38\lib\socket.py", line 669, in readinto
> return self._sock.recv_into(b)
> File "C:\Program Files\Python38\lib\ssl.py", line 1241, in recv_into
> return self.read(nbytes, buffer)
> File "C:\Program Files\Python38\lib\ssl.py", line 1099, in read
> return self._sslobj.read(len, buffer)
> urllib3.exceptions.ProtocolError: ('Connection aborted.', ConnectionResetError(10054, 'An existing connection was forcibly closed by the remote host', None, 10054, None))
> 
> During handling of the above exception, another exception occurred:
> 
> Traceback (most recent call last):
> File "C:\Program Files\Python38\lib\site-packages\exchangelib\services\common.py", line 330, in _get_elements
> yield from self._response_generator(payload=payload)
> File "C:\Program Files\Python38\lib\site-packages\exchangelib\services\common.py", line 292, in _response_generator
> response = self._get_response_xml(payload=payload)
> File "C:\Program Files\Python38\lib\site-packages\exchangelib\services\common.py", line 416, in _get_response_xml
> r = self._get_response(payload=payload, api_version=api_version)
> File "C:\Program Files\Python38\lib\site-packages\exchangelib\services\common.py", line 370, in _get_response
> r, session = post_ratelimited(
> File "C:\Program Files\Python38\lib\site-packages\exchangelib\util.py", line 917, in post_ratelimited
> protocol.retry_policy.raise_response_errors(r)  # Always raises an exception
> File "C:\Program Files\Python38\lib\site-packages\exchangelib\protocol.py", line 700, in raise_response_errors
> raise response.headers["TimeoutException"]
> File "C:\Program Files\Python38\lib\site-packages\exchangelib\util.py", line 843, in post_ratelimited
> r = session.post(
> File "C:\Program Files\Python38\lib\site-packages\requests\sessions.py", line 581, in post
> return self.request('POST', url, data=data, json=json, **kwargs)
> File "C:\Program Files\Python38\lib\site-packages\requests_oauthlib\oauth2_session.py", line 515, in request
> return super(OAuth2Session, self).request(
> File "C:\Program Files\Python38\lib\site-packages\requests\sessions.py", line 533, in request
> resp = self.send(prep, **send_kwargs)
> File "C:\Program Files\Python38\lib\site-packages\requests\sessions.py", line 646, in send
> r = adapter.send(request, **kwargs)
> File "C:\Program Files\Python38\lib\site-packages\requests\adapters.py", line 498, in send
> raise ConnectionError(err, request=request)
> requests.exceptions.ConnectionError: ('Connection aborted.', ConnectionResetError(10054, 'An existing connection was forcibly closed by the remote host', None, 10054, None))

导致错误的代码块:

for aNum, item in enumerate(unprocessed_emails.filter(subject__contains='Notification').order_by('-datetime_received')):

        emailBody = item.body
        emailBody = emailBody.split('has invited you to view:<br><a href="')
        emailSubject = item.subject
        link = ((emailBody[1]).split('" originalsrc="'))[0]
        #Opens link  which auto-downloads file
        #webbrowser.open_new(link)    
        r = requests.get(link, allow_redirects=True) 
        try:
            sleep(2)
            eMessage = f"{aNum} of {emailCount}: Processing email with subject:  {emailSubject}"
            myLogger.info(msg=eMessage)
            filename = getFilename_fromCd(r.headers.get('content-disposition')).replace(":","_")
        except Exception as e:
            exceptionContent = getFilename_fromCd(r.headers.get('content-disposition'))
            eMessage = str('Connection to Office365 Exchange API Failed\n' + 'Error Message:  ' + str(e) + '\nContent that caused exception:\n{exceptionContent}\nContinuing...')
            myLogger.critical(msg=eMessage)
            supportMessage = f""
            try:
                sendEmailToSupport(supportMessage)
            except Exception as e2:
                eMessage2 = str('Attempt to send email to support failed. Error Message:  ' + str(e))
                myLogger.critical(msg=eMessage2)
                continue
            continue
        print(filename)

        if "event" in emailSubject.lower():
            with open(os.path.join(SourcePath, filename), 'wb') as aFile:
                aFile.write(r.content)
        elif "alarm" in emailSubject.lower():
            with open(os.path.join(ASourcePath, filename), 'wb') as aFile:
                aFile.write(r.content)
        print(reportCounter)
        reportCounter += 1`

不知道是什么导致了这个问题。连接超时只发生在下载的第100封电子邮件上,我猜它触发了一些下载限制,但我似乎在网上找不到任何东西。

sg3maiej

sg3maiej1#

您的示例代码缺少定义帐户和连接设置的部分,但使脚本在遇到连接错误时不受影响的一般解决方案是设置重试策略。参见https://ecederstrand.github.io/exchangelib/#fault-tolerance
示例:

credentials = Credentials(...)
config = Configuration(
  retry_policy=FaultTolerance(max_wait=3600), credentials=credentials
)
account = Account(primary_smtp_address='john@example.com', config=config)

相关问题