2012-05-21 6 views
7

urllib.request ile açmak ve okumak istiyorum ama bir SSL hatası alıyorum . Gayet iyi bu kodla http.client kullanarak sayfayı açıp okuyabilir:Python 3.2'de http.client ile bir HTTPS web sayfasını açabilir ve okuyabilirim, ancak urllib.request aynı sayfayı açmakta başarısız oluyor

import http.client 

conn = http.client.HTTPSConnection('www.yande.re') 
conn.request('GET', 'https://yande.re/') 
resp = conn.getresponse() 
data = resp.read() 

Ancak urllib.request kullanarak aşağıdaki kod başarısız: ssl.SSLError: [Errno 1] _ssl.c:392: error:1411809D:SSL routines:SSL_CHECK_SERVERHELLO_TLSEXT:tls invalid ecpointformat list:

import urllib.request 

opener = urllib.request.build_opener() 
resp = opener.open('https://yande.re/') 
data = resp.read() 

Bana şu hatayı veriyor. Sayfayı neden HTTPSConnection ile açabilirim, opener.open değil? Düzenleme

:

import http.client 
conn = http.client.HTTPSConnection('www.yande.re') 
conn.request('GET', 'https://yande.re/') 

ve: İşte senin iki örneklerde veren konak kaynaklanmaktadır benim OpenSSL sürümü ve sorun https://yande.re/

>>> import ssl; ssl.OPENSSL_VERSION 
'OpenSSL 1.0.0a 1 Jun 2010' 
>>> import urllib.request 
>>> urllib.request.urlopen('https://yande.re/') 
Traceback (most recent call last): 
    File "<pyshell#3>", line 1, in <module> 
    urllib.request.urlopen('https://yande.re/') 
    File "C:\Python32\lib\urllib\request.py", line 138, in urlopen 
    return opener.open(url, data, timeout) 
    File "C:\Python32\lib\urllib\request.py", line 369, in open 
    response = self._open(req, data) 
    File "C:\Python32\lib\urllib\request.py", line 387, in _open 
    '_open', req) 
    File "C:\Python32\lib\urllib\request.py", line 347, in _call_chain 
    result = func(*args) 
    File "C:\Python32\lib\urllib\request.py", line 1171, in https_open 
    context=self._context, check_hostname=self._check_hostname) 
    File "C:\Python32\lib\urllib\request.py", line 1138, in do_open 
    raise URLError(err) 
urllib.error.URLError: <urlopen error [Errno 1] _ssl.c:392: error:1411809D:SSL routines:SSL_CHECK_SERVERHELLO_TLSEXT:tls invalid ecpointformat list> 
>>> 
+0

Import ssl öğesinin yapış yapışını yapıştırabilir misiniz? ssl.OPENSSL_VERSION' ve urllib.request.urlopen ('https://yande.re/') ' –

+0

FWIW sonucu, muhtemelen hata ayıklama için bir veri noktasıdır. Eşdeğer Python 2.7.x kodu (aşağıda gösterilmiştir) iyi çalışır: import urllib2 req = urllib2.Request ('https://yande.re') resp = urllib2.urlopen (req) resp.read() – sateesh

+0

http.client için kod yanlıştır . Şunları yapabilirsiniz: 'conn.request ('GET', '/')' – jfs

cevap

1

açmaya çalışırken gelen traceback var ...

import urllib.request 
urllib.request.urlopen('https://yande.re/') 

İlk örnekte, istemciden ana bilgisayarla bağlantı kurmasını istediğinizi unutmayın: www.yande.re ve ikinci örnekte, urllib ilk önce 'https://yande.re' URL'sini ayrıştırır ve sonra ev sahibi yande.re

Bir isteği deneyin www.yande.re ve yande.re aynı IP adresine çözüm olsa da, web sunucusu açısından bu farklı sanal konaklar vardır. Tahminim, web sunucunuzun tarafında bir SNI yapılandırma problemi olduğunu. Asıl soru 21 Mayıs'ta yayınlandığını görmekte ve yande.re'deki 28 Mayıs'taki şu anki sertifika, bu problemi zaten çözdüğünü düşünüyorum.

+1

'conn.request ('GET', '/')' – jfs

-1

bu deneyin:

import connection #imports connection 
import url 

url = 'http://www.google.com/'  
webpage = url.open(url) 

try: 
    connection.receive(webpage) 
except: 
    webpage = url.text('This webpage is not available!') 
    connection.receive(webpage) 
2

Ne tesadüf! Seninle aynı sorunu yaşıyorum, ek bir komplikasyonla: Bir proxy'nin arkasındayım. Https-not-working-with-urllib ile ilgili olarak bu bug report'u buldum. Neyse ki, bir geçici çözüm yayınladılar.

import urllib.request 
import ssl 

##uncomment this code if you're behind a proxy 
##https port is 443 but it doesn't work for me, used port 80 instead 

##proxy_auth = '{0}://{1}:{2}@{3}'.format('https', 'username', 'password', 
##    'proxy:80') 
##proxies = { 'https' : proxy_auth } 
##proxy = urllib.request.ProxyHandler(proxies) 
##proxy_auth_handler = urllib.request.HTTPBasicAuthHandler() 
##opener = urllib.request.build_opener(proxy, proxy_auth_handler, 
##          https_sslv3_handler) 

https_sslv3_handler = 
     urllib.request.HTTPSHandler(context=ssl.SSLContext(ssl.PROTOCOL_SSLv3)) 
opener = urllib.request.build_opener(https_sslv3_handler) 
urllib.request.install_opener(opener) 
resp = opener.open('https://yande.re/') 
data = resp.read().decode('utf-8') 
print(data) 

Btw, http.client nasıl kullanılacağını göstermek için teşekkürler. İnternete bağlanmak için kullanılabilecek başka bir kütüphane olduğunu bilmiyordum. ;)

+0

Çok teşekkür ederim, bu gerçekten biraz farklı bir urllib sorunuyla bana yardımcı oldu – Corvin

+0

Bu kod parçacığı benim için çalışmıyor; Bir el sıkışma hatası ile sona erer: "ssl.SSLError: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 uyarı anlaşması başarısızlığı (_ssl.c: 748)" – MikeB

2

Bu, bug in the early 1.x OpenSSL implementation of elliptic curve cryptography nedeniyle oluşur. istisna ilgili bölümünün daha yakından göz atın:

_ssl.c:392: error:1411809D:SSL routines:SSL_CHECK_SERVERHELLO_TLSEXT:tls invalid ecpointformat list 

Bu AK nokta biçimi TLS uzantısı ilgilenmedikleri bir sonucudur yatan OpenSSL kütüphanesi kodundan bir hatadır. Bir geçici çözüm, SSLv23 yerine SSLv3 kullanmaktır, diğer çözüm ise tüm ECC şifreleme paketlerini devre dışı bırakan bir şifre paketi belirtimi kullanmaktır (ALL:-ECDH ile iyi sonuçlar aldım, test için openssl ciphers kullanın). Düzeltme OpenSSL'yi güncellemektir.

+0

Lütfen kullanıcı örneğinde bir şifre paketi belirtiminin nasıl kullanılacağını belirtebilir misiniz? –

İlgili konular