2009-06-24 17 views

risposta

30

Utilizzare la libreria urlgrabber. Questo include un gestore HTTP per urllib2 che supporta HTTP 1.1 e keepalive:

>>> import urllib2 
>>> from urlgrabber.keepalive import HTTPHandler 
>>> keepalive_handler = HTTPHandler() 
>>> opener = urllib2.build_opener(keepalive_handler) 
>>> urllib2.install_opener(opener) 
>>> 
>>> fo = urllib2.urlopen('http://www.python.org') 

Nota: si consiglia di utilizzare la versione urlgrabber 3.9.0 o precedenti, come il modulo keepalive è stato rimosso nella versione 3.9.1

C'è a port il modulo keepalive a Python 3.

+0

Grazie David. Ho aggiornato la risposta di conseguenza. – msanders

+0

Nuovo sito: http://urlgrabber.baseurl.org/ –

+0

Grazie @Forest: ora ho aggiornato il collegamento nella risposta. – msanders

4

Nota che urlgrabber non funziona completamente con Python 2.6. Ho risolto i problemi (credo) apportando le seguenti modifiche in keepalive.py.

In keepalive.HTTPHandler.do_open() rimuovere questo

 if r.status == 200 or not HANDLE_ERRORS: 
     return r 

E inserire questo

 if r.status == 200 or not HANDLE_ERRORS: 
     # [speedplane] Must return an adinfourl object 
     resp = urllib2.addinfourl(r, r.msg, req.get_full_url()) 
     resp.code = r.status 
     resp.msg = r.reason 
     return resp 
+0

Grazie, ma sarebbe bello se tu spiegassi cosa ha risolto invece di quel commento taggato inutile. – 2371

+0

L'originale r e il tuo resp sono entrambi ed entrambi hanno gli stessi attributi. addinfourl dice "classe per aggiungere i metodi info() e geturl() a un file aperto." ma l'originale ha già informazioni() e geturl(). Non potrei calcolare il beneficio. – 2371

4

Purtroppo keepalive.py è stato rimosso dal urlgrabber il 25 Settembre 2009 dal seguente cambiamento dopo urlgrabber era cambiato per dipendere da pycurl (che supporta keep-alive):

http://yum.baseurl.org/gitweb?p=urlgrabber.git;a=commit;h=f964aa8bdc52b29a2c137a917c72eecd4c4dda94

.210

Tuttavia, è ancora possibile ottenere l'ultima revisione di keepalive.py qui:

http://yum.baseurl.org/gitweb?p=urlgrabber.git;a=blob_plain;f=urlgrabber/keepalive.py;hb=a531cb19eb162ad7e0b62039d19259341f37f3a6

7

O controllare httplib s' HTTPConnection.

+0

che ha funzionato per me ... –

+1

come abilitare keep-alive per HTTPConnection? Ho provato ad aggiungere 'Connection: Keep-Alive' a entrambe le richieste e le intestazioni di risposta, ma' httplib' si riconnette ancora su ogni richiesta –

11

Prova urllib3 che ha le seguenti caratteristiche:

  • riutilizzare la stessa connessione socket per richieste multiple (HTTPConnectionPool e HTTPSConnectionPool) (con la verifica dei certificati lato client opzionale).
  • Pubblicazione di file (encode_multipart_formdata).
  • Reindirizzamento e tentativi interni (facoltativo).
  • Supporta la decodifica gzip e deflate.
  • thread-safe e sanity-safe.
  • Base di codice piccola e facile da comprendere, perfetta per estendere e sviluppare. Per una soluzione più completa, dai un'occhiata a Richieste.

o una soluzione molto più completo - Requests - che supporta keep-alive da version 0.8.0 (utilizzando urllib3 internamente) ed ha il seguente features:

  • estremamente semplice HEAD, GET, POST , PUT, PATCH, DELETE Richieste.
  • Supporto Gevent per richieste asincrone.
  • Sessioni con persistenza dei cookie.
  • Supporto per l'autenticazione di base, di digitazione e personalizzata.
  • Codifica automatica dei dizionari
  • Una semplice interfaccia di dizionario per i cookie di richiesta/risposta.
  • Caricamenti di file multipart.
  • Decodifica automatica di risposte Unicode, gzip e deflate.
  • Supporto completo per URL unicode e nomi di dominio.
4

Si prega di evitare il dolore collettivo e utilizzare Requests invece. Farà la cosa giusta per impostazione predefinita e usa keep-alive se applicabile.

+0

Sto lavorando su qualche autenticazione NTLM e la libreria delle richieste NTLM non funziona correttamente. Tuttavia, la libreria NTLM urllib2 funziona correttamente. Questa domanda è stata quindi utile per me. –

+0

@JeffersonHudson, non ne ero a conoscenza. Potresti avere più fortuna con https://github.com/requests/requests-ntlm –

+1

Ho già proposto richieste nella mia risposta pubblicate più di un anno prima di questa ... –

0

Ecco un urlopen() un po 'simile che mantiene in vita, anche se non è sicuro.

try: 
    from http.client import HTTPConnection, HTTPSConnection 
except ImportError: 
    from httplib import HTTPConnection, HTTPSConnection 
import select 
connections = {} 


def request(method, url, body=None, headers={}, **kwargs): 
    scheme, _, host, path = url.split('/', 3) 
    h = connections.get((scheme, host)) 
    if h and select.select([h.sock], [], [], 0)[0]: 
     h.close() 
     h = None 
    if not h: 
     Connection = HTTPConnection if scheme == 'http:' else HTTPSConnection 
     h = connections[(scheme, host)] = Connection(host, **kwargs) 
    h.request(method, '/' + path, body, headers) 
    return h.getresponse() 


def urlopen(url, data=None, *args, **kwargs): 
    resp = request('POST' if data else 'GET', url, data, *args, **kwargs) 
    assert resp.status < 400, (resp.status, resp.reason, resp.read()) 
    return resp 
Problemi correlati