tag scraping parser parsear htmlparser python html validation xhtml

parser - python html scraping



Validar(X) HTML en Python (8)

Creo que HTML tidy hará lo que quieras. Hay un enlace de Python para ello.

¿Cuál es la mejor manera de validar que un documento sigue alguna versión de HTML (preferiblemente que puedo especificar)? Me gustaría saber dónde ocurren los fallos, como en un validador basado en web, excepto en una aplicación nativa de Python.


Creo que es la forma más elegante de invocar el Servicio de Validación W3C en

http://validator.w3.org/

programáticamente. Pocas personas saben que no es necesario filtrar los resultados para obtener los resultados, ya que el servicio devuelve parámetros de encabezado HTTP no estándar.

X-W3C-Validator-Recursion: 1 X-W3C-Validator-Status: Invalid (or Valid) X-W3C-Validator-Errors: 6 X-W3C-Validator-Warnings: 0

para indicar la validez y el número de errores y advertencias.

Por ejemplo, la línea de comando

curl -I "http://validator.w3.org/check?uri=http%3A%2F%2Fwww.stalsoft.com"

devoluciones

HTTP/1.1 200 OK Date: Wed, 09 May 2012 15:23:58 GMT Server: Apache/2.2.9 (Debian) mod_python/3.3.1 Python/2.5.2 Content-Language: en X-W3C-Validator-Recursion: 1 X-W3C-Validator-Status: Invalid X-W3C-Validator-Errors: 6 X-W3C-Validator-Warnings: 0 Content-Type: text/html; charset=UTF-8 Vary: Accept-Encoding Connection: close

Por lo tanto, puede invocar elegantemente el Servicio de Validación W3C y extraer los resultados del encabezado HTTP:

# Programmatic XHTML Validations in Python # Martin Hepp and Alex Stolz # [email protected] / [email protected] import urllib import urllib2 URL = "http://validator.w3.org/check?uri=%s" SITE_URL = "http://www.heppnetz.de" # pattern for HEAD request taken from # http://.com/questions/4421170/python-head-request-with-urllib2 request = urllib2.Request(URL % urllib.quote(SITE_URL)) request.get_method = lambda : ''HEAD'' response = urllib2.urlopen(request) valid = response.info().getheader(''X-W3C-Validator-Status'') if valid == "Valid": valid = True else: valid = False errors = int(response.info().getheader(''X-W3C-Validator-Errors'')) warnings = int(response.info().getheader(''X-W3C-Validator-Warnings'')) print "Valid markup: %s (Errors: %i, Warnings: %i) " % (valid, errors, warnings)


En mi caso, los paquetes de validación python W3C / HTML no funcionaban en la pip search w3c (a partir de septiembre de 2016).

Lo resolví con

$ pip install requests $ python Python 2.7.12 (default, Jun 29 2016, 12:46:54) [GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> r = requests.post(''https://validator.w3.org/nu/'', ... data=file(''index.html'', ''rb'').read(), ... params={''out'': ''json''}, ... headers={''User-Agent'': ''Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36'', ... ''Content-Type'': ''text/html; charset=UTF-8''}) >>> r.text >>> u''{"messages":[{"type":"info", ... >>> r.json() >>> {u''messages'': [{u''lastColumn'': 59, ...

Más documentación aquí, solicitudes de python , W3C Validator API


Este es un validador html muy básico basado en HTMLParser de lxml. No requiere ninguna conexión a internet.

_html_parser = None def validate_html(html): global _html_parser from lxml import etree from StringIO import StringIO if not _html_parser: _html_parser = etree.HTMLParser(recover = False) return etree.parse(StringIO(html), _html_parser)

Tenga en cuenta que esto no verificará el cierre de las etiquetas, por lo que, por ejemplo, pasará lo siguiente:

validate_html("<a href=''example.com''>foo</a>")

Sin embargo, lo siguiente no:

validate_html("<a href=''example.com''>foo</a")


Prueba tidylib. Puede obtener enlaces realmente básicos como parte del módulo elementtidy (construye elementos de árbol a partir de documentos HTML). http://effbot.org/downloads/#elementtidy

>>> import _elementtidy >>> xhtml, log = _elementtidy.fixup("<html></html>") >>> print log line 1 column 1 - Warning: missing <!DOCTYPE> declaration line 1 column 7 - Warning: discarding unexpected </html> line 1 column 14 - Warning: inserting missing ''title'' element

Analizar el registro debería darle prácticamente todo lo que necesita.


Puede decidir instalar el validador HTML localmente y crear un cliente para solicitar la validación.

Aquí hice un programa para validar una lista de URL en un archivo txt. Solo estaba revisando HEAD para obtener el estado de validación, pero si haces un GET obtendrás los resultados completos. Mira la API del validador, hay muchas opciones para ello.

import httplib2 import time h = httplib2.Http(".cache") f = open("urllistfile.txt", "r") urllist = f.readlines() f.close() for url in urllist: # wait 10 seconds before the next request - be nice with the validator time.sleep(10) resp= {} url = url.strip() urlrequest = "http://qa-dev.w3.org/wmvs/HEAD/check?doctype=HTML5&uri="+url try: resp, content = h.request(urlrequest, "HEAD") if resp[''x-w3c-validator-status''] == "Abort": print url, "FAIL" else: print url, resp[''x-w3c-validator-status''], resp[''x-w3c-validator-errors''], resp[''x-w3c-validator-warnings''] except: pass


XHTML es fácil, use lxml .

HTML es más difícil, ya que tradicionalmente no ha habido tanto interés en la validación entre la multitud de HTML (ejecutar a través de un validador, ¡ay!). La solución más fácil sería ejecutar aplicaciones externas como nsgmls o OpenJade , y luego analizar su salida.


PyTidyLib es un buen enlace de pitón para HTML Tidy. Su ejemplo:

from tidylib import tidy_document document, errors = tidy_document(''''''<p>f&otilde;o <img src="bar.jpg">'''''', options={''numeric-entities'':1}) print document print errors

Además, es compatible tanto con el HTML heredado Tidy como con el nuevo tidy-html5 .