2014-11-24 25 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 

希望這會有所幫助!