Красивый суп извлечение контента на основе типов - PullRequest
0 голосов
/ 03 июля 2018

Я хочу извлечь пары вопросов (type = 'q') и ответов (type = 'a') как одну точку данных из следующего формата xml:

<?xml version="1.0" encoding="us-ascii"?>
<transcript id="001" >
<body>
<section name="Q&amp;A">
      <speaker id="0">
        <plist>
          <p>Thank you. We'll now be conducting the question-and-answer session. <mark type="Operator Instructions" /> Thank you. Please go ahead with your question.</p>
        </plist>
      </speaker>
      <speaker id="3" type="q">
        <plist>
          <p>Good morning. First of all, Happy New Year.</p>
        </plist>
      </speaker>
      <speaker id="2" type="a">
        <plist>
          <p>Happy New Year, sir.</p>
        </plist>
      </speaker>
      <speaker id="3" type="q">
        <plist>
          <p>Thank you. How is your pain now?.</p>
        </plist>
      </speaker>
       <speaker id="2" type="a">
            <plist>
              <p>Oh, it's better now. I think i am healing.</p>
            </plist>
          </speaker>
</section>
</body>
</transcript>

т.е. выходы должны быть такими: ['Доброе утро. Прежде всего, с Новым годом. С новым годом, сэр. ',' Спасибо. Как твоя боль сейчас? О, теперь лучше. Я думаю, что я исцеляю. ']

Может кто-нибудь, пожалуйста, помогите мне сделать это, используя Красивый суп? Мой текущий код извлекает все теги <p> в документе, но проблема заключается в том, что есть и другие разделы (кроме вопросов и ответов), чьи теги <p> извлекаются.

soup = BeautifulSoup(handler, "html.parser")
texts = []
for node in soup.findAll('p'):
    text = " ".join(node.findAll(text=True))
    #text = clean_text(text)
    texts.append(text)

Ответы [ 2 ]

0 голосов
/ 03 июля 2018

Вы можете найти все вопросы и ответы, используя find_all('speaker', type='q') и find_all('speaker', type='a') соответственно. Затем используйте zip, чтобы присоединиться к соответствующему вопросу и его ответу.

Код:

questions = soup.find_all('speaker', type='q')
answers = soup.find_all('speaker', type='a')

for q, a in zip(questions, answers):
    print(' '.join((q.p.text, a.p.text)))

Выход:

Good morning. First of all, Happy New Year. Happy New Year, sir.
Thank you. How is your pain now?. Oh, it's better now. I think i am healing.

Если вы хотите, чтобы это было в списке, вы можете использовать понимание списка :

q_and_a = [' '.join((q.p.text, a.p.text)) for q, a in zip(questions, answers)]
print(q_and_a)
# ['Good morning. First of all, Happy New Year. Happy New Year, sir.',
#  "Thank you. How is your pain now?. Oh, it's better now. I think i am healing."]
0 голосов
/ 03 июля 2018

Вы можете использовать findAll('speaker', {"type": "q"}), чтобы найти вопросы, и findNext("speaker"), чтобы найти соответствующий ответ.

Ex:

from bs4 import BeautifulSoup
soup = BeautifulSoup(handler, "html.parser")
for node in soup.findAll('speaker', {"type": "q"}):
    print( node.find("p").text )
    print( node.findNext("speaker").find("p").text)
    print( "--" )

Выход:

Good morning. First of all, Happy New Year.
Happy New Year, sir.
--
Thank you. How is your pain now?.
Oh, it's better now. I think i am healing.
--
...