40

验证文档是否遵循某些版本的 HTML(最好是我可以指定)的最佳方法是什么?我希望能够知道故障发生在哪里,例如在基于 Web 的验证器中,但在本机 Python 应用程序中除外。

4

9 回答 9

32

PyTidyLib是一个很好的 HTML Tidy 的 Python 绑定。他们的例子:

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

此外,它与旧版 HTML Tidy新的 tidy-html5兼容。

于 2009-08-14T18:04:38.743 回答
16

XHTML 很简单,使用lxml

from lxml import etree
from StringIO import StringIO
etree.parse(StringIO(html), etree.HTMLParser(recover=False))

HTML 更难,因为传统上在 HTML 人群中对验证没有那么大的兴趣(通过验证器运行 StackOverflow 本身,哎呀)。最简单的解决方案是执行nsgmlsOpenJade等外部应用程序,然后解析它们的输出。

于 2008-08-30T01:20:52.157 回答
15

我认为调用 W3C 验证服务的最优雅方式是

http://validator.w3.org/

以编程方式。很少有人知道您不必为了获得结果而对结果进行屏幕抓取,因为该服务返回非标准的 HTTP 标头参数

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

用于指示有效性以及错误和警告的数量。

例如,命令行

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

返回

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

因此,您可以优雅地调用 W3C 验证服务并从 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)
于 2012-05-09T15:53:46.180 回答
11

您可以决定在本地安装 HTML 验证器并创建一个客户端来请求验证。

在这里,我编写了一个程序来验证 txt 文件中的 url 列表。我只是在检查 HEAD 以获取验证状态,但如果您执行 GET,您将获得完整的结果。查看验证器的 API,它有很多选择。

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
于 2009-03-14T22:42:12.123 回答
6

尝试 tidylib。作为 elementtidy 模块的一部分,您可以获得一些非常基本的绑定(从 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

解析日志应该会给你几乎所有你需要的东西。

于 2008-08-30T01:55:50.170 回答
4

html5lib模块可用于验证 HTML5 文档

>>> import html5lib
>>> html5parser = html5lib.HTMLParser(strict=True)
>>> html5parser.parse('<html></html>')
Traceback (most recent call last):
  ...
html5lib.html5parser.ParseError: Unexpected start tag (html). Expected DOCTYPE.
于 2020-03-27T12:50:25.670 回答
2

我认为HTML tidy会做你想做的事。它有一个 Python 绑定。

于 2008-08-30T01:48:07.800 回答
2

在我的情况下,python W3C/HTML cli 验证包不起作用(截至 2016 年 9 月)。

我是这样手动完成requests

代码:

r = requests.post('https://validator.w3.org/nu/', 
    data=open('FILE.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'})

print r.json()

在控制台中:

$ echo '<!doctype html><html lang=en><head><title>blah</title></head><body></body></html>' | tee FILE.html 
$ 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.

>>> import requests

>>> r = requests.post('https://validator.w3.org/nu/', 
...                    data=open('FILE.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":[]}\n'

>>> r.json()
>>> {u'messages': []}

更多文档在这里python requestsW3C Validator API

于 2016-09-05T19:30:06.360 回答
2

这是一个基于 lxml 的 HTMLParser 的非常基本的 html 验证器。它不是一个完整的 html 验证器,但会进行一些基本检查,不需要任何互联网连接,也不需要大型库。

_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)

请注意,这不会检查结束标签,例如,以下内容将通过:

validate_html("<a href='example.com'>foo")
> <lxml.etree._ElementTree at 0xb2fd888>

但是,以下不会:

validate_html("<a href='example.com'>foo</a")
> XMLSyntaxError: End tag : expected '>', line 1, column 29
于 2016-10-24T23:11:17.357 回答