Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

htmlcompare

A Python library to check whether two HTML documents are "the same". It ignores differences which do not change what the document means, so a test does not fail just because a template engine emitted the attributes in a different order or wrote margin: 0px instead of margin: 0.

Usage

import htmlcompare

result = htmlcompare.compare_html(expected_html, actual_html)
if not result:
    print(result)

compare_html() returns a ComparisonResult which is true when both documents are the same. result.differences contains one Difference per mismatch, including the path to the node which caused it.

For tests the library provides two assertions:

from htmlcompare import assert_different_html, assert_same_html

assert_same_html('<div />', '<div></div>')
assert_different_html('<br>', '<p>')

Two files can also be compared on the command line:

htmlcompare expected.html actual.html

What is ignored

  • whitespace between tags, and <div /> written as <div></div>
  • the order of HTML attributes, and the order of the CSS classes inside a class attribute
  • an empty style or class attribute, which is treated like an absent one
  • HTML comments
  • the formatting of CSS. style attributes and <style> tags are parsed with a real CSS parser, so trailing semicolons, the order of declarations, the case of property and function names, the spelling of a URL (url(a.png), url("a.png")), a unit on a zero length and any whitespace CSS has no use for do not matter. At-rules (@media, @font-face, …) are compared the same way.

What is a difference

Something is only ignored when HTML and CSS guarantee that both spellings mean the same thing. Where the meaning can change, the documents differ:

  • whitespace which CSS gives a meaning to: .a .b is the descendant combinator and not .a.b, font-family: Arial Black is not font-family: ArialBlack
  • the order of declarations which can override each other, such as background and background-color
  • custom properties, whose names are case-sensitive and whose values var() substitutes literally: --x: 0px is not the same as --x: 0
  • conditional comments in both their forms, because dropping one changes which clients display the content

Malformed CSS never raises an exception. Whatever the CSS parser can not represent is compared as source text instead, which may report a difference which is not one but never hides one.

Options

compare_html() and both assertions take a CompareOptions instance:

option default effect
ignore_comments True ignore HTML comments
ignore_conditional_comments False ignore conditional comments as well
compare_document_prefix False compare text before the <!DOCTYPE> (e.g. {# … #} metadata emitted by a template engine). Such a prefix is always preserved, it is just not compared by default.

Limitations / Plans

No validation of conditional comments. Their condition is compared but not checked for validity. Not sure which library I can use here but at some point I'll likely need this as well.

JavaScript - for obvious reasons it will be impossible to implement perfect JS comparison but it might be possible to run some kind of "beautifier" to take care of insignificant stylistic changes. However I don't need this feature so this is unlikely to get implemented (unless contributed by someone else).

Custom hooks could help adapting the comparison to your specific needs. However I don't know which API would be best so this will wait until there are real-world use cases.

Better API: The current API is very minimal and implements just what I needed right now. I hope to improve the API once I use this project in more complex scenarios.

Other projects

xmldiff is a well established project to compare two XML documents. However it seems as if the code does not contain knowledge about specific HTML semantics (e.g. CSS, empty attributes, insignificant attribute order).

Misc

The code is licensed under the MIT license. It requires Python 3.9+.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

htmlcompare-0.5.0b1.tar.gz (58.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

htmlcompare-0.5.0b1-py3-none-any.whl (41.5 kB view details)

Uploaded Python 3

File details

Details for the file htmlcompare-0.5.0b1.tar.gz.

File metadata

  • Download URL: htmlcompare-0.5.0b1.tar.gz
  • Upload date:
  • Size: 58.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for htmlcompare-0.5.0b1.tar.gz
Algorithm Hash digest
SHA256 2a198ceb74f5dba47bb5f9057f4b36aa0f6cb5f48e0093554e34b678e9dc9f09
MD5 e2d2107f102a639d9c2f965c3ea76401
BLAKE2b-256 7aaae00c8cca1f5c622048f7342abe1518a951cfb610585d54cc4c1ac1d29dc8

See more details on using hashes here.

Provenance

The following attestation bundles were made for htmlcompare-0.5.0b1.tar.gz:

Publisher: release.yml on FelixSchwarz/htmlcompare

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file htmlcompare-0.5.0b1-py3-none-any.whl.

File metadata

  • Download URL: htmlcompare-0.5.0b1-py3-none-any.whl
  • Upload date:
  • Size: 41.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for htmlcompare-0.5.0b1-py3-none-any.whl
Algorithm Hash digest
SHA256 4c49e6918ad9252a442068ecf3d296bac036d3c69d4eebd7f96dafd10f371ec3
MD5 19bc42aced8f81e308df3ff1a9b000cb
BLAKE2b-256 44ef4f149a58abe327f0fdc59f5dabf6ed1aa5bf75ec357d38b9628fe35e7fa9

See more details on using hashes here.

Provenance

The following attestation bundles were made for htmlcompare-0.5.0b1-py3-none-any.whl:

Publisher: release.yml on FelixSchwarz/htmlcompare

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.5.0

2 files

This release

0.5.0b1 This release

2 files

0.4.1

2 files

0.4.0

2 files

0.3.2

2 files

0.3.1

2 files

0.3.0

2 files

0.2.1

2 files

0.2

2 files

0.1

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page