2014-11-24 27 views
1

虽然试图通过请求访问this site,我得到:要求,机械化,urllib的失败,但卷曲工作

('Connection aborted.', error(54, 'Connection reset by peer')) 

我也试图通过机械化和urllib的访问网站,都失败了。然而,cURL工作正常(见代码结束)。

我试过requests.get()verify=True,stream=True参数的组合,我也尝试过使用cURL头的请求。

我试图搬到urllib /机械化作为替代品,但都给出了同样的错误。

我的请求的代码如下:

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 -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 

回答

2

此过程并非完全简单,因此我认为我会发布一个新答案以便轻松跟踪其他人。

Following this thread,我需要安装这些库得到SNI与Python 2的工作:

然而,当安装pyOpenSSL可能会导致问题pip install pyOpenSSL。事实上,我不得不删除我现有的OpenSSL,因为pyOpenSSL版本0.14似乎没有工作:

pip uninstall pyOpenSSL 

以下命令安装所有必要的依赖:

pip install pyOpenSSL==0.13 ndg-httpsclient pyasn1 

这应该得到请求现在工作SNI的蟒蛇2


继续阅读与pyOpenSSL版本的问题。 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版本。 0.13和纠正问题

pip uninstall pyOpenSSL 
pip install pyOpenSSL==0.13 

,然后在蟒蛇:

import requests 
requests.get("http://datamuster.marketdatasuite.com") 

<Response [200]> 
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

我使用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 

希望这会有所帮助!