Pregunta

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

¿Fue útil?

Solución

XHTML es fácil, úsalo 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 (ejecute StackOverflow a través de un validador, ¡ay!).La solución más sencilla sería ejecutar aplicaciones externas como nsgmls o abiertojade, y luego analizar su salida.

Otros consejos

PyTidyLib es un buen enlace de Python 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 con ambos. HTML heredado ordenado y el nuevo ordenado-html5.

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

http://validator.w3.org/

programáticamente.Pocas personas saben que no es necesario escanear la pantalla de los resultados para obtenerlos, porque 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 del W3C y extraer los resultados del encabezado HTTP:

# Programmatic XHTML Validations in Python
# Martin Hepp and Alex Stolz
# mhepp@computer.org / alex.stolz@ebusiness-unibw.org

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://stackoverflow.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)

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 de texto.Solo estaba revisando HEAD para obtener el estado de validación, pero si haces GET obtendrías los resultados completos.Mire 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

Prueba tidylib.Puede obtener algunos enlaces realmente básicos como parte del módulo elementtidy (construye árboles de elementos 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 proporcionarle prácticamente todo lo que necesita.

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

En mi caso, los paquetes de validación de Python W3C/HTML no funcionaron. pip search w3c (a septiembre de 2016).

Resolví esto 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, API del validador del W3C

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 comprobará las etiquetas de cierre, por lo que, por ejemplo, se pasará lo siguiente:

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

Sin embargo, lo siguiente suele ser habitual:

validate_html("<a href='example.com'>foo</a")
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top