Pergunta

Qual é a melhor maneira de validar se um documento segue alguma versão do HTML (de preferência que eu possa especificar)?Gostaria de saber onde ocorrem as falhas, como em um validador baseado na web, exceto em um aplicativo Python nativo.

Foi útil?

Solução

XHTML é fácil, use lxml.

HTML é mais difícil, já que tradicionalmente não há tanto interesse em validação entre o pessoal do HTML (execute o próprio StackOverflow por meio de um validador, caramba).A solução mais fácil seria executar aplicativos externos, como nsgmls ou OpenJade, e, em seguida, analise sua saída.

Outras dicas

PyTidyLib é uma boa ligação python para HTML Tidy.O exemplo deles:

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

Além disso, é compatível com ambos HTML legado Tidy e a novo arrumado-html5.

Acho que a maneira mais elegante de invocar o Serviço de Validação W3C em

http://validator.w3.org/

programaticamente.Poucas pessoas sabem que você não precisa copiar a tela dos resultados para obtê-los, porque o serviço retorna parâmetros de cabeçalho HTTP não padrão

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

para indicar a validade e o número de erros e avisos.

Por exemplo, a linha de comando

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

retorna

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

Assim, você pode invocar com elegância o serviço de validação W3C e extrair os resultados do cabeçalho 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)

Você pode decidir instalar o validador HTML localmente e criar um cliente para solicitar a validação.

Aqui eu fiz um programa para validar uma lista de urls em um arquivo txt.Eu estava apenas verificando o HEAD para obter o status de validação, mas se você fizer um GET, obterá os resultados completos.Veja a API do validador, há muitas opções para isso.

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

Experimente o tidylib.Você pode obter algumas ligações realmente básicas como parte do módulo elementtidy (cria elementtrees 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

A análise do log deve fornecer praticamente tudo o que você precisa.

eu penso isso HTML arrumado fará o que você quiser.Existe uma ligação Python para isso.

No meu caso, os pacotes de validação python W3C/HTML não funcionaram pip search w3c (em setembro de 2016).

Eu resolvi isso com

$ 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, ...

Mais documentação aqui solicitações python, API validadora W3C

Este é um validador HTML muito básico baseado no HTMLParser do lxml.Não requer nenhuma conexão com 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)

Observe que isso não verificará tags de fechamento, então, por exemplo, o seguinte será aprovado:

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

No entanto, o seguinte costuma:

validate_html("<a href='example.com'>foo</a")
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top