lxml是一个功能齐全的高性能Python库,用于处理XML和HTML。
当运行Python脚本时,我遇到了这个错误 从LXML导入 Importerror:没有名为LXML的模块 现在我尝试安装LXML sudo easy_install lmxl 但这给了我以下错误
在不使用SAX的情况下,控制Python中XML迭代式解析器使用的块大小的最佳方法是什么? (“ iterparse”行为出乎意料)[封闭]
问题:解析python逐行线的XML文件的最佳方法是什么? 如果行不是迭代解析器使用的最佳块尺寸,那么最佳块尺寸是多少?具体来说,W ...
插入LXML,libxml2,for python 3.5在Windows10
i首先尝试为其运行基本PIP安装命令: C:\ Program Files(X86)\ Python35-32> PIP安装LXML 收集LXML 使用缓存的LXML-3.6.4.tar.gz 用于收集的Packa的车轮...
我试图在循环中读取大量压缩文件(.zip 或 .docx),每个文件中又包含大量嵌入的 XML (.xml) 文件。然而,一些嵌入的 XML 文件是
我正在处理一个遗留项目,我需要安装与 python 3.X 兼容的 libxml2 我需要使用 lxml 4.1.1,我尝试使用 Christoph Gohlke 的 Window 二进制文件 https://www.lfd.uci....
在 Python 中逐行解析 XML 文件而不使用 SAX 的最佳方法是什么? (`iterparse` 的行为出乎意料)
问题:在 Python 中逐行解析 XML 文件的最佳方法是什么?我似乎有一个解决方法,但想知道是否有比我的有点 hacky 更好、广为人知的解决方案
我正在处理一个在我尝试构建的刮刀中使用 lxml 的查询。 https://scraperwiki.com/scrapers/thisisscraper/ 我正在逐行完成教程 3,到目前为止已经完成了
如何使用 XML 模块在 Ansible 中删除 XML 文件中的某些节点?
我尝试从 activemq.xml 配置文件中删除一些节点。在此文件中,我想删除除 tcp 之外的所有连接。 我尝试从 activemq.xml 配置文件中删除一些节点。在这个文件中,我想删除除 tcp 之外的所有连接。 <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd"> ... <broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}"> ... <transportConnectors> <!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB --> <transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> <transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> <transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> <transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> <transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> </transportConnectors> ... </broker> </beans> 我使用 Ansible community.general.xml 模块 - name: Désactiver les autres protocoles de publication de message xml: path: /mypath/activemq-modif.xml xpath: "/ns:beans/broker:broker/broker:transportConnectors/broker:transportConnector[@name!='openwire']/*" state: absent namespaces: ns: http://www.springframework.org/schema/beans broker: http://activemq.apache.org/schema/core 当我运行剧本时,没有错误,但文件没有改变。 如果我按照模块文档示例中的说明删除 /*,则会出现错误 fatal: [localhost]: FAILED! => {"changed": false, "msg": "Couldn't delete xpath target: /ns:beans/broker:broker/broker:transportConnectors/broker:transportConnector[@name!='openwire'] (module 'lxml.etree' has no attribute '_ElementStringResult')"} 如何删除(或评论)除 transportConnector 之外的所有 openwire 节点? ansible-playbook [core 2.15.13] config file = None configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules'] ansible python module location = /usr/local/lib/python3.9/site-packages/ansible ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections executable location = /usr/local/bin/ansible-playbook python version = 3.9.18 (main, Oct 4 2024, 00:00:00) [GCC 11.4.1 20231218 (Red Hat 11.4.1-3)] (/usr/bin/python3) jinja version = 3.1.4 libyaml = True Package Version ------------------- -------- ansible 8.7.0 lxml 5.3.0 好的,我已经检查了模块代码xml.py。在第 435 行,一条评论提到了 lxml 5.1.1 删除了etree._ElementStringResult,所以我们不能再简单地假设它在那里 如果我将lxml降级到5.1.0,脚本就可以并且文档按照我的意愿进行更改! 似乎 Ansible xml 模块 在 5.1.0 版本之后无法再正确使用 lxml。所以我为此在 Github 上打开了一个问题。 谢谢。 这是基于 XSLT 的解决方案,它利用所谓的“身份转换”模式。 输入XML <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd">... <broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}"> <transportConnectors> <!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB --> <transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> <transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> <transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> <transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> <transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> </transportConnectors> </broker> </beans> XSLT <?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns2="http://activemq.apache.org/schema/core"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:strip-space elements="*"/> <!--Identity transform--> <xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <xsl:template match="ns2:transportConnector[not(starts-with(@uri,'tcp:'))]"/> </xsl:stylesheet> 输出XML <beans xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <broker xmlns="http://activemq.apache.org/schema/core" dataDirectory="${activemq.data}" brokerName="localhost"> <transportConnectors> <!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB --> <transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> </transportConnectors> </broker> </beans> 基于 如何在 Ansible 中过滤 XML 属性? 和 如何用 Ansible 替换 XML 元素的文本?,一个带有 activemq.xml 的最小示例 <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd"> <broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}"> <transportConnectors> <!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB --> <transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> <transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> <transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> <transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> <transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> </transportConnectors> </broker> </beans> 和剧本xml.yml--- - hosts: localhost become: false gather_facts: false vars: XML: "{{ lookup('file', 'activemq.xml') }}" tasks: - name: Convert XML to YML set_fact: YML: "{{ XML | ansible.utils.from_xml }}" - name: Show content debug: msg: "{{ YML }}" # Drop all transportConnector except the first in list - name: Update path ansible.utils.update_fact: updates: - path: "YML.beans.broker.transportConnectors.transportConnector" value: "{{ YML.beans.broker.transportConnectors.transportConnector[0] }}" register: updated - name: Show updated content debug: msg: "{{ updated.YML | ansible.utils.to_xml }}" - name: Write out XML file copy: dest: updated.activemq.xml content: "{{ updated.YML | ansible.utils.to_xml }}" 将生成一个 updated.activemq.xml 文件<?xml version="1.0" encoding="utf-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd"> <broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}"> <transportConnectors> <transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600"></transportConnector> </transportConnectors> </broker> </beans> 这是因为xml模块需要 在执行此模块的主机上。 lxml >= 2.3.0 并且依赖于它,而 from_xml 过滤器 则不依赖于它。 如果您喜欢从列表中选择一个特定的项目值,例如按名称 - name: Show 'openwire' from transportConnectors debug: msg: "{{ YML.beans.broker.transportConnectors.transportConnector | selectattr('@name', '==', 'openwire') }}" 更新可以通过完成 # Drop all transportConnector except with name 'openwire' - name: Update path ansible.utils.update_fact: updates: - path: "YML.beans.broker.transportConnectors.transportConnector" value: "{{ YML.beans.broker.transportConnectors.transportConnector | selectattr('@name', '==', 'openwire') }}" register: updated
我尝试从 activemq.xml 配置文件中删除一些节点。在此文件中,我想删除除 tcp 之外的所有连接 我尝试从 activemq.xml 配置文件中删除一些节点。在这个文件中,我想删除除 tcp 之外的所有连接 <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd"> ... <broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}"> ... <transportConnectors> <!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB --> <transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> <transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> <transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> <transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> <transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> </transportConnectors> ... </broker> </beans> 我使用ansible xml社区通用模块 - name: Désactiver les autres protocoles de publication de message xml: path: /mypath/activemq-modif.xml xpath: "/ns:beans/broker:broker/broker:transportConnectors/broker:transportConnector[@name!='openwire']/*" state: absent namespaces: ns: http://www.springframework.org/schema/beans broker: http://activemq.apache.org/schema/core 当我运行剧本时,没有错误,但文件没有改变。 如果我按照模块文档示例中的说明删除“/*”,则会出现错误 fatal: [localhost]: FAILED! => {"changed": false, "msg": "Couldn't delete xpath target: /ns:beans/broker:broker/broker:transportConnectors/broker:transportConnector[@name!='openwire'] (module 'lxml.etree' has no attribute '_ElementStringResult')"} 如何删除(或注释)除“openwire”之外的所有 TransportConnector 节点? ansible-playbook [core 2.15.13] config file = None configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules'] ansible python module location = /usr/local/lib/python3.9/site-packages/ansible ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections executable location = /usr/local/bin/ansible-playbook python version = 3.9.18 (main, Oct 4 2024, 00:00:00) [GCC 11.4.1 20231218 (Red Hat 11.4.1-3)] (/usr/bin/python3) jinja version = 3.1.4 libyaml = True Package Version ------------------- -------- ansible 8.7.0 lxml 5.3.0 这是基于 XSLT 的解决方案,它利用所谓的“身份转换”模式。 输入XML <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd">... <broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}"> <transportConnectors> <!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB --> <transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> <transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> <transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> <transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> <transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> </transportConnectors> </broker> </beans> XSLT <?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns2="http://activemq.apache.org/schema/core"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:strip-space elements="*"/> <!--Identity transform--> <xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <xsl:template match="ns2:transportConnector[not(starts-with(@uri,'tcp:'))]"/> </xsl:stylesheet> 输出XML <beans xmlns="http://www.springframework.org/schema/beans" default-lazy-init="default" default-merge="default" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" default-autowire="default"> <broker xmlns="http://activemq.apache.org/schema/core" dataDirectory="${activemq.data}" brokerName="localhost"> <transportConnectors> <!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB --> <transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> </transportConnectors> </broker> </beans>
如何获取 HTML 字符串中文本节点的源索引? 标签具有 sourceline 和 sourcepos 这对此很有用,但 NavigableString 没有任何直接有用的属性,例如 ...
如何使用Python通过指定的不配对标签分割html字符串?例如 split('你好那里', 'br') 应该返回 ['hello', 'there'], 分割('... 如何使用Python通过指定的不配对标签分割html字符串?例如 split('hello<br >there', 'br') 应该返回['hello', 'there'], split('<div id="d71">text1<br data-i="1">text2<br>text3</div>', 'br') 应该返回['<div id="d71">text1', 'text2', 'text3</div>'] 我看过了 def get_start_stop(source, tag_name): soup = BeautifulSoup(source, 'html.parser') return dir(soup.find(tag_name)) 但是我所希望的事情,sourcepos,string,strings,self_and_descendants,.nextSibling.sourcepos没有获得开始和结束索引所需的信息(据我所知)源字符串中的标签。 我也尝试过类似的事情 from lxml import html def split(input_str, tag_name): tree = html.fromstring(input_str) output_list = [] for element in tree.iter(): if element.tag == tag_name: output_list.append(element.tail) else: output_list.append(html.tostring(element, encoding='unicode', with_tail=False)) return output_list 但是with_tail=False没有达到我的预期 使用 lxml 作为 HTML 解析器 假设文档片段是 <div id="d71">text1<br/>text2<br/>text3</div> 查找 div 元素内的所有文本节点 from lxml import html doc = html.parse('temp.html') # returns a node set of text nodes d71txt = doc.xpath('//div[@id="d71"]/text()' 结果 ['text1', 'text2', 'text3'] 子元素的 tail 属性也包含其中一些文本节点。使用 descendant-or-self xpath 轴 >>> d71nodes = doc.xpath('//div[@id="d71"]/descendant-or-self::*') >>> d71nodes[0].text 'text1' >>> d71nodes[1].tail 'text2' >>> d71nodes[2].tail 'text3' 这是一个例子: from bs4 import BeautifulSoup text = """ <p>one<br>two</p> <p>two<br>three</p> """ page = BeautifulSoup(text, "html.parser") for t in page.find_all('p'): print("Got this:", t) for u in t: print(u) 输出: Got this: <p>one<br/>two</p> one <br/> two Got this: <p>two<br/>three</p> two <br/> three 我认为如何从中获取之前和之后应该非常清楚。 我认为BeautifulSoup并没有直接提供HTML标签的开始和结束索引,但是你可以通过在原始字符串中定位标签来找到它们 def get_start_stop(source, tag_name): soup = BeautifulSoup(source, 'html.parser') tag = soup.find(tag_name) if tag: start = source.find(f"<{tag_name}") end = source.find(">", start) + 1 return start, end return None
我想使用 lxml 库用新信息更新 xml 文件。 例如,我有这样的代码: >>> 从 lxml 导入 etree >>> >>> 树 = etree.parse('books.xml') w...
我有一些由脚本生成的 XML,可能有也可能没有空元素。有人告诉我现在 XML 中不能有空元素。这是一个例子: <...
在Python中解析Google Earth KML文件(lxml,命名空间)
我正在尝试使用 xml 模块将 .kml 文件解析为 Python(在我用于 HTML 的 BeautifulSoup 中未能完成此操作之后)。 因为这是我第一次这样做,所以我就跟着走了......
我正在使用 Python lxml.html 包来抓取 HTML 文件。 我试图抓取的 HTML 部分读取 DAB Ensemble 1 的描述我不关心的东西 我正在使用 Python lxml.html 包来抓取 HTML 文件。 我试图抓取的 HTML 部分读取 <h1>Description of DAB Ensemble 1</h1><table>Stuff I don't care about</table> <!-- Tags I don't care about --> <div id="announcement_data_block"> <h3>Announcement information</h3> <p>No announcement information is broadcast</p> </div> <!-- More tags I don't care about --> <h1>Description of DAB Ensemble 2</h1><table>Stuff I don't care about</table> <!-- Tags I don't care about --> <div id="announcement_data_block"> <h3>Announcement information</h3> <h4>Announcement switching (FIG0/19)</h4> <table>Stuff I DO care about</table> </div> <!-- More tags I don't are about --> 我对“公告切换”表感兴趣,对于给定的 DAB 整体,该表可能存在也可能不存在。我有一个lxml.hmtl.xpath表达式如下: f'//h1[text()="Description of DAB Ensemble {ens_idx}"]/following-sibling::table/following-sibling::div[@id="announcement_data_block"]/h4[starts-with(text(), "Announcement switching")]/following-sibling::table' 根据我的理解,这个 XPath 语句是说,对于给定的 ens_idx 值: 从根目录开始,找到文本匹配“Description of DAB Ensemble {ens_idx}”的 h1 标签(例如“Description of DAB Ensemble 1”、“Description of DAB Ensemble 2”),然后转到您看到的第一个表。 在上面的示例中,它将是标记为“我不关心的东西”的表。 然后,转到下一个 id 为“announcement_data_block”的 div。 在该 div 中,找到一个 h4 标签,其文本以“公告切换”开头。 获取接下来的第一个表。 在上面的示例中,DAB Ensemble 1 没有这样的表。 我希望 xpath 在尝试获取 DAB Ensemble 1 的表时返回 None 。但是,xpath 在遇到 h1 标签“DAB Ensemble 2 的描述”时不知道停止,因此它会继续运行,直到找到 DAB Ensemble 2的h4标签。 我正在寻求帮助,以找到一个 xpath 语句,该语句将使 XPath 无条件停止在下一个“DAB Ensemble 的描述”h1 标记处。本质上我希望将该指令修改为: 从根目录开始,找到文本匹配“Description of DAB Ensemble {ens_idx}”的 h1 标签(例如“Description of DAB Ensemble 1”、“Description of DAB Ensemble 2”),然后转到您看到的第一个表。 在上面的示例中,它将是标记为“我不关心的东西”的表。 然后,转到下一个 id 为“announcement_data_block”的 div。 在该 div 中,找到一个 h4 标签,其文本以“公告切换”开头。 获取随后的第一个表。 如果在文本匹配“Description of DAB Ensemble {ens_idx + 1}”或 EOF 的 h1 标记之前找不到此条件,则返回 None。 粗体部分是我的 XPath 表达式中缺少的部分。有谁知道如何构造这样的表达式? 从示例中可以看出,H1 和带有 id 的 div 都是兄弟姐妹,所以 搜索应表明找到的第一个 following::table 和第一个 @id="announcement_data_block" 是必需的,因为 f'//h1[text()="Description of DAB Ensemble {ens_idx}"]/following-sibling::table[1]/following-sibling::div[@id="announcement_data_block"][1]/h4[starts-with(text(), "Announcement switching")]/following-sibling::table' 顺便说一句:id 不应重复。
我正在使用 Python lxml.html 包来抓取 HTML 文件。 我正在尝试抓取部分内容的 HTML DAB Ensemble 1 的描述我不关心的东西&... 我正在使用 Python lxml.html 包来抓取 HTML 文件。 我正在尝试抓取部分内容的 HTML <h1>Description of DAB Ensemble 1</h1><table>Stuff I don't care about</table> <!-- Tags I don't care about --> <div id="announcement_data_block"> <h3>Announcement information</h3> <p>No announcement information is broadcast</p> </div> <!-- More tags I don't care about --> <h1>Description of DAB Ensemble 2</h1><table>Stuff I don't care about</table> <!-- Tags I don't care about --> <div id="announcement_data_block"> <h3>Announcement information</h3> <h4>Announcement switching (FIG0/19)</h4> <table>Stuff I DO care about</table> </div> <!-- More tags I don't are about --> 我对“公告切换”表感兴趣,对于给定的 DAB 整体,该表可能存在也可能不存在。我有一个lxml.hmtl.xpath表达式如下: f'//h1[text()="Description of DAB Ensemble {ens_idx}"]/following-sibling::table/following-sibling::div[@id="announcement_data_block"]/h4[starts-with(text(), "Announcement switching")]/following-sibling::table' 根据我的理解,这个 XPath 语句是说,对于给定的 ens_idx 值: 从根目录开始,找到文本匹配“Description of DAB Ensemble {ens_idx}”的 h1 标签(例如“Description of DAB Ensemble 1”、“Description of DAB Ensemble 2”),然后转到您看到的第一个表。 在上面的示例中,它将是标记为“我不关心的东西”的表。 然后,转到下一个 id 为“announcement_data_block”的 div。 在该 div 中,找到一个 h4 标签,其文本以“公告切换”开头。 获取接下来的第一个表。 在上面的示例中,DAB Ensemble 1 没有这样的表。 我希望 xpath 在尝试获取 DAB Ensemble 1 的表时返回 None 。但是,xpath 在遇到 h1 标签“DAB Ensemble 2 的描述”时不知道停止,因此它会继续运行,直到找到 DAB Ensemble 2的h4标签。 我正在寻求帮助,以找到一个 xpath 语句,该语句将使 XPath 无条件停止在下一个“DAB Ensemble 的描述”h1 标记处。本质上我希望将该指令修改为: 从根目录开始,找到文本匹配“Description of DAB Ensemble {ens_idx}”的 h1 标签(例如“Description of DAB Ensemble 1”、“Description of DAB Ensemble 2”),然后转到您看到的第一个表。 在上面的示例中,它将是标记为“我不关心的东西”的表。 然后,转到下一个 id 为“announcement_data_block”的 div。 在该 div 中,找到一个 h4 标签,其文本以“公告切换”开头。 获取随后的第一个表。 如果在文本匹配“Description of DAB Ensemble {ens_idx + 1}”或 EOF 的 h1 标记之前找不到此条件,则返回 None。 粗体部分是我的 XPath 表达式中缺少的部分。有谁知道如何构造这样的表达式? 从示例中可以看出,H1 和带有 id 的 div 都是兄弟姐妹,所以 搜索应表明找到的第一个 following::table 和第一个 @id="announcement_data_block" 是必需的,因为 f'//h1[text()="Description of DAB Ensemble {ens_idx}"]/following-sibling::table[1]/following-sibling::div[@id="announcement_data_block"][1]/h4[starts-with(text(), "Announcement switching")]/following-sibling::table' 顺便说一句:id 不应重复。