2009-11-23 6 views
9

Estoy tratando de analizar y enviar un formulario en un sitio web usando mechanize, pero parece que el analizador de formularios incorporado no puede detectar la forma y sus elementos. Sospecho que se está ahogando en HTML mal formado, y me gustaría intentar analizarlo previamente con un analizador mejor diseñado para manejar HTML incorrecto (digamos lxml o BeautifulSoup) y luego alimentar el resultado limpio y embellecido al formulario analizador Necesito mecanizar no solo para enviar el formulario sino también para mantener las sesiones (estoy trabajando en este formulario desde una sesión de inicio de sesión)¿Es posible conectar un analizador de HTML más robusto a Python Mechanize?

No estoy seguro de cómo hacerlo, si es posible. . No estoy tan familiarizado con los diversos detalles del protocolo HTTP, cómo hacer que funcionen varias partes, etc. ¿Alguna sugerencia?

Respuesta

3

lectura de la gran ejemplo en la primera página de la mechanize website:

# Sometimes it's useful to process bad headers or bad HTML: 
response = br.response() # this is a copy of response 
headers = response.info() # currently, this is a mimetools.Message 
headers["Content-type"] = "text/html; charset=utf-8" 
response.set_data(response.get_data().replace("<!---", "<!--")) 
br.set_response(response) 

por lo que parece muy posible procesar previamente la respuesta con otro programa de análisis que regenerar HTML bien formado, luego alimentar de nuevo a mecanizar para su posterior procesamiento.

+0

Sí, Supongo que me perdí eso. Por otra parte, los documentos mecanizados no son exactamente los mejor organizados. ¡Gracias! – int3

1

Lo que está buscando se puede hacer con lxml.etree que es el emulador xml.etree.ElementTree (y reemplazo) proporcionada por lxml:

Primero tomamos mala mala formada HTML:

% cat bad.html 
<html> 
<HEAD> 
    <TITLE>this HTML is awful</title> 
</head> 
<body> 
    <h1>THIS IS H1</H1> 
    <A HREF=MYLINK.HTML>This is a link and it is awful</a> 
    <img src=yay.gif> 
</body> 
</html> 

(Observar el caso mixto entre las etiquetas de apertura y cierre, las comillas que faltan).

Y luego analizarlo:

>>> from lxml import etree 
>>> bad = file('bad.html').read() 
>>> html = etree.HTML(bad) 
>>> print etree.tostring(html) 
<html><head><title>this HTML is awful</title></head><body> 
    <h1>THIS IS H1</h1> 
    <a href="MYLINK.HTML">This is a link and it is awful</a> 
    <img src="yay.gif"/></body></html> 

observar que el etiquetado y la cita se ha corregido para nosotros.

Si tenía problemas para analizar el código HTML antes, esta podría ser la respuesta que está buscando. En cuanto a los detalles de HTTP, esa es otra cuestión completamente distinta.

+0

Yo sé cómo usar lxml, en realidad ...: P Me preguntaba cómo hacerlo funcionar con mecanizar. – int3

+0

¡Entonces buena suerte para ti! ¡Agarra tus tobillos! – jathanism

10

Tuve un problema donde faltaba un campo de formulario de un formulario, no pude encontrar ningún html con formato incorrecto, pero pensé que esa era la causa, así que usé la función de embellecimiento de BeautifulSoup para analizarlo y funcionó.

resp = br.open(url) 
soup = BeautifulSoup(resp.get_data()) 
resp.set_data(soup.prettify()) 
br.set_response(resp) 

Me encantaría saber cómo hacerlo automáticamente.

edición: encontrar la manera de hacer esto de forma automática

class PrettifyHandler(mechanize.BaseHandler): 
    def http_response(self, request, response): 
     if not hasattr(response, "seek"): 
      response = mechanize.response_seek_wrapper(response) 
     # only use BeautifulSoup if response is html 
     if response.info().dict.has_key('content-type') and ('html' in response.info().dict['content-type']): 
      soup = BeautifulSoup(response.get_data()) 
      response.set_data(soup.prettify()) 
     return response 

    # also parse https in the same way 
    https_response = http_response 

br = mechanize.Browser() 
br.add_handler(PrettifyHandler()) 

br usará ahora BeautifulSoup para analizar todas las respuestas, donde html está contenido en el tipo de contenido (tipo MIME), por ejemplo text/html

+0

¿Ha probado la solución actualizada ('PrettifyHandler')? No funcionó para mí – sirfz

+0

@sirfz Lo probé en el momento y funcionó. No he utilizado mechanize o BeautifulSoup durante varios años, tal vez no funcione con las versiones actuales. ¿Estás seguro de que tu respuesta tiene un encabezado 'content-type' que incluye la cadena' html'? – cerberos

+0

sí, agregué un pdb dentro de 'http_response' antes de la condición y nunca lo alcancé. Supongo que es como dijiste, no compatible con la última versión, aunque hubiera sido muy conveniente. – sirfz

Cuestiones relacionadas