Sophie

Sophie

distrib > CentOS > 5 > i386 > by-pkgid > 90dba77ca23efa667b541b5c0dd77497 > files > 384

python-lxml-2.0.11-2.el5.i386.rpm

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.4.1: http://docutils.sourceforge.net/" />
<title>lxml.html</title>
<link rel="stylesheet" href="style.css" type="text/css" />
</head>
<body>
<div class="document" id="lxml-html">
<div class="sidemenu"><ul id="lxml"><li><span class="section title">lxml</span><ul class="menu foreign" id="index"><li class="menu title"><a href="index.html">lxml</a><ul class="submenu"><li class="menu item"><a href="index.html#introduction">Introduction</a></li><li class="menu item"><a href="index.html#documentation">Documentation</a></li><li class="menu item"><a href="index.html#download">Download</a></li><li class="menu item"><a href="index.html#mailing-list">Mailing list</a></li><li class="menu item"><a href="index.html#bug-tracker">Bug tracker</a></li><li class="menu item"><a href="index.html#license">License</a></li><li class="menu item"><a href="index.html#old-versions">Old Versions</a></li></ul></li></ul><ul class="menu foreign" id="intro"><li class="menu title"><a href="intro.html">Why lxml?</a><ul class="submenu"><li class="menu item"><a href="intro.html#motto">Motto</a></li><li class="menu item"><a href="intro.html#aims">Aims</a></li></ul></li></ul><ul class="menu foreign" id="installation"><li class="menu title"><a href="installation.html">Installing lxml</a><ul class="submenu"><li class="menu item"><a href="installation.html#requirements">Requirements</a></li><li class="menu item"><a href="installation.html#installation">Installation</a></li><li class="menu item"><a href="installation.html#building-lxml-from-sources">Building lxml from sources</a></li><li class="menu item"><a href="installation.html#ms-windows">MS Windows</a></li><li class="menu item"><a href="installation.html#macos-x">MacOS-X</a></li></ul></li></ul><ul class="menu foreign" id="lxml2"><li class="menu title"><a href="lxml2.html">What's new in lxml 2.0?</a><ul class="submenu"><li class="menu item"><a href="lxml2.html#changes-in-etree-and-objectify">Changes in etree and objectify</a></li><li class="menu item"><a href="lxml2.html#new-modules">New modules</a></li></ul></li></ul><ul class="menu foreign" id="performance"><li class="menu title"><a href="performance.html">Benchmarks and Speed</a><ul class="submenu"><li class="menu item"><a href="performance.html#general-notes">General notes</a></li><li class="menu item"><a href="performance.html#how-to-read-the-timings">How to read the timings</a></li><li class="menu item"><a href="performance.html#parsing-and-serialising">Parsing and Serialising</a></li><li class="menu item"><a href="performance.html#the-elementtree-api">The ElementTree API</a></li><li class="menu item"><a href="performance.html#xpath">XPath</a></li><li class="menu item"><a href="performance.html#a-longer-example">A longer example</a></li><li class="menu item"><a href="performance.html#lxml-objectify">lxml.objectify</a></li></ul></li></ul><ul class="menu foreign" id="compatibility"><li class="menu title"><a href="compatibility.html">ElementTree compatibility of lxml.etree</a></li></ul><ul class="menu foreign" id="FAQ"><li class="menu title"><a href="FAQ.html">lxml FAQ - Frequently Asked Questions</a><ul class="submenu"><li class="menu item"><a href="FAQ.html#general-questions">General Questions</a></li><li class="menu item"><a href="FAQ.html#installation">Installation</a></li><li class="menu item"><a href="FAQ.html#contributing">Contributing</a></li><li class="menu item"><a href="FAQ.html#bugs">Bugs</a></li><li class="menu item"><a href="FAQ.html#threading">Threading</a></li><li class="menu item"><a href="FAQ.html#parsing-and-serialisation">Parsing and Serialisation</a></li><li class="menu item"><a href="FAQ.html#xpath-and-document-traversal">XPath and Document Traversal</a></li></ul></li></ul></li></ul><ul id="Developing with lxml"><li><span class="section title">Developing with lxml</span><ul class="menu foreign" id="tutorial"><li class="menu title"><a href="tutorial.html">The lxml.etree Tutorial</a><ul class="submenu"><li class="menu item"><a href="tutorial.html#the-element-class">The Element class</a></li><li class="menu item"><a href="tutorial.html#the-elementtree-class">The ElementTree class</a></li><li class="menu item"><a href="tutorial.html#parsing-from-strings-and-files">Parsing from strings and files</a></li><li class="menu item"><a href="tutorial.html#namespaces">Namespaces</a></li><li class="menu item"><a href="tutorial.html#the-e-factory">The E-factory</a></li><li class="menu item"><a href="tutorial.html#elementpath">ElementPath</a></li></ul></li></ul><ul class="menu foreign" id="api index"><li class="menu title"><a href="api/index.html">API reference</a></li></ul><ul class="menu foreign" id="api"><li class="menu title"><a href="api.html">APIs specific to lxml.etree</a><ul class="submenu"><li class="menu item"><a href="api.html#lxml-etree">lxml.etree</a></li><li class="menu item"><a href="api.html#other-element-apis">Other Element APIs</a></li><li class="menu item"><a href="api.html#trees-and-documents">Trees and Documents</a></li><li class="menu item"><a href="api.html#iteration">Iteration</a></li><li class="menu item"><a href="api.html#error-handling-on-exceptions">Error handling on exceptions</a></li><li class="menu item"><a href="api.html#error-logging">Error logging</a></li><li class="menu item"><a href="api.html#serialisation">Serialisation</a></li><li class="menu item"><a href="api.html#xinclude-and-elementinclude">XInclude and ElementInclude</a></li><li class="menu item"><a href="api.html#write-c14n-on-elementtree">write_c14n on ElementTree</a></li></ul></li></ul><ul class="menu foreign" id="parsing"><li class="menu title"><a href="parsing.html">Parsing XML and HTML with lxml</a><ul class="submenu"><li class="menu item"><a href="parsing.html#parsers">Parsers</a></li><li class="menu item"><a href="parsing.html#the-target-parser-interface">The target parser interface</a></li><li class="menu item"><a href="parsing.html#the-feed-parser-interface">The feed parser interface</a></li><li class="menu item"><a href="parsing.html#iterparse-and-iterwalk">iterparse and iterwalk</a></li><li class="menu item"><a href="parsing.html#python-unicode-strings">Python unicode strings</a></li></ul></li></ul><ul class="menu foreign" id="validation"><li class="menu title"><a href="validation.html">Validation with lxml</a><ul class="submenu"><li class="menu item"><a href="validation.html#validation-at-parse-time">Validation at parse time</a></li><li class="menu item"><a href="validation.html#dtd">DTD</a></li><li class="menu item"><a href="validation.html#relaxng">RelaxNG</a></li><li class="menu item"><a href="validation.html#xmlschema">XMLSchema</a></li><li class="menu item"><a href="validation.html#schematron">Schematron</a></li></ul></li></ul><ul class="menu foreign" id="xpathxslt"><li class="menu title"><a href="xpathxslt.html">XPath and XSLT with lxml</a><ul class="submenu"><li class="menu item"><a href="xpathxslt.html#xpath">XPath</a></li><li class="menu item"><a href="xpathxslt.html#xslt">XSLT</a></li></ul></li></ul><ul class="menu foreign" id="objectify"><li class="menu title"><a href="objectify.html">lxml.objectify</a><ul class="submenu"><li class="menu item"><a href="objectify.html#the-lxml-objectify-api">The lxml.objectify API</a></li><li class="menu item"><a href="objectify.html#asserting-a-schema">Asserting a Schema</a></li><li class="menu item"><a href="objectify.html#objectpath">ObjectPath</a></li><li class="menu item"><a href="objectify.html#python-data-types">Python data types</a></li><li class="menu item"><a href="objectify.html#how-data-types-are-matched">How data types are matched</a></li><li class="menu item"><a href="objectify.html#what-is-different-from-lxml-etree?">What is different from lxml.etree?</a></li></ul></li></ul><ul class="menu current" id="lxmlhtml"><li class="menu title"><a href="lxmlhtml.html">lxml.html</a><ul class="submenu"><li class="menu item"><a href="lxmlhtml.html#parsing-html">Parsing HTML</a></li><li class="menu item"><a href="lxmlhtml.html#html-element-methods">HTML Element Methods</a></li><li class="menu item"><a href="lxmlhtml.html#running-html-doctests">Running HTML doctests</a></li><li class="menu item"><a href="lxmlhtml.html#creating-html-with-the-e-factory">Creating HTML with the E-factory</a></li><li class="menu item"><a href="lxmlhtml.html#working-with-links">Working with links</a></li><li class="menu item"><a href="lxmlhtml.html#forms">Forms</a></li><li class="menu item"><a href="lxmlhtml.html#cleaning-up-html">Cleaning up HTML</a></li><li class="menu item"><a href="lxmlhtml.html#html-diff">HTML Diff</a></li><li class="menu item"><a href="lxmlhtml.html#examples">Examples</a></li></ul></li></ul><ul class="menu foreign" id="cssselect"><li class="menu title"><a href="cssselect.html">lxml.cssselect</a><ul class="submenu"><li class="menu item"><a href="cssselect.html#the-cssselector-class">The CSSSelector class</a></li><li class="menu item"><a href="cssselect.html#css-selectors">CSS Selectors</a></li><li class="menu item"><a href="cssselect.html#limitations">Limitations</a></li></ul></li></ul><ul class="menu foreign" id="elementsoup"><li class="menu title"><a href="elementsoup.html">BeautifulSoup Parser</a><ul class="submenu"><li class="menu item"><a href="elementsoup.html#entity-handling">Entity handling</a></li><li class="menu item"><a href="elementsoup.html#using-soupparser-as-a-fallback">Using soupparser as a fallback</a></li></ul></li></ul></li></ul><ul id="Extending lxml"><li><span class="section title">Extending lxml</span><ul class="menu foreign" id="resolvers"><li class="menu title"><a href="resolvers.html">Document loading and URL resolving</a><ul class="submenu"><li class="menu item"><a href="resolvers.html#resolvers">Resolvers</a></li><li class="menu item"><a href="resolvers.html#document-loading-in-context">Document loading in context</a></li><li class="menu item"><a href="resolvers.html#i-o-access-control-in-xslt">I/O access control in XSLT</a></li></ul></li></ul><ul class="menu foreign" id="extensions"><li class="menu title"><a href="extensions.html">Extension functions for XPath and XSLT</a><ul class="submenu"><li class="menu item"><a href="extensions.html#the-functionnamespace">The FunctionNamespace</a></li><li class="menu item"><a href="extensions.html#global-prefix-assignment">Global prefix assignment</a></li><li class="menu item"><a href="extensions.html#the-xpath-context">The XPath context</a></li><li class="menu item"><a href="extensions.html#evaluators-and-xslt">Evaluators and XSLT</a></li><li class="menu item"><a href="extensions.html#evaluator-local-extensions">Evaluator-local extensions</a></li><li class="menu item"><a href="extensions.html#what-to-return-from-a-function">What to return from a function</a></li></ul></li></ul><ul class="menu foreign" id="element classes"><li class="menu title"><a href="element_classes.html">Using custom Element classes in lxml</a><ul class="submenu"><li class="menu item"><a href="element_classes.html#element-initialization">Element initialization</a></li><li class="menu item"><a href="element_classes.html#setting-up-a-class-lookup-scheme">Setting up a class lookup scheme</a></li><li class="menu item"><a href="element_classes.html#implementing-namespaces">Implementing namespaces</a></li></ul></li></ul><ul class="menu foreign" id="sax"><li class="menu title"><a href="sax.html">Sax support</a><ul class="submenu"><li class="menu item"><a href="sax.html#building-a-tree-from-sax-events">Building a tree from SAX events</a></li><li class="menu item"><a href="sax.html#producing-sax-events-from-an-elementtree-or-element">Producing SAX events from an ElementTree or Element</a></li><li class="menu item"><a href="sax.html#interfacing-with-pulldom-minidom">Interfacing with pulldom/minidom</a></li></ul></li></ul><ul class="menu foreign" id="capi"><li class="menu title"><a href="capi.html">The public C-API of lxml.etree</a><ul class="submenu"><li class="menu item"><a href="capi.html#writing-external-modules-in-cython">Writing external modules in Cython</a></li><li class="menu item"><a href="capi.html#writing-external-modules-in-c">Writing external modules in C</a></li></ul></li></ul></li></ul><ul id="Developing lxml"><li><span class="section title">Developing lxml</span><ul class="menu foreign" id="build"><li class="menu title"><a href="build.html">How to build lxml from source</a><ul class="submenu"><li class="menu item"><a href="build.html#cython">Cython</a></li><li class="menu item"><a href="build.html#subversion">Subversion</a></li><li class="menu item"><a href="build.html#setuptools">Setuptools</a></li><li class="menu item"><a href="build.html#running-the-tests-and-reporting-errors">Running the tests and reporting errors</a></li><li class="menu item"><a href="build.html#contributing-an-egg">Contributing an egg</a></li><li class="menu item"><a href="build.html#providing-newer-library-versions-on-mac-os-x">Providing newer library versions on Mac-OS X</a></li><li class="menu item"><a href="build.html#static-linking-on-windows">Static linking on Windows</a></li><li class="menu item"><a href="build.html#building-debian-packages-from-svn-sources">Building Debian packages from SVN sources</a></li></ul></li></ul><ul class="menu foreign" id="lxml source howto"><li class="menu title"><a href="lxml-source-howto.html">How to read the source of lxml</a><ul class="submenu"><li class="menu item"><a href="lxml-source-howto.html#what-is-cython?">What is Cython?</a></li><li class="menu item"><a href="lxml-source-howto.html#where-to-start?">Where to start?</a></li><li class="menu item"><a href="lxml-source-howto.html#lxml-etree">lxml.etree</a></li><li class="menu item"><a href="lxml-source-howto.html#python-modules">Python modules</a></li><li class="menu item"><a href="lxml-source-howto.html#lxml-objectify">lxml.objectify</a></li><li class="menu item"><a href="lxml-source-howto.html#lxml-pyclasslookup">lxml.pyclasslookup</a></li><li class="menu item"><a href="lxml-source-howto.html#lxml-html">lxml.html</a></li></ul></li></ul><ul class="menu foreign" id="changes 2 0 11"><li class="menu title"><a href="changes-2.0.11.html">Release Changelog</a></li></ul><ul class="menu foreign" id="credits"><li class="menu title"><a href="credits.html">Credits</a><ul class="submenu"><li class="menu item"><a href="credits.html#special-thanks-goes-to:">Special thanks goes to:</a></li></ul></li></ul></li></ul></div><h1 class="title">lxml.html</h1>
<p>Since version 2.0, lxml comes with a dedicated package for dealing
with HTML: <tt class="docutils literal"><span class="pre">lxml.html</span></tt>.  It provides a special Element API for HTML
elements, as well as a number of utilities for common tasks.</p>
<div class="contents topic">
<p class="topic-title first"><a id="contents" name="contents">Contents</a></p>
<ul class="simple">
<li><a class="reference" href="#parsing-html" id="id1" name="id1">Parsing HTML</a><ul>
<li><a class="reference" href="#parsing-html-fragments" id="id2" name="id2">Parsing HTML fragments</a></li>
<li><a class="reference" href="#really-broken-pages" id="id3" name="id3">Really broken pages</a></li>
</ul>
</li>
<li><a class="reference" href="#html-element-methods" id="id4" name="id4">HTML Element Methods</a></li>
<li><a class="reference" href="#running-html-doctests" id="id5" name="id5">Running HTML doctests</a></li>
<li><a class="reference" href="#creating-html-with-the-e-factory" id="id6" name="id6">Creating HTML with the E-factory</a><ul>
<li><a class="reference" href="#viewing-your-html" id="id7" name="id7">Viewing your HTML</a></li>
</ul>
</li>
<li><a class="reference" href="#working-with-links" id="id8" name="id8">Working with links</a><ul>
<li><a class="reference" href="#functions" id="id9" name="id9">Functions</a></li>
</ul>
</li>
<li><a class="reference" href="#forms" id="id10" name="id10">Forms</a><ul>
<li><a class="reference" href="#form-filling-example" id="id11" name="id11">Form Filling Example</a></li>
<li><a class="reference" href="#form-submission" id="id12" name="id12">Form Submission</a></li>
</ul>
</li>
<li><a class="reference" href="#cleaning-up-html" id="id13" name="id13">Cleaning up HTML</a><ul>
<li><a class="reference" href="#autolink" id="id14" name="id14">autolink</a></li>
<li><a class="reference" href="#wordwrap" id="id15" name="id15">wordwrap</a></li>
</ul>
</li>
<li><a class="reference" href="#html-diff" id="id16" name="id16">HTML Diff</a></li>
<li><a class="reference" href="#examples" id="id17" name="id17">Examples</a><ul>
<li><a class="reference" href="#microformat-example" id="id18" name="id18">Microformat Example</a></li>
</ul>
</li>
</ul>
</div>
<p>The main API is based on the <a class="reference" href="tutorial.html">lxml.etree</a> API, and thus, on the <a class="reference" href="http://effbot.org/zone/element-index.htm">ElementTree</a>
API.</p>
<div class="section">
<h1><a id="parsing-html" name="parsing-html">Parsing HTML</a></h1>
<div class="section">
<h2><a id="parsing-html-fragments" name="parsing-html-fragments">Parsing HTML fragments</a></h2>
<p>There are several functions available to parse HTML:</p>
<dl class="docutils">
<dt><tt class="docutils literal"><span class="pre">parse(filename_url_or_file)</span></tt>:</dt>
<dd><p class="first">Parses the named file or url, or if the object has a <tt class="docutils literal"><span class="pre">.read()</span></tt>
method, parses from that.</p>
<p class="last">If you give a URL, or if the object has a <tt class="docutils literal"><span class="pre">.geturl()</span></tt> method (as
file-like objects from <tt class="docutils literal"><span class="pre">urllib.urlopen()</span></tt> have), then that URL
is used as the base URL.  You can also provide an explicit
<tt class="docutils literal"><span class="pre">base_url</span></tt> keyword argument.</p>
</dd>
<dt><tt class="docutils literal"><span class="pre">document_fromstring(string)</span></tt>:</dt>
<dd>Parses a document from the given string.  This always creates a
correct HTML document, which means the parent node is <tt class="docutils literal"><span class="pre">&lt;html&gt;</span></tt>,
and there is a body and possibly a head.</dd>
<dt><tt class="docutils literal"><span class="pre">fragment_fromstring(string,</span> <span class="pre">create_parent=False)</span></tt>:</dt>
<dd>Returns an HTML fragment from a string.  The fragment must contain
just a single element, unless <tt class="docutils literal"><span class="pre">create_parent</span></tt> is given;
e.g,. <tt class="docutils literal"><span class="pre">fragment_fromstring(string,</span> <span class="pre">create_parent='div')</span></tt> will
wrap the element in a <tt class="docutils literal"><span class="pre">&lt;div&gt;</span></tt>.</dd>
<dt><tt class="docutils literal"><span class="pre">fragments_fromstring(string)</span></tt>:</dt>
<dd>Returns a list of the elements found in the fragment.</dd>
<dt><tt class="docutils literal"><span class="pre">fromstring(string)</span></tt>:</dt>
<dd>Returns <tt class="docutils literal"><span class="pre">document_fromstring</span></tt> or <tt class="docutils literal"><span class="pre">fragment_fromstring</span></tt>, based
on whether the string looks like a full document, or just a
fragment.</dd>
</dl>
</div>
<div class="section">
<h2><a id="really-broken-pages" name="really-broken-pages">Really broken pages</a></h2>
<p>The normal HTML parser is capable of handling broken HTML, but for
pages that are far enough from HTML to call them 'tag soup', it may
still fail to parse the page.  A way to deal with this is
<a class="reference" href="elementsoup.html">ElementSoup</a>, which deploys the well-known <a class="reference" href="http://www.crummy.com/software/BeautifulSoup/">BeautifulSoup</a> parser to
build an lxml HTML tree.</p>
</div>
</div>
<div class="section">
<h1><a id="html-element-methods" name="html-element-methods">HTML Element Methods</a></h1>
<p>HTML elements have all the methods that come with ElementTree, but
also include some extra methods:</p>
<dl class="docutils">
<dt><tt class="docutils literal"><span class="pre">.drop_tree()</span></tt>:</dt>
<dd>Drops the element and all its children.  Unlike
<tt class="docutils literal"><span class="pre">el.getparent().remove(el)</span></tt> this does <em>not</em> remove the tail
text; with <tt class="docutils literal"><span class="pre">drop_tree</span></tt> the tail text is merged with the previous
element.</dd>
<dt><tt class="docutils literal"><span class="pre">.drop_tag()</span></tt>:</dt>
<dd>Drops the tag, but keeps its children and text.</dd>
<dt><tt class="docutils literal"><span class="pre">.find_class(class_name)</span></tt>:</dt>
<dd>Returns a list of all the elements with the given CSS class name.
Note that class names are space separated in HTML, so
<tt class="docutils literal"><span class="pre">doc.find_class_name('highlight')</span></tt> will find an element like
<tt class="docutils literal"><span class="pre">&lt;div</span> <span class="pre">class="sidebar</span> <span class="pre">highlight"&gt;</span></tt>.  Class names <em>are</em> case
sensitive.</dd>
<dt><tt class="docutils literal"><span class="pre">.find_rel_links(rel)</span></tt>:</dt>
<dd>Returns a list of all the <tt class="docutils literal"><span class="pre">&lt;a</span> <span class="pre">rel="{rel}"&gt;</span></tt> elements.  E.g.,
<tt class="docutils literal"><span class="pre">doc.find_rel_links('tag')</span></tt> returns all the links <a class="reference" href="http://microformats.org/wiki/rel-tag">marked as
tags</a>.</dd>
<dt><tt class="docutils literal"><span class="pre">.get_element_by_id(id,</span> <span class="pre">default=None)</span></tt>:</dt>
<dd>Return the element with the given <tt class="docutils literal"><span class="pre">id</span></tt>, or the <tt class="docutils literal"><span class="pre">default</span></tt> if
none is found.  If there are multiple elements with the same id
(which there shouldn't be, but there often is), this returns only
the first.</dd>
<dt><tt class="docutils literal"><span class="pre">.text_content()</span></tt>:</dt>
<dd>Returns the text content of the element, including the text
content of its children, with no markup.</dd>
<dt><tt class="docutils literal"><span class="pre">.cssselect(expr)</span></tt>:</dt>
<dd>Select elements from this element and its children, using a CSS
selector expression.  (Note that <tt class="docutils literal"><span class="pre">.xpath(expr)</span></tt> is also
available as on all lxml elements.)</dd>
<dt><tt class="docutils literal"><span class="pre">.label</span></tt>:</dt>
<dd>Returns the corresponding <tt class="docutils literal"><span class="pre">&lt;label&gt;</span></tt> element for this element, if
any exists (None if there is none).  Label elements have a
<tt class="docutils literal"><span class="pre">label.for_element</span></tt> attribute that points back to the element.</dd>
<dt><tt class="docutils literal"><span class="pre">.base_url</span></tt>:</dt>
<dd>The base URL for this element, if one was saved from the parsing.
This attribute is not settable.  Is None when no base URL was
saved.</dd>
</dl>
</div>
<div class="section">
<h1><a id="running-html-doctests" name="running-html-doctests">Running HTML doctests</a></h1>
<p>One of the interesting modules in the <tt class="docutils literal"><span class="pre">lxml.html</span></tt> package deals with
doctests.  It can be hard to compare two HTML pages for equality, as
whitespace differences aren't meaningful and the structural formatting
can differ.  This is even more a problem in doctests, where output is
tested for equality and small differences in whitespace or the order
of attributes can let a test fail.  And given the verbosity of
tag-based languages, it may take more than a quick look to find the
actual differences in the doctest output.</p>
<p>Luckily, lxml provides the <tt class="docutils literal"><span class="pre">lxml.doctestcompare</span></tt> module that
supports relaxed comparison of XML and HTML pages and provides a
readable diff in the output when a test fails.  The HTML comparison is
most easily used by importing the <tt class="docutils literal"><span class="pre">usedoctest</span></tt> module in a doctest:</p>
<pre class="literal-block">
&gt;&gt;&gt; import lxml.html.usedoctest
</pre>
<p>Now, if you have a HTML document and want to compare it to an expected result
document in a doctest, you can do the following:</p>
<pre class="literal-block">
&gt;&gt;&gt; import lxml.html
&gt;&gt;&gt; html = lxml.html.fromstring('''\
...    &lt;html&gt;&lt;body onload="" color="white"&gt;
...      &lt;p&gt;Hi  !&lt;/p&gt;
...    &lt;/body&gt;&lt;/html&gt;
... ''')

&gt;&gt;&gt; print lxml.html.tostring(html)
&lt;html&gt;&lt;body onload="" color="white"&gt;&lt;p&gt;Hi !&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;

&gt;&gt;&gt; print lxml.html.tostring(html)
&lt;html&gt; &lt;body color="white" onload=""&gt; &lt;p&gt;Hi    !&lt;/p&gt; &lt;/body&gt; &lt;/html&gt;

&gt;&gt;&gt; print lxml.html.tostring(html)
&lt;html&gt;
  &lt;body color="white" onload=""&gt;
    &lt;p&gt;Hi !&lt;/p&gt;
  &lt;/body&gt;
&lt;/html&gt;
</pre>
<p>In documentation, you would likely prefer the pretty printed HTML output, as
it is the most readable.  However, the three documents are equivalent from the
point of view of an HTML tool, so the doctest will silently accept any of the
above.  This allows you to concentrate on readability in your doctests, even
if the real output is a straight ugly HTML one-liner.</p>
<p>Note that there is also an <tt class="docutils literal"><span class="pre">lxml.usedoctest</span></tt> module which you can
import for XML comparisons.  The HTML parser notably ignores
namespaces and some other XMLisms.</p>
</div>
<div class="section">
<h1><a id="creating-html-with-the-e-factory" name="creating-html-with-the-e-factory">Creating HTML with the E-factory</a></h1>
<p>lxml.html comes with a predefined HTML vocabulary for the <a class="reference" href="http://online.effbot.org/2006_11_01_archive.htm#et-builder">E-factory</a>,
originally written by Fredrik Lundh.  This allows you to quickly generate HTML
pages and fragments:</p>
<pre class="literal-block">
&gt;&gt;&gt; from lxml.html import builder as E
&gt;&gt;&gt; from lxml.html import usedoctest
&gt;&gt;&gt; html = E.HTML(
...   E.HEAD(
...     E.LINK(rel="stylesheet", href="great.css", type="text/css"),
...     E.TITLE("Best Page Ever")
...   ),
...   E.BODY(
...     E.H1(E.CLASS("heading"), "Top News"),
...     E.P("World News only on this page", style="font-size: 200%"),
...     "Ah, and here's some more text, by the way.",
...     lxml.html.fromstring("&lt;p&gt;... and this is a parsed fragment ...&lt;/p&gt;")
...   )
... )

&gt;&gt;&gt; print lxml.html.tostring(html)
&lt;html&gt;
  &lt;head&gt;
    &lt;link href="great.css" rel="stylesheet" type="text/css"&gt;
    &lt;title&gt;Best Page Ever&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;h1 class="heading"&gt;Top News&lt;/h1&gt;
    &lt;p style="font-size: 200%"&gt;World News only on this page&lt;/p&gt;
    Ah, and here's some more text, by the way.
    &lt;p&gt;... and this is a parsed fragment ...&lt;/p&gt;
  &lt;/body&gt;
&lt;/html&gt;
</pre>
<p>Note that you should use <tt class="docutils literal"><span class="pre">lxml.html.tostring</span></tt> and <strong>not</strong>
<tt class="docutils literal"><span class="pre">lxml.tostring</span></tt>.  <tt class="docutils literal"><span class="pre">lxml.tostring(doc)</span></tt> will return the XML
representation of the document, which is not valid HTML.  In
particular, things like <tt class="docutils literal"><span class="pre">&lt;script</span> <span class="pre">src="..."&gt;&lt;/script&gt;</span></tt> will be
serialized as <tt class="docutils literal"><span class="pre">&lt;script</span> <span class="pre">src="..."</span> <span class="pre">/&gt;</span></tt>, which completely confuses
browsers.</p>
<div class="section">
<h2><a id="viewing-your-html" name="viewing-your-html">Viewing your HTML</a></h2>
<p>A handy method for viewing your HTML:
<tt class="docutils literal"><span class="pre">lxml.html.open_in_browser(lxml_doc)</span></tt> will write the document to
disk and open it in a browser (with the <a class="reference" href="http://python.org/doc/current/lib/module-webbrowser.html">webbrowser module</a>).</p>
</div>
</div>
<div class="section">
<h1><a id="working-with-links" name="working-with-links">Working with links</a></h1>
<p>There are several methods on elements that allow you to see and modify
the links in a document.</p>
<dl class="docutils">
<dt><tt class="docutils literal"><span class="pre">.iterlinks()</span></tt>:</dt>
<dd><p class="first">This yields <tt class="docutils literal"><span class="pre">(element,</span> <span class="pre">attribute,</span> <span class="pre">link,</span> <span class="pre">pos)</span></tt> for every link in
the document.  <tt class="docutils literal"><span class="pre">attribute</span></tt> may be None if the link is in the
text (as will be the case with a <tt class="docutils literal"><span class="pre">&lt;style&gt;</span></tt> tag with
<tt class="docutils literal"><span class="pre">@import</span></tt>).</p>
<p>This finds any link in an <tt class="docutils literal"><span class="pre">action</span></tt>, <tt class="docutils literal"><span class="pre">archive</span></tt>, <tt class="docutils literal"><span class="pre">background</span></tt>,
<tt class="docutils literal"><span class="pre">cite</span></tt>, <tt class="docutils literal"><span class="pre">classid</span></tt>, <tt class="docutils literal"><span class="pre">codebase</span></tt>, <tt class="docutils literal"><span class="pre">data</span></tt>, <tt class="docutils literal"><span class="pre">href</span></tt>,
<tt class="docutils literal"><span class="pre">longdesc</span></tt>, <tt class="docutils literal"><span class="pre">profile</span></tt>, <tt class="docutils literal"><span class="pre">src</span></tt>, <tt class="docutils literal"><span class="pre">usemap</span></tt>, <tt class="docutils literal"><span class="pre">dynsrc</span></tt>, or
<tt class="docutils literal"><span class="pre">lowsrc</span></tt> attribute.  It also searches <tt class="docutils literal"><span class="pre">style</span></tt> attributes for
<tt class="docutils literal"><span class="pre">url(link)</span></tt>, and <tt class="docutils literal"><span class="pre">&lt;style&gt;</span></tt> tags for <tt class="docutils literal"><span class="pre">@import</span></tt> and <tt class="docutils literal"><span class="pre">url()</span></tt>.</p>
<p class="last">This function does <em>not</em> pay attention to <tt class="docutils literal"><span class="pre">&lt;base</span> <span class="pre">href&gt;</span></tt>.</p>
</dd>
<dt><tt class="docutils literal"><span class="pre">.resolve_base_href()</span></tt>:</dt>
<dd>This function will modify the document in-place to take account of
<tt class="docutils literal"><span class="pre">&lt;base</span> <span class="pre">href&gt;</span></tt> if the document contains that tag.  In the process
it will also remove that tag from the document.</dd>
<dt><tt class="docutils literal"><span class="pre">.make_links_absolute(base_href,</span> <span class="pre">resolve_base_href=True)</span></tt>:</dt>
<dd><p class="first">This makes all links in the document absolute, assuming that
<tt class="docutils literal"><span class="pre">base_href</span></tt> is the URL of the document.  So if you pass
<tt class="docutils literal"><span class="pre">base_href="http://localhost/foo/bar.html"</span></tt> and there is a link
to <tt class="docutils literal"><span class="pre">baz.html</span></tt> that will be rewritten as
<tt class="docutils literal"><span class="pre">http://localhost/foo/baz.html</span></tt>.</p>
<p class="last">If <tt class="docutils literal"><span class="pre">resolve_base_href</span></tt> is true, then any <tt class="docutils literal"><span class="pre">&lt;base</span> <span class="pre">href&gt;</span></tt> tag
will be taken into account (just calling
<tt class="docutils literal"><span class="pre">self.resolve_base_href()</span></tt>).</p>
</dd>
<dt><tt class="docutils literal"><span class="pre">.rewrite_links(link_repl_func,</span> <span class="pre">resolve_base_href=True,</span> <span class="pre">base_href=None)</span></tt>:</dt>
<dd><p class="first">This rewrites all the links in the document using your given link
replacement function.  If you give a <tt class="docutils literal"><span class="pre">base_href</span></tt> value, all
links will be passed in after they are joined with this URL.</p>
<p>For each link <tt class="docutils literal"><span class="pre">link_repl_func(link)</span></tt> is called.  That function
then returns the new link, or None to remove the attribute or tag
that contains the link.  Note that all links will be passed in,
including links like <tt class="docutils literal"><span class="pre">"#anchor"</span></tt> (which is purely internal), and
things like <tt class="docutils literal"><span class="pre">"mailto:bob@example.com"</span></tt> (or <tt class="docutils literal"><span class="pre">javascript:...</span></tt>).</p>
<p class="last">If you want access to the context of the link, you should use
<tt class="docutils literal"><span class="pre">.iterlinks()</span></tt> instead.</p>
</dd>
</dl>
<div class="section">
<h2><a id="functions" name="functions">Functions</a></h2>
<p>In addition to these methods, there are corresponding functions:</p>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">iterlinks(html)</span></tt></li>
<li><tt class="docutils literal"><span class="pre">make_links_absolute(html,</span> <span class="pre">base_href,</span> <span class="pre">...)</span></tt></li>
<li><tt class="docutils literal"><span class="pre">rewrite_links(html,</span> <span class="pre">link_repl_func,</span> <span class="pre">...)</span></tt></li>
<li><tt class="docutils literal"><span class="pre">resolve_base_href(html)</span></tt></li>
</ul>
<p>These functions will parse <tt class="docutils literal"><span class="pre">html</span></tt> if it is a string, then return the new
HTML as a string.  If you pass in a document, the document will be copied
(except for <tt class="docutils literal"><span class="pre">iterlinks()</span></tt>), the method performed, and the new document
returned.</p>
</div>
</div>
<div class="section">
<h1><a id="forms" name="forms">Forms</a></h1>
<p>Any <tt class="docutils literal"><span class="pre">&lt;form&gt;</span></tt> elements in a document are available through
the list <tt class="docutils literal"><span class="pre">doc.forms</span></tt> (e.g., <tt class="docutils literal"><span class="pre">doc.forms[0]</span></tt>).  Form, input, select,
and textarea elements each have special methods.</p>
<p>Input elements (including <tt class="docutils literal"><span class="pre">&lt;select&gt;</span></tt> and <tt class="docutils literal"><span class="pre">&lt;textarea&gt;</span></tt>) have these
attributes:</p>
<dl class="docutils">
<dt><tt class="docutils literal"><span class="pre">.name</span></tt>:</dt>
<dd>The name of the element.</dd>
<dt><tt class="docutils literal"><span class="pre">.value</span></tt>:</dt>
<dd><p class="first">The value of an input, the content of a textarea, the selected
option(s) of a select.  This attribute can be set.</p>
<p class="last">In the case of a select that takes multiple options (<tt class="docutils literal"><span class="pre">&lt;select</span>
<span class="pre">multiple&gt;</span></tt>) this will be a set of the selected options; you can
add or remove items to select and unselect the options.</p>
</dd>
</dl>
<p>Select attributes:</p>
<dl class="docutils">
<dt><tt class="docutils literal"><span class="pre">.value_options</span></tt>:</dt>
<dd>For select elements, this is all the <em>possible</em> values (the values
of all the options).</dd>
<dt><tt class="docutils literal"><span class="pre">.multiple</span></tt>:</dt>
<dd>For select elements, true if this is a <tt class="docutils literal"><span class="pre">&lt;select</span> <span class="pre">multiple&gt;</span></tt>
element.</dd>
</dl>
<p>Input attributes:</p>
<dl class="docutils">
<dt><tt class="docutils literal"><span class="pre">.type</span></tt>:</dt>
<dd>The type attribute in <tt class="docutils literal"><span class="pre">&lt;input&gt;</span></tt> elements.</dd>
<dt><tt class="docutils literal"><span class="pre">.checkable</span></tt>:</dt>
<dd>True if this can be checked (i.e., true for type=radio and
type=checkbox).</dd>
<dt><tt class="docutils literal"><span class="pre">.checked</span></tt>:</dt>
<dd>If this element is checkable, the checked state.  Raises
AttributeError on non-checkable inputs.</dd>
</dl>
<p>The form itself has these attributes:</p>
<dl class="docutils">
<dt><tt class="docutils literal"><span class="pre">.inputs</span></tt>:</dt>
<dd>A dictionary-like object that can be used to access input elements
by name.  When there are multiple input elements with the same
name, this returns list-like structures that can also be used to
access the options and their values as a group.</dd>
<dt><tt class="docutils literal"><span class="pre">.fields</span></tt>:</dt>
<dd><p class="first">A dictionary-like object used to access <em>values</em> by their name.
<tt class="docutils literal"><span class="pre">form.inputs</span></tt> returns elements, this only returns values.
Setting values in this dictionary will effect the form inputs.
Basically <tt class="docutils literal"><span class="pre">form.fields[x]</span></tt> is equivalent to
<tt class="docutils literal"><span class="pre">form.inputs[x].value</span></tt> and <tt class="docutils literal"><span class="pre">form.fields[x]</span> <span class="pre">=</span> <span class="pre">y</span></tt> is equivalent
to <tt class="docutils literal"><span class="pre">form.inputs[x].value</span> <span class="pre">=</span> <span class="pre">y</span></tt>.  (Note that sometimes
<tt class="docutils literal"><span class="pre">form.inputs[x]</span></tt> returns a compound object, but these objects
also have <tt class="docutils literal"><span class="pre">.value</span></tt> attributes.)</p>
<p class="last">If you set this attribute, it is equivalent to
<tt class="docutils literal"><span class="pre">form.fields.clear();</span> <span class="pre">form.fields.update(new_value)</span></tt></p>
</dd>
<dt><tt class="docutils literal"><span class="pre">.form_values()</span></tt>:</dt>
<dd>Returns a list of <tt class="docutils literal"><span class="pre">[(name,</span> <span class="pre">value),</span> <span class="pre">...]</span></tt>, suitable to be passed
to <tt class="docutils literal"><span class="pre">urllib.urlencode()</span></tt> for form submission.</dd>
<dt><tt class="docutils literal"><span class="pre">.action</span></tt>:</dt>
<dd>The <tt class="docutils literal"><span class="pre">action</span></tt> attribute.  This is resolved to an absolute URL if
possible.</dd>
<dt><tt class="docutils literal"><span class="pre">.method</span></tt>:</dt>
<dd>The <tt class="docutils literal"><span class="pre">method</span></tt> attribute, which defaults to <tt class="docutils literal"><span class="pre">GET</span></tt>.</dd>
</dl>
<div class="section">
<h2><a id="form-filling-example" name="form-filling-example">Form Filling Example</a></h2>
<p>Note that you can change any of these attributes (values, method,
action, etc) and then serialize the form to see the updated values.
You can, for instance, do:</p>
<pre class="literal-block">
&gt;&gt;&gt; from lxml.html import fromstring, tostring
&gt;&gt;&gt; form_page = fromstring('''&lt;html&gt;&lt;body&gt;&lt;form&gt;
...   Your name: &lt;input type="text" name="name"&gt; &lt;br&gt;
...   Your phone: &lt;input type="text" name="phone"&gt; &lt;br&gt;
...   Your favorite pets: &lt;br&gt;
...   Dogs: &lt;input type="checkbox" name="interest" value="dogs"&gt; &lt;br&gt;
...   Cats: &lt;input type="checkbox" name="interest" value="cats"&gt; &lt;br&gt;
...   Llamas: &lt;input type="checkbox" name="interest" value="llamas"&gt; &lt;br&gt;
...   &lt;input type="submit"&gt;&lt;/form&gt;&lt;/body&gt;&lt;/html&gt;''')
&gt;&gt;&gt; form = form_page.forms[0]
&gt;&gt;&gt; form.fields = dict(
...     name='John Smith',
...     phone='555-555-3949',
...     interest=set(['cats', 'llamas']))
&gt;&gt;&gt; print tostring(form)
&lt;html&gt;
  &lt;body&gt;
    &lt;form&gt;
    Your name:
      &lt;input name="name" type="text" value="John Smith"&gt;
      &lt;br&gt;Your phone:
      &lt;input name="phone" type="text" value="555-555-3949"&gt;
      &lt;br&gt;Your favorite pets:
      &lt;br&gt;Dogs:
      &lt;input name="interest" type="checkbox" value="dogs"&gt;
      &lt;br&gt;Cats:
      &lt;input checked name="interest" type="checkbox" value="cats"&gt;
      &lt;br&gt;Llamas:
      &lt;input checked name="interest" type="checkbox" value="llamas"&gt;
      &lt;br&gt;
      &lt;input type="submit"&gt;
    &lt;/form&gt;
  &lt;/body&gt;
&lt;/html&gt;
</pre>
</div>
<div class="section">
<h2><a id="form-submission" name="form-submission">Form Submission</a></h2>
<p>You can submit a form with <tt class="docutils literal"><span class="pre">lxml.html.submit_form(form_element)</span></tt>.
This will return a file-like object (the result of
<tt class="docutils literal"><span class="pre">urllib.urlopen()</span></tt>).</p>
<p>If you have extra input values you want to pass you can use the
keyword argument <tt class="docutils literal"><span class="pre">extra_values</span></tt>, like <tt class="docutils literal"><span class="pre">extra_values={'submit':</span>
<span class="pre">'Yes!'}</span></tt>.  This is the only way to get submit values into the form,
as there is no state of "submitted" for these elements.</p>
<p>You can pass in an alternate opener with the <tt class="docutils literal"><span class="pre">open_http</span></tt> keyword
argument, which is a function with the signature <tt class="docutils literal"><span class="pre">open_http(method,</span>
<span class="pre">url,</span> <span class="pre">values)</span></tt>.</p>
<p>Example:</p>
<pre class="literal-block">
&gt;&gt;&gt; from lxml.html import parse, submit_form
&gt;&gt;&gt; page = parse('http://tinyurl.com').getroot()
&gt;&gt;&gt; page.forms[1].fields['url'] = 'http://codespeak.net/lxml/'
&gt;&gt;&gt; result = parse(submit_form(page.forms[1])).getroot()
&gt;&gt;&gt; [a.attrib['href'] for a in result.xpath("//a[@target='_blank']")]
['http://tinyurl.com/2xae8s', 'http://preview.tinyurl.com/2xae8s']
</pre>
</div>
</div>
<div class="section">
<h1><a id="cleaning-up-html" name="cleaning-up-html">Cleaning up HTML</a></h1>
<p>The module <tt class="docutils literal"><span class="pre">lxml.html.clean</span></tt> provides a <tt class="docutils literal"><span class="pre">Cleaner</span></tt> class for cleaning up
HTML pages.  It supports removing embedded or script content, special tags,
CSS style annotations and much more.</p>
<p>Say, you have an evil web page from an untrusted source that contains lots of
content that upsets browsers and tries to run evil code on the client side:</p>
<pre class="literal-block">
&gt;&gt;&gt; html = '''\
... &lt;html&gt;
...  &lt;head&gt;
...    &lt;script type="text/javascript" src="evil-site"&gt;&lt;/script&gt;
...    &lt;link rel="alternate" type="text/rss" src="evil-rss"&gt;
...    &lt;style&gt;
...      body {background-image: url(javascript:do_evil)};
...      div {color: expression(evil)};
...    &lt;/style&gt;
...  &lt;/head&gt;
...  &lt;body onload="evil_function()"&gt;
...    &lt;!-- I am interpreted for EVIL! --&gt;
...    &lt;a href="javascript:evil_function()"&gt;a link&lt;/a&gt;
...    &lt;a href="#" onclick="evil_function()"&gt;another link&lt;/a&gt;
...    &lt;p onclick="evil_function()"&gt;a paragraph&lt;/p&gt;
...    &lt;div style="display: none"&gt;secret EVIL!&lt;/div&gt;
...    &lt;object&gt; of EVIL! &lt;/object&gt;
...    &lt;iframe src="evil-site"&gt;&lt;/iframe&gt;
...    &lt;form action="evil-site"&gt;
...      Password: &lt;input type="password" name="password"&gt;
...    &lt;/form&gt;
...    &lt;blink&gt;annoying EVIL!&lt;/blink&gt;
...    &lt;a href="evil-site"&gt;spam spam SPAM!&lt;/a&gt;
...    &lt;image src="evil!"&gt;
...  &lt;/body&gt;
... &lt;/html&gt;'''
</pre>
<p>To remove the all suspicious content from this unparsed document, use the
<tt class="docutils literal"><span class="pre">clean_html</span></tt> function:</p>
<pre class="literal-block">
&gt;&gt;&gt; from lxml.html.clean import clean_html

&gt;&gt;&gt; print clean_html(html)
&lt;html&gt;
  &lt;body&gt;
    &lt;div&gt;
      &lt;style&gt;/* deleted */&lt;/style&gt;
      &lt;a href=""&gt;a link&lt;/a&gt;
      &lt;a href="#"&gt;another link&lt;/a&gt;
      &lt;p&gt;a paragraph&lt;/p&gt;
      &lt;div&gt;secret EVIL!&lt;/div&gt;
      of EVIL!
      Password:
      annoying EVIL!
      &lt;a href="evil-site"&gt;spam spam SPAM!&lt;/a&gt;
      &lt;img src="evil!"&gt;
    &lt;/div&gt;
  &lt;/body&gt;
&lt;/html&gt;
</pre>
<p>The <tt class="docutils literal"><span class="pre">Cleaner</span></tt> class supports several keyword arguments to control exactly
which content is removed:</p>
<pre class="literal-block">
&gt;&gt;&gt; from lxml.html.clean import Cleaner

&gt;&gt;&gt; cleaner = Cleaner(page_structure=False, links=False)
&gt;&gt;&gt; print cleaner.clean_html(html)
&lt;html&gt;
  &lt;head&gt;
    &lt;link rel="alternate" src="evil-rss" type="text/rss"&gt;
    &lt;style&gt;/* deleted */&lt;/style&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;a href=""&gt;a link&lt;/a&gt;
    &lt;a href="#"&gt;another link&lt;/a&gt;
    &lt;p&gt;a paragraph&lt;/p&gt;
    &lt;div&gt;secret EVIL!&lt;/div&gt;
    of EVIL!
    Password:
    annoying EVIL!
    &lt;a href="evil-site"&gt;spam spam SPAM!&lt;/a&gt;
    &lt;img src="evil!"&gt;
  &lt;/body&gt;
&lt;/html&gt;

&gt;&gt;&gt; cleaner = Cleaner(style=True, links=True, add_nofollow=True,
...                   page_structure=False, safe_attrs_only=False)

&gt;&gt;&gt; print cleaner.clean_html(html)
&lt;html&gt;
  &lt;head&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;a href=""&gt;a link&lt;/a&gt;
    &lt;a href="#"&gt;another link&lt;/a&gt;
    &lt;p&gt;a paragraph&lt;/p&gt;
    &lt;div&gt;secret EVIL!&lt;/div&gt;
    of EVIL!
    Password:
    annoying EVIL!
    &lt;a href="evil-site" rel="nofollow"&gt;spam spam SPAM!&lt;/a&gt;
    &lt;img src="evil!"&gt;
  &lt;/body&gt;
&lt;/html&gt;
</pre>
<p>You can also whitelist some otherwise dangerous content with
<tt class="docutils literal"><span class="pre">Cleaner(host_whitelist=['www.youtube.com'])</span></tt>, which would allow
embedded media from YouTube, while still filtering out embedded media
from other sites.</p>
<p>See the docstring of <tt class="docutils literal"><span class="pre">Cleaner</span></tt> for the details of what can be
cleaned.</p>
<div class="section">
<h2><a id="autolink" name="autolink">autolink</a></h2>
<p>In addition to cleaning up malicious HTML, <tt class="docutils literal"><span class="pre">lxml.html.clean</span></tt>
contains functions to do other things to your HTML.  This includes
autolinking:</p>
<pre class="literal-block">
autolink(doc, ...)

autolink_html(html, ...)
</pre>
<p>This finds anything that looks like a link (e.g.,
<tt class="docutils literal"><span class="pre">http://example.com</span></tt>) in the <em>text</em> of an HTML document, and
turns it into an anchor.  It avoids making bad links.</p>
<p>Links in the elements <tt class="docutils literal"><span class="pre">&lt;textarea&gt;</span></tt>, <tt class="docutils literal"><span class="pre">&lt;pre&gt;</span></tt>, <tt class="docutils literal"><span class="pre">&lt;code&gt;</span></tt>,
anything in the head of the document.  You can pass in a list of
elements to avoid in <tt class="docutils literal"><span class="pre">avoid_elements=['textarea',</span> <span class="pre">...]</span></tt>.</p>
<p>Links to some hosts can be avoided.  By default links to
<tt class="docutils literal"><span class="pre">localhost*</span></tt>, <tt class="docutils literal"><span class="pre">example.*</span></tt> and <tt class="docutils literal"><span class="pre">127.0.0.1</span></tt> are not
autolinked.  Pass in <tt class="docutils literal"><span class="pre">avoid_hosts=[list_of_regexes]</span></tt> to control
this.</p>
<p>Elements with the <tt class="docutils literal"><span class="pre">nolink</span></tt> CSS class are not autolinked.  Pass
in <tt class="docutils literal"><span class="pre">avoid_classes=['code',</span> <span class="pre">...]</span></tt> to control this.</p>
<p>The <tt class="docutils literal"><span class="pre">autolink_html()</span></tt> version of the function parses the HTML
string first, and returns a string.</p>
</div>
<div class="section">
<h2><a id="wordwrap" name="wordwrap">wordwrap</a></h2>
<p>You can also wrap long words in your html:</p>
<pre class="literal-block">
word_break(doc, max_width=40, ...)

word_break_html(html, ...)
</pre>
<p>This finds any long words in the text of the document and inserts
<tt class="docutils literal"><span class="pre">&amp;#8203;</span></tt> in the document (which is the Unicode zero-width space).</p>
<p>This avoids the elements <tt class="docutils literal"><span class="pre">&lt;pre&gt;</span></tt>, <tt class="docutils literal"><span class="pre">&lt;textarea&gt;</span></tt>, and <tt class="docutils literal"><span class="pre">&lt;code&gt;</span></tt>.
You can control this with <tt class="docutils literal"><span class="pre">avoid_elements=['textarea',</span> <span class="pre">...]</span></tt>.</p>
<p>It also avoids elements with the CSS class <tt class="docutils literal"><span class="pre">nobreak</span></tt>.  You can
control this with <tt class="docutils literal"><span class="pre">avoid_classes=['code',</span> <span class="pre">...]</span></tt>.</p>
<p>Lastly you can control the character that is inserted with
<tt class="docutils literal"><span class="pre">break_character=u'\u200b'</span></tt>.  However, you cannot insert markup,
only text.</p>
<p><tt class="docutils literal"><span class="pre">word_break_html(html)</span></tt> parses the HTML document and returns a
string.</p>
</div>
</div>
<div class="section">
<h1><a id="html-diff" name="html-diff">HTML Diff</a></h1>
<p>The module <tt class="docutils literal"><span class="pre">lxml.html.diff</span></tt> offers some ways to visualize
differences in HTML documents.  These differences are <em>content</em>
oriented.  That is, changes in markup are largely ignored; only
changes in the content itself are highlighted.</p>
<p>There are two ways to view differences: <tt class="docutils literal"><span class="pre">htmldiff</span></tt> and
<tt class="docutils literal"><span class="pre">html_annotate</span></tt>.  One shows differences with <tt class="docutils literal"><span class="pre">&lt;ins&gt;</span></tt> and
<tt class="docutils literal"><span class="pre">&lt;del&gt;</span></tt>, while the other annotates a set of changes similar to <tt class="docutils literal"><span class="pre">svn</span>
<span class="pre">blame</span></tt>.  Both these functions operate on text, and work best with
content fragments (only what goes in <tt class="docutils literal"><span class="pre">&lt;body&gt;</span></tt>), not complete
documents.</p>
<p>Example of <tt class="docutils literal"><span class="pre">htmldiff</span></tt>:</p>
<blockquote>
<pre class="doctest-block">
&gt;&gt;&gt; from lxml.html.diff import htmldiff, html_annotate
&gt;&gt;&gt; doc1 = '''&lt;p&gt;Here is some text.&lt;/p&gt;'''
&gt;&gt;&gt; doc2 = '''&lt;p&gt;Here is &lt;b&gt;a lot&lt;/b&gt; of &lt;i&gt;text&lt;/i&gt;.&lt;/p&gt;'''
&gt;&gt;&gt; doc3 = '''&lt;p&gt;Here is &lt;b&gt;a little&lt;/b&gt; &lt;i&gt;text&lt;/i&gt;.&lt;/p&gt;'''
&gt;&gt;&gt; print htmldiff(doc1, doc2)
&lt;p&gt;Here is &lt;ins&gt;&lt;b&gt;a lot&lt;/b&gt; of &lt;i&gt;text&lt;/i&gt;.&lt;/ins&gt; &lt;del&gt;some text.&lt;/del&gt; &lt;/p&gt;
&gt;&gt;&gt; print html_annotate([(doc1, 'author1'), (doc2, 'author2'),
...                      (doc3, 'author3')])
&lt;p&gt;&lt;span title="author1"&gt;Here is&lt;/span&gt;
   &lt;b&gt;&lt;span title="author2"&gt;a&lt;/span&gt;
   &lt;span title="author3"&gt;little&lt;/span&gt;&lt;/b&gt;
   &lt;i&gt;&lt;span title="author2"&gt;text&lt;/span&gt;&lt;/i&gt;
   &lt;span title="author2"&gt;.&lt;/span&gt;&lt;/p&gt;
</pre>
</blockquote>
<p>As you can see, it is imperfect as such things tend to be.  On larger
tracts of text with larger edits it will generally do better.</p>
<p>The <tt class="docutils literal"><span class="pre">html_annotate</span></tt> function can also take an optional second
argument, <tt class="docutils literal"><span class="pre">markup</span></tt>.  This is a function like <tt class="docutils literal"><span class="pre">markup(text,</span>
<span class="pre">version)</span></tt> that returns the given text marked up with the given
version.  The default version, the output of which you see in the
example, looks like:</p>
<pre class="literal-block">
def default_markup(text, version):
    return '&lt;span title="%s"&gt;%s&lt;/span&gt;' % (
        cgi.escape(unicode(version), 1), text)
</pre>
</div>
<div class="section">
<h1><a id="examples" name="examples">Examples</a></h1>
<div class="section">
<h2><a id="microformat-example" name="microformat-example">Microformat Example</a></h2>
<p>This example parses the <a class="reference" href="http://microformats.org/wiki/hcard">hCard</a>
microformat.</p>
<p>First we get the page:</p>
<pre class="literal-block">
&gt;&gt;&gt; import urllib
&gt;&gt;&gt; from lxml.html import fromstring
&gt;&gt;&gt; url = 'http://microformats.org/'
&gt;&gt;&gt; content = urllib.urlopen(url).read()
&gt;&gt;&gt; doc = fromstring(content)
&gt;&gt;&gt; doc.make_links_absolute(url)
</pre>
<p>Then we create some objects to put the information in:</p>
<pre class="literal-block">
&gt;&gt;&gt; class Card(object):
...     def __init__(self, **kw):
...         for name, value in kw:
...             setattr(self, name, value)
&gt;&gt;&gt; class Phone(object):
...     def __init__(self, phone, types=()):
...         self.phone, self.types = phone, types
</pre>
<p>And some generally handy functions for microformats:</p>
<pre class="literal-block">
&gt;&gt;&gt; def get_text(el, class_name):
...     els = el.find_class(class_name)
...     if els:
...         return els[0].text_content()
...     else:
...         return ''
&gt;&gt;&gt; def get_value(el):
...     return get_text(el, 'value') or el.text_content()
&gt;&gt;&gt; def get_all_texts(el, class_name):
...     return [e.text_content() for e in els.find_class(class_name)]
&gt;&gt;&gt; def parse_addresses(el):
...     # Ideally this would parse street, etc.
...     return el.find_class('adr')
</pre>
<p>Then the parsing:</p>
<pre class="literal-block">
&gt;&gt;&gt; for el in doc.find_class('hcard'):
...     card = Card()
...     card.el = el
...     card.fn = get_text(el, 'fn')
...     card.tels = []
...     for tel_el in card.find_class('tel'):
...         card.tels.append(Phone(get_value(tel_el),
...                                get_all_texts(tel_el, 'type')))
...     card.addresses = parse_addresses(el)
</pre>
</div>
</div>
</div>
<div class="footer">
<hr class="footer" />
Generated on: 2008-12-12.

</div>
</body>
</html>