【问题标题】:How can I find one tag between two other tags?如何在其他两个标签之间找到一个标签?
【发布时间】:2016-09-15 09:22:19
【问题描述】:

我有一个结构如下的文档:

<tag1>some_text_1</tag1>
<tag2>text_1</tag2>
<tag3>....</tag3>
<tag2>text_2</tag2>
<tag1>some_text_2</tag1>
<tag2>text_3</tag2>
...

我需要获取在tag1 之后和some_text_1 之后和下一个tag1 之前的所有tag2 实例。

【问题讨论】:

  • 你的意思是在下一个 text_2 之前还是在 some_text_2 之前,因为在下一个 tag2 之前的所有 tag2 实例都没有意义。因为只有一个 tag2。
  • tag2 可以出现在后面还是直接后面?您的示例输入并不适合您的问题描述。
  • 是的,我的错误应该是在带有指定文本的 tag1 之后和下一个 tag1 之前
  • 是直接在之后还是可以在之后的任何地方?

标签: python python-3.x beautifulsoup


【解决方案1】:

您的描述 我需要获取 tag1 之后和下一个 tag2 之前的所有 tag2 实例。 基本上等同于在任何 tag1 之后获取第一个 tag2 文本 some_text_

所以找到带有特定文本的tag1's,并检查下一个兄弟标签是否是tag2,如果是拉标签2:

html = """<tag1>some_text_1</tag1>
<tag2>text_1</tag2>
<tag3>....</tag3>
<tag2>text_2</tag2>
<tag1>some_text_2</tag1>
<tag2>text_3</tag2>"""


def get_tags_if_preceded_by(soup, tag1, tag2, text):
    for t1 in soup.find_all(tag1, text=text):
        nxt_sib = t1.find_next_sibling()
        if nxt_sib and nxt_sib.name == tag2:
            yield nxt_sib

soup = BeautifulSoup(html, "lxml")

print(list(get_tags_if_preceded_by(soup, "tag1", "tag2", "some_text_1")))

如果不必直接在后面,其实更简单,你只需要搜索特定的tag2兄弟:

def get_tags_if_preceded_by(soup, tag1, tag2, text):
    for t1 in soup.find_all(tag1, text=text):
        nxt_sib = t1.find_next_sibling(t2)
        if nxt_sib:
            yield nxt_sib

如果你真的想专门找两个标签之间的标签,可以使用this answer中的逻辑。

【讨论】:

    【解决方案2】:
    from bs4 import BeautifulSoup 
    
    html = '''<tag1>some_text_1</tag1>
            <tag2>text_1</tag2>
        <tag3>....</tag3>
        <tag2>text_2</tag2>
        <tag1>some_text_2</tag1>
        <tag2>text_3</tag2>'''
    
    soup = BeautifulSoup(html,"html.parser")
    
    def findalltags(tag1,tag2,soup):
        # tag1 is between which tag
        # tag2 get info of which tag
        a = soup.find(tag1)
        lis = []
        while True:
            a = a.find_next()
            if(str(a.name) == tag1):
                break
            elif(str(a.name) == tag2):
                lis.append(a)
        return lis
    if __name__ == '__main__':
        print findalltags('tag1','tag2',soup)
    

    希望这能解决问题,但我认为这不是一种有效的方法。如果您熟悉正则表达式,则可以使用它们。

    【讨论】:

    • a.name 是一个字符串,括号也不需要。
    • 我们将得到它的Unicode我不知道它是否可以与字符串相等,所以为了避免它我转换成字符串
    • u"foo" == "foo" 可以正常工作,如果名称中有非 ascii 字符,则调用 str 会出错。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-14
    • 1970-01-01
    相关资源
    最近更新 更多