标签: lxml

带有lxml的Python漂亮的XML打印机

在用"丑陋"的XML读取现有文件并进行一些修改后,漂亮的打印不起作用.我试过了etree.write(FILE_NAME, pretty_print=True).

我有以下XML:

<testsuites tests="14" failures="0" disabled="0" errors="0" time="0.306" name="AllTests">
    <testsuite name="AIR" tests="14" failures="0" disabled="0" errors="0" time="0.306">
....
Run Code Online (Sandbox Code Playgroud)

我这样使用它:

tree = etree.parse('original.xml')
root = tree.getroot()

...    
# modifications
...

with open(FILE_NAME, "w") as f:
    tree.write(f, pretty_print=True)
Run Code Online (Sandbox Code Playgroud)

python lxml pretty-print

19
推荐指数
4
解决办法
3万
查看次数

Python Lxml(objectify):检查标签是否存在

我需要检查xml文件中是否存在某个标记.

例如,我想查看此代码段中是否存在该标记:

 <main>
       <elem1/>
       <elem2>Hi</elem2>
       <elem3/>
       ...
 </main>
Run Code Online (Sandbox Code Playgroud)

目前,我正在使用一个带有错误检查的丑陋黑客,如下所示:

try:
   if root.elem1.tag:
      foo = elem1
except AttributeError:
   foo = "error finding elem1"
Run Code Online (Sandbox Code Playgroud)

如果无法找到节点,我也想自定义字符串(即"无法找到-tagname-").

我必须检查一长串变量,我不想重复代码100次.

有什么建议?

编辑:

以下是实际xml文件的片段:

<main>
 <asset name="Virtual Dvaered Unpresence">
  <virtual/>
  <presence>
   <faction>Dvaered</faction>
   <value>-1000.000000</value>
   <range>0</range>
  </presence>
 </asset>
 <asset name="Virtual Empire Small">
  <virtual/>
  <presence>
   <faction>Empire</faction>
   <value>100.000000</value>
   <range>2</range>
  </presence>
 </asset>
</main>
Run Code Online (Sandbox Code Playgroud)

我想检查标签是否存在,如果是,则获取内容.

编辑编辑:好的,我将结合两个答案,但我只能投一票.抱歉.

编辑3:关于XPath的相关问题:Python lxml(objectify):Xpath麻烦

python xml lxml objectify

19
推荐指数
3
解决办法
2万
查看次数

如何通过Python中的XPath以命名空间无关的方式查找XML元素?

因为我第二次遇到这个烦人的问题,我觉得这个问题会有所帮助.

有时候我必须从XML文档中获取Elements,但是这样做的方法很尴尬.

我想知道一个python库,它可以实现我想要的,一种优雅的方式来表示我的XPath,一种在前缀中自动注册命名空间的方法,或者在内置XML实现中的隐藏首选项,或者在lxml中完全删除命名空间.澄清之后,除非你已经知道我想要什么:)

实施例-doc的:

<root xmlns="http://really-long-namespace.uri"
  xmlns:other="http://with-ambivalent.end/#">
    <other:elem/>
</root>
Run Code Online (Sandbox Code Playgroud)

我可以做什么

ElementTree API是唯一内置的(我知道)提供XPath查询.但它需要我使用"UNames".这看起来像这样:/{http://really-long-namespace.uri}root/{http://with-ambivalent.end/#}elem

如您所见,这些都非常冗长.我可以通过以下方式缩短它们:

default_ns = "http://really-long-namespace.uri"
other_ns   = "http://with-ambivalent.end/#"
doc.find("/{{{0}}}root/{{{1}}}elem".format(default_ns, other_ns))
Run Code Online (Sandbox Code Playgroud)

但是,这是双方{{{丑陋}}}和脆弱的,因为http…end/#http…end#http…end/http…end和我是谁知道哪个变种会用吗?

此外,lxml支持名称空间前缀,但它既不使用文档中的名称前缀,也不提供处理默认名称空间的自动方法.我仍然需要从每个命名空间中获取一个元素以从文档中检索它.命名空间属性不会保留,因此也无法自动从这些属性中检索它们.

有一种与命名空间无关的XPath查询方式,但它在内置实现中既详细又丑陋且不可用: /*[local-name() = 'root']/*[local-name() = 'elem']

我想做的事

我想找到一个库,选项或通用的XPath变形函数,通过输入以下内容来实现上述示例...

  1. Unnamespaced: /root/elem
  2. 来自文档的命名空间前缀: /root/other:elem

...加上可能是一些我确实想要使用文档前缀或剥离命名空间的语句.

进一步澄清:虽然我目前的用例很简单,但将来我将不得不使用更复杂的用例.

谢谢阅读!


解决了

用户samplebias将我的注意力引向了py-dom-xpath ; 正是我在寻找什么.我的实际代码现在看起来像这样:

#parse the document into a DOM tree
rdf_tree = xml.dom.minidom.parse("install.rdf")
#read the default namespace and prefix from the root node
context = xpath.XPathContext(rdf_tree)

name    = context.findvalue("//em:id", rdf_tree)
version …
Run Code Online (Sandbox Code Playgroud)

python xml xpath lxml elementtree

19
推荐指数
1
解决办法
2万
查看次数

为什么lxml.etree.iterparse()占用了我所有的记忆?

这最终消耗了我所有可用的内存,然后该进程被终止.我已经尝试将标签更改schedule为"较小"标签,但这并没有什么区别.

我做错了什么/如何处理这个大文件iterparse()

import lxml.etree

for schedule in lxml.etree.iterparse('really-big-file.xml', tag='schedule'):
    print "why does this consume all my memory?"
Run Code Online (Sandbox Code Playgroud)

我可以轻松地将其切割并以较小的块处理它,但这比我想要的更糟糕.

python xml memory lxml iterparse

19
推荐指数
2
解决办法
8580
查看次数

如何使用LXML解析损坏的HTML

我正在尝试使用python 2.5和2.7上的LXML解析器解析破坏的HTML

与LXML文档(http://lxml.de/parsing.html#parsing-html)不同,解析损坏的HTML不起作用:

from lxml import etree
import StringIO
broken_html = "<html><head><title>test<body><h1>page title</h3>"
parser = etree.HTMLParser()
tree   = etree.parse(StringIO.StringIO(broken_html))
Run Code Online (Sandbox Code Playgroud)

结果:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "lxml.etree.pyx", line 2954, in lxml.etree.parse (src/lxml/lxml.etree.c:56220)
  File "parser.pxi", line 1550, in lxml.etree._parseDocument (src/lxml/lxml.etree.c:82482)
  File "parser.pxi", line 1578, in lxml.etree._parseMemoryDocument (src/lxml/lxml.etree.c:82764)
  File "parser.pxi", line 1457, in lxml.etree._parseDoc (src/lxml/lxml.etree.c:81562)
  File "parser.pxi", line 965, in lxml.etree._BaseParser._parseDoc (src/lxml/lxml.etree.c:78232)
  File "parser.pxi", line 569, in lxml.etree._ParserContext._handleParseResultDoc (src/lxml/lxml.etree.c:74488)
  File "parser.pxi", line 650, in …
Run Code Online (Sandbox Code Playgroud)

python lxml

19
推荐指数
3
解决办法
9245
查看次数

将lxml设置为默认的BeautifulSoup解析器

我正在进行网络抓取项目,并遇到速度问题.为了尝试修复它,我想使用lxml而不是html.parser作为BeautifulSoup的解析器.我已经能够做到这一点:

soup = bs4.BeautifulSoup(html, 'lxml')
Run Code Online (Sandbox Code Playgroud)

但我不想'lxml'每次打电话给BeautifulSoup都要反复输入.有没有办法在程序开始时设置一次使用哪个解析器?

html python lxml beautifulsoup html-parsing

19
推荐指数
2
解决办法
2万
查看次数

使用lxml.etree.iterparse解析损坏的XML

我试图以一种内存有效的方式解析一个带有lxml的巨大xml文件(即从磁盘懒洋洋地流式传输,而不是将整个文件加载到内存中).不幸的是,该文件包含一些破坏默认解析器的坏ascii字符.如果我设置recover = True,则解析器可以工作,但是iterparse方法不会使用recover参数或自定义解析器对象.有谁知道如何使用iterparse来解析破碎的xml?

#this works, but loads the whole file into memory
parser = lxml.etree.XMLParser(recover=True) #recovers from bad characters.
tree = lxml.etree.parse(filename, parser)

#how do I do the equivalent with iterparse?  (using iterparse so the file can be streamed lazily from disk)
context = lxml.etree.iterparse(filename, tag='RECORD')
#record contains 6 elements that I need to extract the text from
Run Code Online (Sandbox Code Playgroud)

谢谢你的帮助!

编辑 - 以下是我遇到的编码错误类型的示例:

In [17]: data
Out[17]: '\t<articletext>&lt;p&gt;The cafeteria rang with excited voices.  Our barbershop quartet, The Bell \r Tones was …
Run Code Online (Sandbox Code Playgroud)

python xml lxml sax

17
推荐指数
2
解决办法
2万
查看次数

如何使用html5lib解析HTML,并使用XPath查询解析的HTML?

我正在尝试使用html5lib将html页面解析为我可以使用xpath查询的内容.html5lib文档接近零,我花了太多时间试图解决这个问题.最终目标是拉出表的第二行:

<html>
    <table>
        <tr><td>Header</td></tr>
        <tr><td>Want This</td></tr>
    </table>
</html>
Run Code Online (Sandbox Code Playgroud)

所以试试吧:

>>> doc = html5lib.parse('<html><table><tr><td>Header</td></tr><tr><td>Want This</td> </tr></table></html>', treebuilder='lxml')
>>> doc
<lxml.etree._ElementTree object at 0x1a1c290>
Run Code Online (Sandbox Code Playgroud)

看起来不错,让我们看看我们还有什么:

>>> root = doc.getroot()
>>> print(lxml.etree.tostring(root))
<html:html xmlns:html="http://www.w3.org/1999/xhtml"><html:head/><html:body><html:table><html:tbody><html:tr><html:td>Header</html:td></html:tr><html:tr><html:td>Want This</html:td></html:tr></html:tbody></html:table></html:body></html:html>
Run Code Online (Sandbox Code Playgroud)

大笑?

认真.我打算使用一些xpath来获取我想要的数据,但这似乎不起作用.那我该怎么办?我愿意尝试不同的库和方法.

python xpath parsing lxml html5lib

17
推荐指数
2
解决办法
1万
查看次数

如何用LXML编写命名空间元素属性?

我正在使用lxml(2.2.8)来创建和编写一些XML(特别是XGMML).将要阅读它的应用程序显然相当挑剔,并希望看到一个顶级元素:

<graph label="Test" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xlink="h
ttp://www.w3.org/1999/xlink" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-
ns#" xmlns:cy="http://www.cytoscape.org" xmlns="http://www.cs.rpi.edu/XGMML"  di
rected="1">
Run Code Online (Sandbox Code Playgroud)

如何xmlns:使用lxml 设置这些属性?如果我尝试明显的

root.attrib['xmlns:dc']='http://purl.org/dc/elements/1.1/'
root.attrib['xmlns:xlink']='http://www.w3.org/1999/xlink'
root.attrib['xmlns:rdf']='http://www.w3.org/1999/02/22-rdf-syntax-ns#'
root.attrib['xmlns:cy']='http://www.cytoscape.org'
root.attrib['xmlns']='http://www.cs.rpi.edu/XGMML'
Run Code Online (Sandbox Code Playgroud)

lxml抛出一个 ValueError: Invalid attribute name u'xmlns:dc'

我过去曾经使用过很多XML和lxml来处理简单的事情,但是到目前为止还是设法避免需要知道关于命名空间的任何事情.

python lxml xml-namespaces cytoscape

17
推荐指数
2
解决办法
1万
查看次数

为html表提取lxml xpath

我有一个类似于以下的html文档:

<html xmlns="http://www.w3.org/1999/xhtml" xmlns="http://www.w3.org/1999/xhtml">
    <div id="Symbols" class="cb">
    <table class="quotes">
    <tr><th>Code</th><th>Name</th>
        <th style="text-align:right;">High</th>
        <th style="text-align:right;">Low</th>
    </tr>
    <tr class="ro" onclick="location.href='/xyz.com/A.htm';" style="color:red;">
        <td><a href="/xyz.com/A.htm" title="Display,A">A</a></td>
        <td>A Inc.</td>
        <td align="right">45.44</td>
        <td align="right">44.26</td>
    <tr class="re" onclick="location.href='/xyz.com/B.htm';" style="color:red;">
        <td><a href="/xyz.com/B.htm" title="Display,B">B</a></td>
        <td>B Inc.</td>
        <td align="right">18.29</td>
        <td align="right">17.92</td>
</div></html>
Run Code Online (Sandbox Code Playgroud)

我需要code/name/high/low从表中提取信息.

我使用了Stack Over Flow中类似示例中的以下代码:

#############################
import urllib2
from lxml import html, etree

webpg = urllib2.urlopen(http://www.eoddata.com/stocklist/NYSE/A.htm).read()
table = html.fromstring(webpg)

for row in table.xpath('//table[@class="quotes"]/tbody/tr'):
    for column in row.xpath('./th[position()>0]/text() | ./td[position()=1]/a/text() | ./td[position()>1]/text()'):
        print column.strip(),
    print

#############################
Run Code Online (Sandbox Code Playgroud)

我没有得到任何输出.我必须将第一个循环xpath更改table.xpath('//tr') …

html python xpath lxml html-table

16
推荐指数
1
解决办法
1万
查看次数