92780


xmlで1つのdocumentに対して、yearが2021であり，かつparagraphのtextにthirdが含まれていたら1つのdocumentに含まれるparagraphの全てのtextを抽出するというプログラムを作成しています．文字列検索条件では上手くできたのですが，year条件を含めると抽出すると"ABC"という文字列が抽出できなかったので改善策を教えていただきたいです.yearとparagraphが別々のpassageに入ってるので難しいかなとも思いました.

**ソースコード1(文字列検索条件)**

[code]

     texts = soup.select(f'''
                document:has(>passage>infon[key="type"]:-soup-contains("paragraph")~text:-soup-contains("third"))
                    passage >
                        infon[key="type"]:-soup-contains("paragraph") ~text:-soup-contains("")
    ''')
    
[/code]

**ソースコード2(文字列検索条件とyear条件)**

[code]

     texts = soup.select(f'''
          document:has(>passage>infon[key="year"]:-soup-contains("2021") ) >
            passage:has(>infon[key="type"]:-soup-contains("paragraph")~text:-soup-contains("third"))>
                infon[key="type"]:-soup-contains("paragraph") ~text:-soup-contains("")
    ''')
    
[/code]

**xml**

[code]

    <collection>
        <document>
            <passage>
                <infon key="year">2021</infon>>
            </passage>
            <passage>
                <infon key="type">paragraph</infon>
                <text>third five</text>
            </passage>
            <passage>
                <infon key="type">paragraph</infon>
                <text>ABC</text>
            </passage>
        </document>
        <document>
            <passage>
                <infon key="year">2021</infon>>
            </passage>
            <passage>
                <infon key="type">paragraph</infon>
                <text> third six </text>
            </passage>
        </document>
    </collection>
    
[/code]

**ソースコード2実行結果**

[code]

    ['third five']
    [' third six ']
    
[/code]


CC BY-SA 4.0
2022-12-14T05:53:49.713
92774
2022-12-14T08:57:40.517
2022-12-14T08:57:40.517
3060
54656
question
python python3 beautifulsoup
bs4のCSSセレクタでの要素抽出


`:has` を2段階にします。

[code]

    from bs4 import BeautifulSoup
    
    with open('result.xml') as xml:
        soup = BeautifulSoup(xml, 'xml')
    
    texts = soup.select(
          'document:has(>passage>infon[key="year"]:-soup-contains("2021"))'
          ':has(>passage>text:-soup-contains("third")) > passage > text')
    
    print(texts)
    
    # [<text>third five</text>, <text>ABC</text>, <text> third six </text>]
    
[/code]


CC BY-SA 4.0
2022-12-14T08:36:35.360
92780
2022-12-14T08:36:35.360
47127
92774
answer