Package: klon
Klon is a collection of Python utilities for manipulating ElementTrees. It's a
thin-ish, transparent wrapper around thelxml.etreemodule.klon.build_etreeSource code:klon/build.pyA utility for building element trees using list and string literals.>>>fromklonimportbuild_etree>>>etree=build_etree(...'html',...[...'head',...['title','Test Document'],...],...[...'body',...['h1#title','This is a test'],...['a',{'href':'/page'},['img',{'src':'image.jpg'}]],...[...'p.text',...'This is a text',...['br'],...'This is a tail',...],...],...)Nested lists are translated to nested elements:the first element in the list must be a string, and becomes the tag nameoptionally, the second element can be a dict, specifying tag attributesany other elements become the tag's childrenAs a convenience, theidandclassattributes can be set directly from the
tag name string, using CSS-like syntax:tag#idandtag.class.klon.tostringSource code:klon/utils.pyA thin wrapper aroundlxml.etree.tostring.>>>fromklonimporttostring>>>print(tostring(etree,pretty_print=True))<html><head><title>TestDocument</title></head><body><h1id="title">Thisisatest</h1><ahref="/page"><imgsrc="image.jpg"/></a><pclass="text">Thisisatext<br/>Thisisatail</p></body></html>The main difference with the underlying LXML function is thatencoding=strby
default, i.e. it produces strings by default, rather than bytes.klon.extract_textSource code:klon/text.pyExtracts all text from the given node and its descendants.By default, all contiguous whitespace is normalized to a single ASCII space,
and so the output will always be a single line of text. However ifmultiline=Trueis specified, paragraph-breaking tags are preserved, in the
same way that a web browser would. Other whitespace is still normalized, but
the output now contains both ASCII spaces and ASCII newlines.>>>fromklonimportextract_text>>>body=etree.find('body')# using the same example etree defined above>>>print(tostring(body,pretty_print=True))<body><h1id="title">Thisisatest</h1><ahref="/page"><imgsrc="image.jpg"/></a><pclass="text">Thisisatext<br/>Thisisatail</p></body>>>>extract_text(body)'This is a test This is a text This is a tail'>>>extract_text(body,multiline=True)'This is a test\n\nThis is a text\nThis is a tail'Note that the<p>tag translates to a double newline, while the<br>tag
translates to a single\n, mimicking how a browser renders them.klon.detachSource code:klon/utils.pyTakes one node as argument, and removes it from its tree. Takes care to
preserve the node'stailtext by reattaching it to the correct position in
the tree.>>>fromklonimportdetach>>>print(tostring(body,pretty_print=True))<body><h1id="title">Thisisatest</h1><ahref="/page"><imgsrc="image.jpg"/></a><pclass="text">Thisisatext<br/>Thisisatail</p></body>>>>br=detach(body.xpath('.//br')[0])>>>print(tostring(body,pretty_print=True))<body><h1id="title">Thisisatest</h1><ahref="/page"><imgsrc="image.jpg"/></a><pclass="text">ThisisatextThisisatail</p></body>Note thatThis is a tail, which was thetailof the<br>node, has been
preserved, in this case by appending it to thetextof its parent node.klon.make_all_urls_absoluteSource code:klon/html.pyTakes a URL and a document etree, and modifies the etree in place to convert
all relative URLs to absolute ones, using the given URL as a base. All standard
tag attributes that specify a URL (e.g.<a href="...">,<img src="...">,<form action="...">etc) are converted.>>>fromklonimportmake_all_urls_absolute>>>print(tostring(body.find('a')))<ahref="/page"><imgsrc="image.jpg"/></a>>>>make_all_urls_absolute('https://site.com/path/',etree)>>>print(tostring(body.find('a')))<ahref="https://site.com/page"><imgsrc="https://site.com/path/image.jpg"/></a>klon.parse_formSource code:klon/forms.pyTakes an ElementTree whose root is a<form>node, and returns arequests.Requestthat corresponds to the request that would be sent by a
browser if the form was submitted.>>>fromklonimportparse_form>>>form=build_etree(...'form',...{'method':'POST','action':'/publish'},...[...'div',...['input',{'name':'title','value':'Some title'}],...],...[...'select',...{'name':'kind'},...['option',{'value':'comment'},'Comment'],...['option',{'value':'question','selected':'yes'},'Question'],...],...)>>>request=parse_form(form,base_url='https://web.site/')>>>request.url'https://web.site/publish'>>>request.method'POST'>>>request.data{'title':'Some title','kind':'question'}