BeautifulSoup не находит никаких XML-тегов

#python-3.x #xml #beautifulsoup

#python-3.x #xml #beautifulsoup

Вопрос:

Я пытаюсь извлечь слова с определенными свойствами из словаря XML. Например, все глаголы, указанные типом в лемме . Затем я разделю эти записи на основе определения или перегиба. Но сейчас мне просто нужно изучить объект Beautifulsoup. Я совсем новичок в XML. Вот первая запись в словаре. Я закрыл его, чтобы сделать его допустимым XML (я надеюсь). Я пытаюсь следовать руководству здесь

 <?xml version='1.0' encoding='utf-8'?>
<Dictionary xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="lexinAA.xsd">
  <Article ArticleID="1000002" Sortkey="a">
    <Lemma ID="1000002" LemmaID="1" Rank="350" Type="subst." Value="a" Variant="" VariantID="3, 4">
      <Phonetic File="v2/100021_1.mp3">a:</Phonetic>
      <Inflection Form="best.f.sing.">a:et</Inflection>
      <Inflection Form="obest.f.pl.">a:n</Inflection>
      <Inflection Form="best.f.pl.">a:na</Inflection>
      <Index Value="a" />
      <Index Value="a:et" />
      <Index Value="a:n" />
      <Index Value="a:na" />
      <Index Value="as" />
      <Index Value="a:ets" />
      <Index Value="a:ns" />
      <Index Value="a:nas" />
      <Lexeme ID="1" LexemeID="1000006" Lexemeno="1" VariantID="3">
        <Definition ID="9011000">första bokstaven i alfabetet</Definition>
        <Idiom DoubleID="2060026" ID="1000008" OldID="2">a och o
          <Definition DoubleID="2030380" ID="1000009">det viktigaste</Definition>
        </Idiom>
        <Idiom DoubleID="2060590" ID="1000010" OldID="1">har man sagt a får man också säga b
          <Definition DoubleID="2030824" ID="1000011">har man börjat får man fortsätta</Definition>
        </Idiom>
      </Lexeme>
      <Lexeme ID="2" LexemeID="1000013" Lexemeno="2" VariantID="4">
        <Definition ID="9011001">sjätte tonen i C-durskalan</Definition>
        <Compound ID="2000667" OldID="">a-moll</Compound>
        <Compound ID="2000668" OldID="">A-dur</Compound>
        <Index Value="a-moll" />
        <Index Value="a-molls" />
        <Index Value="a moll" />
        <Index Value="a molls" />
        <Index Value="A-dur" />
        <Index Value="A-durs" />
        <Index Value="A dur" />
        <Index Value="A durs" />
      </Lexeme>
    </Lemma>
  </Article>
</Dictionary>
  

Вот мой код Beautifulsoup

 from bs4 import BeautifulSoup as bs


content = []
with open('swe_swe.xml', 'r') as file:
    content = file.readlines()
    content = "".join(content)
    bs_content = bs(content, 'lxml')

result = bs_content.find('Article')
print(result)
print(bs_content.find('Inflection Form="best.f.sing.">a:et'))
  

Результат обоих отпечатков — None .

То, что я ожидаю от тега ‘Article’, — это либо вся первая запись для первого слова ‘a’, либо только строка:

 ArticleID="1000002" Sortkey="a">
  

Теги в словаре выглядят совершенно иначе, чем в руководстве, поэтому я чувствую, что упускаю что-то очевидное.

Комментарии:

1. Можете ли вы отредактировать свой вопрос и добавить точный результат, который вы ожидаете от двух print() операторов в вашем коде (или любого другого ожидаемого результата)? Кроме того, поскольку вы импортируете lxml, можете ли вы использовать его вместо BS?

2. @JackFleeting Я внес изменения, но поскольку BS все равно импортирует lxml, я просто удалил lxml. Я все еще хочу использовать BeautifulSoup, поскольку в предыдущей попытке я обнаружил, что lxml является сложным.

Ответ №1:

В данном случае проще использовать селекторы css. Обратите внимание, что имена элементов указаны в нижнем регистре. Например, чтобы получить текст <Article> :

 for s in soup.select_one('article').stripped_strings:
          print(s)
  

Другой пример:

 print(soup.select_one('inflection[form="best.f.sing."]'))
  

выводит

 <inflection form="best.f.sing.">a:et</inflection>
  

Наконец, чтобы получить значение атрибута LexemeID в Lexeme элементах:

 for lex in soup.select('lexeme'):
    print(lex.attrs['lexemeid'])
  

Выводит:

 1000006
1000013
  

и т.д.

Комментарии:

1. @Glubbdrubb Действительно! Кроме того, с lxml (как библиотекой, а не только синтаксическим анализатором) — который, в отличие от BS, использует xpath — выражение поиска использовало бы надлежащий корпус, как в (например): doc.xpath('//Inflection[@Form="best.f.sing."]/text()') .