La biblioteca urllib2 utiliza objetos OpenerDirector para manejar la abertura real. Afortunadamente, la biblioteca de Python proporciona los valores predeterminados para que no tenga que hacerlo. Sin embargo, son estos objetos OpenerDirector los que agregan los encabezados adicionales.
para ver lo que hay después de la solicitud ha sido enviado (por lo que puede iniciar sesión, por ejemplo):
req = urllib2.Request(url='http://google.com')
response = urllib2.urlopen(req)
print req.unredirected_hdrs
(produces {'Host': 'google.com', 'User-agent': 'Python-urllib/2.5'} etc)
Los unredirected_hdrs es donde los OpenerDirectors vierten sus cabeceras extra. Simplemente al mirar req.headers
, solo se mostrarán sus propios encabezados; la biblioteca los dejará sin molestar.
Si necesita ver los encabezados antes de enviar la solicitud, deberá subclasificar el OpenerDirector para interceptar la transmisión.
Espero que ayude.
EDITAR: Olvidé mencionar que, una vez enviada la solicitud, req.header_items()
le dará una lista de tuplas de TODOS los encabezados, con las suyas y las agregadas por el OpenerDirector. Debería haber mencionado esto primero, ya que es el más sencillo :-) Lo siento.
EDIT 2: Después de su pregunta sobre un ejemplo para definir su propio controlador, esta es la muestra que se me ocurrió. La preocupación en cualquier monkeying con la cadena de solicitud es que tenemos que estar seguros de que el controlador es seguro para múltiples solicitudes, por lo que no me siento cómodo simplemente reemplazando la definición de putheader en la clase HTTPConnection directamente.
Lamentablemente, como las partes internas de HTTPConnection y AbstractHTTPHandler son muy internas, tenemos que reproducir gran parte del código de la biblioteca de python para inyectar nuestro comportamiento personalizado. Suponiendo que no me haya equivocado a continuación y esto funciona tan bien como lo hizo en mis 5 minutos de prueba, tenga cuidado de revisar esta anulación si actualiza su versión de Python a un número de revisión (es decir: 2.5.x a 2.5.y o 2.5 a 2.6, etc.).
Debo mencionar que estoy en Python 2.5.1. Si tiene 2.6 o, particularmente, 3.0, puede necesitar ajustar esto en consecuencia.
Háganme saber si esto no funciona. Estoy teniendo waaaayyyy demasiada diversión con esta pregunta:
import urllib2
import httplib
import socket
class CustomHTTPConnection(httplib.HTTPConnection):
def __init__(self, *args, **kwargs):
httplib.HTTPConnection.__init__(self, *args, **kwargs)
self.stored_headers = []
def putheader(self, header, value):
self.stored_headers.append((header, value))
httplib.HTTPConnection.putheader(self, header, value)
class HTTPCaptureHeaderHandler(urllib2.AbstractHTTPHandler):
def http_open(self, req):
return self.do_open(CustomHTTPConnection, req)
http_request = urllib2.AbstractHTTPHandler.do_request_
def do_open(self, http_class, req):
# All code here lifted directly from the python library
host = req.get_host()
if not host:
raise URLError('no host given')
h = http_class(host) # will parse host:port
h.set_debuglevel(self._debuglevel)
headers = dict(req.headers)
headers.update(req.unredirected_hdrs)
headers["Connection"] = "close"
headers = dict(
(name.title(), val) for name, val in headers.items())
try:
h.request(req.get_method(), req.get_selector(), req.data, headers)
r = h.getresponse()
except socket.error, err: # XXX what error?
raise urllib2.URLError(err)
r.recv = r.read
fp = socket._fileobject(r, close=True)
resp = urllib2.addinfourl(fp, r.msg, req.get_full_url())
resp.code = r.status
resp.msg = r.reason
# This is the line we're adding
req.all_sent_headers = h.stored_headers
return resp
my_handler = HTTPCaptureHeaderHandler()
opener = urllib2.OpenerDirector()
opener.add_handler(my_handler)
req = urllib2.Request(url='http://www.google.com')
resp = opener.open(req)
print req.all_sent_headers
shows: [('Accept-Encoding', 'identity'), ('Host', 'www.google.com'), ('Connection', 'close'), ('User-Agent', 'Python-urllib/2.5')]
Si se conecta a través de SSL, use 'urllib2.HTTPSHandler' (' https_open() ') y' httplib.HTTPSConnection' en su lugar. –