[英]Beautiful Soup Multiple Answers from Single Question
我正在尝试使用 Beautiful Soup 抓取一个有多个答案的 html 测验。 我能够独立地抓取答案和问题,并且已经找到了如何组合其中一些的方法,错误如下。 问题是有些问题的答案不止一个,所以我在输出上相差一个,即问题 1 有多个答案只会有一个,然后问题 2 会有问题 1 的答案。 html 代码中有很多层,即复选框、正确的标签和不正确的标签答案……这对下一个问题以相同的顺序重复。 最终状态是抓取正确的问题和答案,然后将它们转储到闪存卡程序中以供学习之用。 我不确定这是否是最好的方法,或者是否有另一个可以更好地工作的 python 库? 任何方向和帮助将不胜感激。
<div class="detailed-result-panel--panel-row--2aE8z detailed-result-panel--question-container--7NyiS">
<form class="">
<div class="mc-quiz-question--header--3fsHJ">
<span>
Question 1:
</span>
<span class="mc-quiz-question--incorrect--1QOBY">
Incorrect
</span>
<div class="mc-quiz-question--question-prompt--2_dlz" data-purpose="safely-set-inner-html:rich-text-viewer:html" id="question-prompt">
<p>
Select TWO examples of XYZ.
</p>
</div>
</div>
<ul aria-labelledby="question-prompt" role="group">
<li>
<div class="mc-quiz-answer--answer-body--1JtTQ mc-quiz-answer--incorrect--2v11K checkbox boxed disabled">
<label title="">
<div class="pos-r">
<input checked="" data-index="0" disabled="" name="answer" type="checkbox"/>
<span class="toggle-control-label checkbox-label">
</span>
</div>
<div class="fx toggle-control-label">
<div class="fx fx-lc mc-quiz-answer--incorrect--2v11K">
<div class="fx">
<div class="mc-quiz-answer--question-copy--314BC" data-purpose="safely-set-inner-html:rich-text-viewer:html">
<p>
ANSWER 1
</p>
</div>
</div>
<div class="mc-quiz-answer--correctness--3pFQG">
(Incorrect)
</div>
</div>
</div>
</label>
</div>
</li>
<li>
<div class="mc-quiz-answer--answer-body--1JtTQ checkbox boxed disabled">
<label title="">
<div class="pos-r">
<input data-index="1" disabled="" name="answer" type="checkbox"/>
<span class="toggle-control-label checkbox-label">
</span>
</div>
<div class="fx toggle-control-label">
<div class="fx fx-lc">
<div class="fx">
<div class="mc-quiz-answer--question-copy--314BC" data-purpose="safely-set-inner-html:rich-text-viewer:html">
<p>
ANSWER 2
</p>
</div>
</div>
</div>
</div>
</label>
</div>
</li>
<li>
<div class="mc-quiz-answer--answer-body--1JtTQ mc-quiz-answer--correct--is6Db checkbox boxed disabled">
<label title="">
<div class="pos-r">
<input checked="" data-index="2" disabled="" name="answer" type="checkbox"/>
<span class="toggle-control-label checkbox-label">
</span>
</div>
<div class="fx toggle-control-label">
<div class="fx fx-lc mc-quiz-answer--correct--is6Db">
<div class="fx">
<div class="mc-quiz-answer--question-copy--314BC" data-purpose="safely-set-inner-html:rich-text-viewer:html">
<p>
ANSWER 3
</p>
</div>
</div>
<div class="mc-quiz-answer--correctness--3pFQG">
(Correct)
</div>
</div>
</div>
</label>
</div>
</li>
<li>
<div class="mc-quiz-answer--answer-body--1JtTQ mc-quiz-answer--correct--is6Db checkbox boxed disabled">
<label title="">
<div class="pos-r">
<input data-index="3" disabled="" name="answer" type="checkbox"/>
<span class="toggle-control-label checkbox-label">
</span>
</div>
<div class="fx toggle-control-label">
<div class="fx fx-lc mc-quiz-answer--correct--is6Db">
<div class="fx">
<div class="mc-quiz-answer--question-copy--314BC" data-purpose="safely-set-inner-html:rich-text-viewer:html">
<p>
XYZ Management
</p>
</div>
</div>
<div class="mc-quiz-answer--correctness--3pFQG">
(Correct)
</div>
</div>
</div>
</label>
</div>
</li>
<li>
<div class="mc-quiz-answer--answer-body--1JtTQ checkbox boxed disabled">
<label title="">
<div class="pos-r">
<input data-index="4" disabled="" name="answer" type="checkbox"/>
<span class="toggle-control-label checkbox-label">
</span>
</div>
<div class="fx toggle-control-label">
<div class="fx fx-lc">
<div class="fx">
<div class="mc-quiz-answer--question-copy--314BC" data-purpose="safely-set-inner-html:rich-text-viewer:html">
<p>
ANSWER 4
</p>
</div>
</div>
</div>
</div>
</label>
</div>
</li>
</ul>
from bs4 import BeautifulSoup
import re
with open('inputfile.html', encoding="utf-8") as f:
contents = f.read()
soup = BeautifulSoup(contents, 'lxml')
questions = soup.find_all('div','mc-quiz-question--question-prompt--2_dlz')
answers = soup.find_all('div','fx fx-lc mc-quiz-answer--correct--is6Db', 'safely-set-inner-html:rich-text-viewer:html')
for q, a in zip(questions, answers):
print(' '.join((q.p.text, a.p.text)))
Select TWO examples of XYZ. ANSWER 3
What does XYZ provide? ANSWER 4 <--- this is from the previous Question
Question: Select TWO examples of XYZ.
Answer: ANSWER 3 ANSWER 4
Question: What does XYZ provide?
Answer: ANSWER 1
Question: How does XYZ do ABC?
Answer: ANSWER 3
这将解析大约一半然后错误,假设它期望文本类型并返回其他内容。
Traceback (most recent call last):
File "myparsar.py", line 111, in <module>
print(' '.join((q.p.text, a.p.text)))
AttributeError: 'NoneType' object has no attribute 'text'
好的,如果我理解正确,您想从一个问题中提取多个更正的答案。 你大部分都做对了。 但是在 for 循环中,您错误地使用了 zip 函数。 我建议你在这里检查一下。
如果您有多个问题,您应该开始通过其容器查找所有问题:
question_containers = soup.find_all('div', 'detailed-result-panel--question-container--7NyiS')
然后您可以遍历每个容器以获取问题和答案。
for container in question_containers:
question = container.find('div', 'mc-quiz-question--question-prompt--2_dlz')
answers = container.find_all('div', 'fx fx-lc mc-quiz-answer--correct--is6Db', 'safely-set-inner-html:rich-text-viewer:html')
由于您对一个问题有多个答案,因此您应该使用嵌套的 for 循环来遍历所有答案:
ans = []
for a in answers:
answer_text = a.text.strip().split('\n')
ans.append(answer_text[0])
print('Question:\n', question.text.strip(), '\nAnswers:\n', ', '.join(ans))
对于每个答案,我使用 .text、.strip 和 .split 来仅获取答案文本。 然后我将其附加到答案列表中,并使用此列表打印出您想要的内容。
soup = BeautifulSoup(contents, 'lxml')
question_containers = soup.find_all('div', 'detailed-result-panel--question-container--7NyiS')
for container in question_containers:
question = container.find('div', 'mc-quiz-question--question-prompt--2_dlz')
answers = container.find_all('div', 'fx fx-lc mc-quiz-answer--correct--is6Db', 'safely-set-inner-html:rich-text-viewer:html')
ans = []
for a in answers:
answer_text = a.text.strip().split('\n')
ans.append(answer_text[0])
print('Question:\n', question.text.strip(), '\nAnswers:\n', ', '.join(ans))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.