在尝试通过请求访问this site时,我收到:
('Connection aborted.', error(54, 'Connection reset by peer'))
我还尝试通过mechanize和urllib访问该网站,两者都失败了。但是cURL工作正常(请参阅end代码)。
我尝试了requests.get()
参数verify=True
,stream=True
的组合,我也尝试过使用cURL标头的请求。
我尝试移动到urllib / Mechanize作为替代方案,但两者都给出了相同的错误。
我的请求代码如下:
import requests
import cookielib
url = "https://datamuster.marketdatasuite.com/Account/LogOn?ReturnUrl=%2fProfile%2fList"
header = {
'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Encoding':'gzip,deflate,sdch',
'Accept-Language':'en-US,en;q=0.8',
'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 Safari/537.36'
}
jar = cookielib.CookieJar()
s = requests.Session()
s.headers.update(header)
r = s.get(url, cookies=jar)
带标题的cURL测试:
$ curl -v -I -H "....Testing: Header...." https://datamuster.marketdatasuite.com/Account/LogOn?ReturnUrl=%2fProfile%2fList
* Hostname was NOT found in DNS cache
* Trying 54.252.86.7...
* Connected to datamuster.marketdatasuite.com (54.252.86.7) port 443 (#0)
* TLS 1.2 connection using TLS_RSA_WITH_AES_128_CBC_SHA256
* Server certificate: datamuster.marketdatasuite.com
* Server certificate: COMODO SSL CA
* Server certificate: AddTrust External CA Root
> HEAD /Account/LogOn?ReturnUrl=%2fProfile%2fList HTTP/1.1
> User-Agent: curl/7.37.1
> Host: datamuster.marketdatasuite.com
> Accept: */*
> ....Testing: Header....
>
< HTTP/1.1 200 OK
答案 0 :(得分:3)
服务器需要使用SNI,如果没有使用SNI,则只关闭连接。看起来像curl使用SNI,而至少你使用的请求库的版本不使用SNI。
您可以使用OpenSSL尝试此操作。没有SNI你会收到错误:
$ openssl s_client -connect datamuster.marketdatasuite.com:443
CONNECTED(00000003)
write:errno=104
但是如果你使用SNI(-servername ...
)那么它可以工作:
CONNECTED(00000003)
depth=1 C = GB, ST = Greater Manchester, L = Salford, O = COMODO CA Limited, CN = COMODO SSL CA
...
SSL-Session:
Protocol : TLSv1.2
Cipher : AES128-SHA256
根据FAQ for request SNI不支持Python 2,仅支持Python 3.有关如何使用Python 2使SNI成为可能的信息,请参阅此资源。
答案 1 :(得分:2)
这个过程并不是那么简单,所以我想我会发布一个新的答案,让其他人更容易理解。
Following this thread,我需要安装这些库,让SNI与Python 2一起使用:
但是,与pip install pyOpenSSL
一起安装时,pyOpenSSL可能会导致问题。我实际上不得不删除我现有的openssl,因为pyOpenSSL版本0.14似乎不起作用:
pip uninstall pyOpenSSL
以下命令安装了所有必需的依赖项:
pip install pyOpenSSL==0.13 ndg-httpsclient pyasn1
这应该可以获得在python 2上使用SNI的请求。
继续阅读pyOpenSSL ver的问题。 0.14 ... 强>
安装ver时0.14我收到以下错误:
Command /usr/local/opt/python/bin/python2.7 -c "import setuptools, tokenize;__file__='/private/var/folders/04/3f_y5fw166v03k7b51j1tsl80000gn/T/pip_build_alex/cryptography/setup.py';exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\r\n', '\n'), __file__, 'exec'))" install --record /var/folders/04/3f_y5fw166v03k7b51j1tsl80000gn/T/pip-7QR71B-record/install-record.txt --single-version-externally-managed --compile failed with error code 1 in /private/var/folders/04/3f_y5fw166v03k7b51j1tsl80000gn/T/pip_build_alex/cryptography
Storing debug log for failure in /Users/alex/.pip/pip.log
和pyOpenSSL安装为ver。 0.14不完整:
$ pip show pyOpenSSL
---
Name: pyOpenSSL
Version: 0.14
Location: /usr/local/lib/python2.7/site-packages
Requires: cryptography, six
从requests.get()
尝试中可以看出:
import requests
response = requests.get("http://datamuster.marketdatasuite.com")
(...lots of errors...)
raise ConnectionError(err, request=request)
requests.exceptions.ConnectionError: ('Connection aborted.', error(54, 'Connection reset by peer'))
以下命令恢复为pyOpenSSL ver。 0.13并更正问题
pip uninstall pyOpenSSL
pip install pyOpenSSL==0.13
然后在python:
import requests
requests.get("http://datamuster.marketdatasuite.com")
<Response [200]>
答案 2 :(得分:1)
使用Python请求向WordPress发送测试请求时我遇到了同样的问题(我在专用服务器上安装了WordPress)。 我试图更新SSL包但没有成功。
然后,我意识到发送到服务器的请求在接收响应时出现延迟。长延迟请求总是被“踢掉”并导致('连接中止。',错误(54,'连接重置由对等'))。 事实证明,当请求仍在等待响应时,Web服务器(apache)会重置连接。
我将KeepAliveTimeout从5秒增加到20秒(在Apache Web服务器中)并且再也不会出现此错误。
改进例外代码: 增加KeepAliveTimeout适用于大多数测试。但是,在某些测试中,我仍然遇到相同的错误并且程序停止。我添加了捕获异常的代码并重复它发生的请求。
import requests
...
while(1):
requestOK = True
try:
r = session.get(requestURL, headers=headers, timeout=None)
except requests.exceptions.ConnectionError:
print ("'Connection aborted.', error(54, 'Connection reset by peer')")
print ("\tResend request...")
requestOK = False
if requestOK:
break
希望这会有所帮助!