【问题标题】:Extracting everything between two lxml tags Python提取两个lxml标签Python之间的所有内容
【发布时间】:2020-05-01 12:12:07
【问题描述】:

考虑下面的html sn-p

<html>
  .
  .
  .
  <div>
    <p> Hello </p>
    <div>
      <b>
        Text1
      </b>
      <p>
        This is a huge paragraph text
      </p>
       .
       .
       .
     </div>
  </div>
  .
  .
  .
  <div>
    <i>
      Text2
    </i>
  </div>
  
 
  
      
  
  

假设我需要提取从Text1Text2 的所有内容,包括标签。 使用一些方法,我已经能够提取出这两者的标签,即它们的唯一 ID。

基本上我有 2 个 Element.etree 元素,对应于我需要的两个标签。

如何提取两个标签之间的所有内容?

(我能想到的一个可能的解决方案是找到两个标签的共同祖先,然后执行iterwalk() 并从 Element1 开始提取,并在 2 处停止。但是,我不确定这会如何) 任何解决方案将不胜感激。

请注意,我已经找到了我需要的两个标签,我不是在寻找解决方案来找到这些标签(例如使用 xpath)

编辑:我想要的输出是

      <b>
        Text1
      </b>
      <p>
        This is a huge paragraph text
      </p>
       .
       .
       .
     </div>
  </div>
  .
  .
  .
  <div>
    <i>
      Text2
    </i>

请注意,我不介意最初的 2 个&lt;div&gt; 标签,但不想要Hello。 结束的结束标签也是如此。我最感兴趣的是中间的内容。

编辑 2:我使用复杂的 xpath 条件提取了 Etree 元素,这对于 bs4 等其他替代方案是不可行的,因此任何使用 lxml 元素的解决方案都将不胜感激:)

【问题讨论】:

  • 你能提供想要的输出吗?
  • 我已经用所需的输出编辑了我的帖子。道歉
  • 您应该考虑使用正则表达式
  • 输出可能不是正确的xml 结构,有问题吗?
  • 不,这不是问题。我最感兴趣的是提取中间的文本

标签: python html tags lxml


【解决方案1】:

经过审查和提问:

from essentials.tokening import CreateToken # This was imported just to generate a random string - pip install mknxgn_essentials
import bs4

HTML = """<html>
    <div>
        <div>
            <div id="start">
                Hello, My name is mark
            </div>
        </div>
    </div>

    <div>
        This is in the middle
    </div>

    <div>
        <div id="end">
            This is the end
        </div>
    </div>

    <div>
        Do not include this.
    </div>

</html>"""

RandomString = CreateToken(30, HTML) #Generate a random string that could never occur on it's own in the file, if it did occur, use something else 
soup = bs4.BeautifulSoup(HTML, features="lxml") # Convert the text into soup
start_div = soup.find("div", attrs={"id": "start"}) #assuming you can find this element
start_div.insert_before(RandomString) # insert the random string before this element
end_div = soup.find("div", attrs={"id": "end"})     #again, i was assuming you can also find this element
end_div.insert_after(RandomString) # insert the random string after this element

print(str(soup).split(RandomString)[1]) # Get between both random strings

这个返回的输出:

>>>             <div id="start">
>>>                 Hello, My name is mark
>>>             </div>
>>>     </div>
>>> </div>
>>>     <div>
>>>         This is in the middle
>>>     </div>
>>> <div>
>>>     <div id="end">
>>>         This is the end
>>>     </div>

【讨论】:

  • 嗨。最初我使用的是beautifulsoup,但切换到lxml,因为我的问题不像findall('div')那么简单。使用复杂的 xpath 语句,我能够将精确的 Etree 元素归零,但是,beautifulsoup 不支持这一点。那么,既然我有了我的 lxml 独特元素,我该如何解决这个问题呢?
  • 嗨@ShrutheeshRaman,你能给我举个例子,说明除了你已经提供的之外,你还想完成什么吗?根据您刚才的解释,您是否正在尝试:收集从 X 到 Y 的所有内容,它们可能位于不同的父树中?
  • 嗨@Mark,是的,我正在尝试完全按照您的公式进行操作。 stackoverflow.com/a/61476144/9926472 这是我之前的问题,我按照链接中给出的解决方案进行操作。使用该解决方案中提供的正则表达式和 xpath 条件的组合,我能够找到我的两个 lxml 元素 E1 和 E2。现在我想收集从 E1 到 E2 的所有东西(可能在不同的树上,就像你说的那样)。
  • 哦,太好了!这是一个很棒的解决方案,从来没有想过这个!谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-07
  • 1970-01-01
  • 2022-11-18
  • 2020-02-05
  • 2016-06-22
  • 1970-01-01
  • 2019-09-10
相关资源
最近更新 更多