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
PyTidyLib es un buen enlace de pitón para HTML Tidy. Su ejemplo:
from tidylib import tidy_document
document, errors = tidy_document(''''''<p>fõ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 .