Синтаксический анализ статей из XML-файла

#python #xml #elementtree

#python #xml #elementtree

Вопрос:

Я хочу проанализировать XML-файл, включающий несколько статей:

 <root>
    <article id="0000001" published-at="2017-10-12" title="Trump Just Woke Up amp;amp; Viciously Attacked Puerto Ricans On Twitter Like A Cruel Old Man">
      <p>Donald Trump ran on many braggadocios and largely unrealistic campaign promises. One of <a href="http://www.cnn.com/2017/03/16/politics/trump-infrastructure/index.html" type="external">those promises</a> was to be the best, the hugest, the most competent
        infrastructure president the United States has ever seen. Trump was going to fix every infrastructure problem in the country and Make America Great Again in the process.</p>
      <p>That is, unless you’re a brown American. In that case, you’re on your own, even after a massive natural disaster like Hurricane Maria.</p>
      <p>Puerto Rico’s debt, which the Puerto Rican citizens not in government would have no responsibility for, has nothing to do with using federal emergency disaster funds to save the lives of American citizens there. The infrastructure is certainly a mess
        at this point after a Category 5 hurricane ripped through the island, and <a href="http://abcnews.go.com/US/16-percent-puerto-rico-power-weeks-hurricane-maria/story?id=50417366" type="external">84 percent</a> of Puerto Rican people are currently without
        electricity.</p>
      <p>Emergency efforts after Hurricanes Irma and Harvey reportedly went very well and Trump praised himself as well and even saw his disastrous approval ratings tick up slightly as a result. However, the insufficient response in Puerto Rico has nothing to
        do with Trump, in his mind, and can only be blamed on the people there who do not live in a red state and have no electoral college votes to offer the new president for 2020.</p>
      <p>They’re on their own.</p>
      <p>Twitter responded with sheer incredulity at Trump’s vicious attack on an already suffering people.</p> Featured image screengrab via
      <p><a href="http://www.youtube.com/watch?v=Z4pMxaH5oxsamp;amp;t=57s" type="external">YouTube</a></p>
    </article>
    <article id="0000002" published-at="2017-10-11" title="Liberals wailing about gun control, but what about abortion?">
      Photo By Justin Sullivan/Getty Images
      <p>In response to Joyce Newman’s recent letter about a conversation about guns: According to the National Right to Life Organization, approximately 600,000 babies are murdered every year by Planned Parenthood with more than 52 million murdered since Roe
        v. Wade. This makes Planned Parenthood the biggest mass murderer in the history of the world. Is she willing to have a serious conversation about that? Where is her outrage over that?</p>
      <p>More people die every year from overdoses or auto accidents then from guns. More people die every year from obesity then from guns. Where is her outrage over those issues?</p>
      <p>The left’s obsession with gun “control” is just that, control. It has always been about Democrats wanting to control every aspect of your life. They support Planned Parenthood but go ballistic when a gun is used to kill someone. It’s the old game of
        “don’t pay any attention to what’s going on over there, but look what’s happening here.”</p>
    </article>
</root>
  

Я смог извлечь идентификатор статьи и заголовок, но я не понял, как я могу извлечь содержимое с <p></p> тегами.
Я пытался использовать следующий код:

 for article in root.iter():
    p = article.find('p').text
  

Я получил эту ошибку :

Объект ‘NoneType’ не имеет атрибута ‘text’

Может ли кто-нибудь помочь мне проверить, как я должен исправить код, и, более того, как я могу извлечь их без <a></a> тегов?

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

1. Пожалуйста, предоставьте содержимое XML в виде текста, а не изображения.

2. Теперь я перешел к тексту 🙂

Ответ №1:

Используете ли вы модуль beautifulsoup? Если нет, я бы настоятельно рекомендовал использовать его там, вы можете использовать функцию:

 content = article.select('p')
for element in content:
    content.append(element.text)
    content.remove(element)
  

Это должно дать вам все абзацы.

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

1. Спасибо! Я использовал дерево элементов. Однако, когда я использовал beautifulsoup для вашего кода: for content in soup.find_all('article'): content = article.select('p').text . Я получил сообщение об ошибке «объект ‘list’ не имеет атрибута ‘text'»

2. Извините, когда вы используете . функция find позволяет получить список всех элементов, являющихся абзацами. Вам нужно пройти по списку и превратить каждый элемент в абзац. Я отредактировал код, чтобы он работал.

3. спасибо, кажется, работает .. 🙂 но знаете ли вы, как я могу не возвращать теги <p></p> из текстов? поскольку теги — это не то, что я хотел

4. О да… Я думаю, вам просто нужно создать содержимое списка перед циклом for. Тогда результат должен быть без каких-либо <p> .

Ответ №2:

Используйте тот код, который работал у меня:

 from bs4 import BeautifulSoup
article = your_file_text
article = BeautifulSoup(article, "html.parser")

content = []
for element in article.find_all('p'):
    element = element.text.strip()
    content.append(element)
  

Ответ №3:

Я предполагаю, что вы используете xml.etree.ElementTree, так что попробуйте:

 for article in root.iter():
    pg = article.findall('p')
    if pg:
       p = pg[0]

  

или вы можете выполнить итерацию, чтобы получить все значения.

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

1. спасибо 🙂 Я попробовал ваш способ, но он вернул только первый элемент ‘p’.. но как я могу повторить весь элемент ‘p’, если каждая статья, которая у меня есть, содержит разное количество элементов ‘p’?

2. Я не понимаю, что вы имели в виду под инструкцией для pg? Но я действительно хотел бы знать, как это будет работать здесь 🙂