Как распечатать определенные элементы из проанализированного HTML? - PullRequest
0 голосов
/ 30 сентября 2019

Я пытаюсь напечатать определенные строки из моей строки HTML-кода, проанализированной с помощью BS4.

Я хочу, чтобы мой конечный результат выглядел так:

КАК ПЕЧАТЬ ЭТОТ ВОПРОС?

a. Я хочу напечатать это

б. Я ХОЧУ ПЕЧАТЬ ЭТО СЛИШКОМ

c. Я ХОЧУ ПЕЧАТЬ ЭТО ТАКЖЕ

d. Я ХОЧУ ПЕЧАТЬ ЭТО ХОРОШО

ПРАВИЛЬНЫЙ ОТВЕТориентируйся глазами. Мой конечный результат включает печать строк 23, 33, 39, 45, 51 и 63. Как мне этого добиться?

<div class="que multichoice deferredfeedback correct" id="q7">
   <div class="info">
    <h3 class="no">
     Question
     <span class="qno">
      7
     </span>
    </h3>
    <div class="state">
     Correct
    </div>
    <div class="grade">
     Mark 1.00 out of 1.00
    </div>
   </div>
   <div class="content">
    <div class="formulation">
     <h4 class="accesshide">
      Question text
     </h4>
     <input name="q7391425:7_:sequencecheck" type="hidden" value="3"/>
     <div class="qtext">
      HOW DO I PRINT THIS QUESTION?
     </div>
     <div class="ablock">
      <div class="prompt">
       Select one:
      </div>
      <div class="answer">
       <div class="r0">
        <input disabled="disabled" id="q7391425:7_answer0" name="q7391425:7_answer" type="radio" value="0"/>
        <label for="q7391425:7_answer0">
         a. I WANT TO PRINT THIS
        </label>
       </div>
       <div class="r1 correct">
        <input checked="checked" disabled="disabled" id="q7391425:7_answer1" name="q7391425:7_answer" type="radio" value="1"/>
        <label for="q7391425:7_answer1">
         b. I WANT TO PRINT THIS TOO
        </label>
       </div>
       <div class="r0">
        <input disabled="disabled" id="q7391425:7_answer2" name="q7391425:7_answer" type="radio" value="2"/>
        <label for="q7391425:7_answer2">
         c. I WANT TO PRINT THIS ALSO
        </label>
       </div>
       <div class="r1">
        <input disabled="disabled" id="q7391425:7_answer3" name="q7391425:7_answer" type="radio" value="3"/>
        <label for="q7391425:7_answer3">
         d. I WANT TO PRINT THIS AS WELL
        </label>
       </div>
      </div>
     </div>
    </div>
    <div class="outcome">
     <h4 class="accesshide">
      Feedback
     </h4>
     <div class="feedback">
      <div class="rightanswer">
       THE CORRECT ANSWER IS: I WANT TO PRINT THIS
      </div>
     </div>
    </div>
   </div>
  </div>

Учитывая понимание Фураса, я понял, что должен был включить больше информации.

Я сейчас использую

from bs4 import BeautifulSoup as BS
text = (input('Enter Source Code File Name - '))
with open(text) as file:
  data = file.read()
soup = BS(data, 'html.parser')
for qtext in soup.find_all('div', class_='qtext'):
  print(qtext.text.strip())
for labels in soup.find_all('label'):
  print(labels.text.strip())
for ras in soup.find_all('div', class_='rightanswer'):
  print(ras.text.strip())

Каждый из текстовых файлов с исходным кодом, который у меня есть, содержит 10 вопросов с несколькими вариантами ответов, и я хочу, чтобы код печатался в формате:

QText

Ответ0-3

RightAnswer

(и затем повторять этот цикл до тех пор, пока больше не останется или 9 раз)

--- Какэто прямо сейчас, он возвращает следующее ---

QText (x10)

Answer0-3 (x10)

RightAnswer (x10)

Как мне изменить это, чтобы завершить один цикл получения 1 qtext, 4 answer0-3 и затем 1 rightanswer перед началом другого цикла?

1 Ответ

0 голосов
/ 30 сентября 2019

Все элементы можно найти, используя tag или class

print(soup.find('div', class_='qtext').text.strip())

# HOW DO I PRINT THIS QUESTION?

for item in soup.find_all('label'):
    print(item.text.strip())

# a. I WANT TO PRINT THIS
# b. I WANT TO PRINT THIS TOO
# c. I WANT TO PRINT THIS ALSO
# d. I WANT TO PRINT THIS AS WELL

print(soup.find('div', class_='rightanswer').text.strip())

# THE CORRECT ANSWER IS: I WANT TO PRINT THIS

Вместо .text.strip() вы также можете использовать .get_text(strip=True)


Полный код:

data = '''
<div class="que multichoice deferredfeedback correct" id="q7">
   <div class="info">
    <h3 class="no">
     Question
     <span class="qno">
      7
     </span>
    </h3>
    <div class="state">
     Correct
    </div>
    <div class="grade">
     Mark 1.00 out of 1.00
    </div>
   </div>
   <div class="content">
    <div class="formulation">
     <h4 class="accesshide">
      Question text
     </h4>
     <input name="q7391425:7_:sequencecheck" type="hidden" value="3"/>
     <div class="qtext">
      HOW DO I PRINT THIS QUESTION?
     </div>
     <div class="ablock">
      <div class="prompt">
       Select one:
      </div>
      <div class="answer">
       <div class="r0">
        <input disabled="disabled" id="q7391425:7_answer0" name="q7391425:7_answer" type="radio" value="0"/>
        <label for="q7391425:7_answer0">
         a. I WANT TO PRINT THIS
        </label>
       </div>
       <div class="r1 correct">
        <input checked="checked" disabled="disabled" id="q7391425:7_answer1" name="q7391425:7_answer" type="radio" value="1"/>
        <label for="q7391425:7_answer1">
         b. I WANT TO PRINT THIS TOO
        </label>
       </div>
       <div class="r0">
        <input disabled="disabled" id="q7391425:7_answer2" name="q7391425:7_answer" type="radio" value="2"/>
        <label for="q7391425:7_answer2">
         c. I WANT TO PRINT THIS ALSO
        </label>
       </div>
       <div class="r1">
        <input disabled="disabled" id="q7391425:7_answer3" name="q7391425:7_answer" type="radio" value="3"/>
        <label for="q7391425:7_answer3">
         d. I WANT TO PRINT THIS AS WELL
        </label>
       </div>
      </div>
     </div>
    </div>
    <div class="outcome">
     <h4 class="accesshide">
      Feedback
     </h4>
     <div class="feedback">
      <div class="rightanswer">
       THE CORRECT ANSWER IS: I WANT TO PRINT THIS
      </div>
     </div>
    </div>
   </div>
  </div>
'''

from bs4 import BeautifulSoup as BS

soup = BS(data, 'html.parser')

print(soup.find('div', class_='qtext').text.strip())
for item in soup.find_all('label'):
    print(item.text.strip())
print(soup.find('div', class_='rightanswer').text.strip())

РЕДАКТИРОВАТЬ: Если у вас есть больше вопросов в HTML, вы можете найти тег, который содержит один вопрос с его выбором и правильным ответом - т.е. <div class="que multichoice deferredfeedback correct" id="q7"> - а затем найдите все эти теги и затем выполните поиск внутри этих тегов.

for questions in soup.find_all('div', class_='multichoice'):

    print(questions.find('div', class_='qtext').text.strip())
    for item in questions.find_all('label'):
        print(item.text.strip())
    print(questions.find('div', class_='rightanswer').text.strip())

Полный код - я дублировал один и тот же HTML-код для имитации двух вопросов:

data = '''
<div class="que multichoice deferredfeedback correct" id="q7">
   <div class="info">
    <h3 class="no">
     Question
     <span class="qno">
      7
     </span>
    </h3>
    <div class="state">
     Correct
    </div>
    <div class="grade">
     Mark 1.00 out of 1.00
    </div>
   </div>
   <div class="content">
    <div class="formulation">
     <h4 class="accesshide">
      Question text
     </h4>
     <input name="q7391425:7_:sequencecheck" type="hidden" value="3"/>
     <div class="qtext">
      HOW DO I PRINT THIS QUESTION?
     </div>
     <div class="ablock">
      <div class="prompt">
       Select one:
      </div>
      <div class="answer">
       <div class="r0">
        <input disabled="disabled" id="q7391425:7_answer0" name="q7391425:7_answer" type="radio" value="0"/>
        <label for="q7391425:7_answer0">
         a. I WANT TO PRINT THIS
        </label>
       </div>
       <div class="r1 correct">
        <input checked="checked" disabled="disabled" id="q7391425:7_answer1" name="q7391425:7_answer" type="radio" value="1"/>
        <label for="q7391425:7_answer1">
         b. I WANT TO PRINT THIS TOO
        </label>
       </div>
       <div class="r0">
        <input disabled="disabled" id="q7391425:7_answer2" name="q7391425:7_answer" type="radio" value="2"/>
        <label for="q7391425:7_answer2">
         c. I WANT TO PRINT THIS ALSO
        </label>
       </div>
       <div class="r1">
        <input disabled="disabled" id="q7391425:7_answer3" name="q7391425:7_answer" type="radio" value="3"/>
        <label for="q7391425:7_answer3">
         d. I WANT TO PRINT THIS AS WELL
        </label>
       </div>
      </div>
     </div>
    </div>
    <div class="outcome">
     <h4 class="accesshide">
      Feedback
     </h4>
     <div class="feedback">
      <div class="rightanswer">
       THE CORRECT ANSWER IS: I WANT TO PRINT THIS
      </div>
     </div>
    </div>
   </div>
  </div>
<div class="que multichoice deferredfeedback correct" id="q7">
   <div class="info">
    <h3 class="no">
     Question
     <span class="qno">
      7
     </span>
    </h3>
    <div class="state">
     Correct
    </div>
    <div class="grade">
     Mark 1.00 out of 1.00
    </div>
   </div>
   <div class="content">
    <div class="formulation">
     <h4 class="accesshide">
      Question text
     </h4>
     <input name="q7391425:7_:sequencecheck" type="hidden" value="3"/>
     <div class="qtext">
      HOW DO I PRINT THIS QUESTION?
     </div>
     <div class="ablock">
      <div class="prompt">
       Select one:
      </div>
      <div class="answer">
       <div class="r0">
        <input disabled="disabled" id="q7391425:7_answer0" name="q7391425:7_answer" type="radio" value="0"/>
        <label for="q7391425:7_answer0">
         a. I WANT TO PRINT THIS
        </label>
       </div>
       <div class="r1 correct">
        <input checked="checked" disabled="disabled" id="q7391425:7_answer1" name="q7391425:7_answer" type="radio" value="1"/>
        <label for="q7391425:7_answer1">
         b. I WANT TO PRINT THIS TOO
        </label>
       </div>
       <div class="r0">
        <input disabled="disabled" id="q7391425:7_answer2" name="q7391425:7_answer" type="radio" value="2"/>
        <label for="q7391425:7_answer2">
         c. I WANT TO PRINT THIS ALSO
        </label>
       </div>
       <div class="r1">
        <input disabled="disabled" id="q7391425:7_answer3" name="q7391425:7_answer" type="radio" value="3"/>
        <label for="q7391425:7_answer3">
         d. I WANT TO PRINT THIS AS WELL
        </label>
       </div>
      </div>
     </div>
    </div>
    <div class="outcome">
     <h4 class="accesshide">
      Feedback
     </h4>
     <div class="feedback">
      <div class="rightanswer">
       THE CORRECT ANSWER IS: I WANT TO PRINT THIS
      </div>
     </div>
    </div>
   </div>
  </div>
'''  

from bs4 import BeautifulSoup as BS

soup = BS(data, 'html.parser')

for questions in soup.find_all('div', class_='multichoice'):

    print(questions.find('div', class_='qtext').text.strip())
    for item in questions.find_all('label'):
        print(item.text.strip())
    print(questions.find('div', class_='rightanswer').text.strip())
    print('---')

Или вы можете использовать for -loop для группировки элементов

from bs4 import BeautifulSoup as BS

soup = BS(data, 'html.parser')

all_questions = soup.find_all('div', class_='qtext')
all_choices = soup.find_all('label')
all_answers = soup.find_all('div', class_='rightanswer')

for x in range(len(all_questions)):
    print(all_questions[x].text.strip())

    y = x*4
    for item in all_choices[y:y+4]:
        print(item.text.strip())

    print(all_answers[x].text.strip())
    print('---')

Полный код:

data = '''
<div class="que multichoice deferredfeedback correct" id="q7">
   <div class="info">
    <h3 class="no">
     Question
     <span class="qno">
      7
     </span>
    </h3>
    <div class="state">
     Correct
    </div>
    <div class="grade">
     Mark 1.00 out of 1.00
    </div>
   </div>
   <div class="content">
    <div class="formulation">
     <h4 class="accesshide">
      Question text
     </h4>
     <input name="q7391425:7_:sequencecheck" type="hidden" value="3"/>
     <div class="qtext">
      HOW DO I PRINT THIS QUESTION?
     </div>
     <div class="ablock">
      <div class="prompt">
       Select one:
      </div>
      <div class="answer">
       <div class="r0">
        <input disabled="disabled" id="q7391425:7_answer0" name="q7391425:7_answer" type="radio" value="0"/>
        <label for="q7391425:7_answer0">
         a. I WANT TO PRINT THIS
        </label>
       </div>
       <div class="r1 correct">
        <input checked="checked" disabled="disabled" id="q7391425:7_answer1" name="q7391425:7_answer" type="radio" value="1"/>
        <label for="q7391425:7_answer1">
         b. I WANT TO PRINT THIS TOO
        </label>
       </div>
       <div class="r0">
        <input disabled="disabled" id="q7391425:7_answer2" name="q7391425:7_answer" type="radio" value="2"/>
        <label for="q7391425:7_answer2">
         c. I WANT TO PRINT THIS ALSO
        </label>
       </div>
       <div class="r1">
        <input disabled="disabled" id="q7391425:7_answer3" name="q7391425:7_answer" type="radio" value="3"/>
        <label for="q7391425:7_answer3">
         d. I WANT TO PRINT THIS AS WELL
        </label>
       </div>
      </div>
     </div>
    </div>
    <div class="outcome">
     <h4 class="accesshide">
      Feedback
     </h4>
     <div class="feedback">
      <div class="rightanswer">
       THE CORRECT ANSWER IS: I WANT TO PRINT THIS
      </div>
     </div>
    </div>
   </div>
  </div>
<div class="que multichoice deferredfeedback correct" id="q7">
   <div class="info">
    <h3 class="no">
     Question
     <span class="qno">
      7
     </span>
    </h3>
    <div class="state">
     Correct
    </div>
    <div class="grade">
     Mark 1.00 out of 1.00
    </div>
   </div>
   <div class="content">
    <div class="formulation">
     <h4 class="accesshide">
      Question text
     </h4>
     <input name="q7391425:7_:sequencecheck" type="hidden" value="3"/>
     <div class="qtext">
      HOW DO I PRINT THIS QUESTION?
     </div>
     <div class="ablock">
      <div class="prompt">
       Select one:
      </div>
      <div class="answer">
       <div class="r0">
        <input disabled="disabled" id="q7391425:7_answer0" name="q7391425:7_answer" type="radio" value="0"/>
        <label for="q7391425:7_answer0">
         a. I WANT TO PRINT THIS
        </label>
       </div>
       <div class="r1 correct">
        <input checked="checked" disabled="disabled" id="q7391425:7_answer1" name="q7391425:7_answer" type="radio" value="1"/>
        <label for="q7391425:7_answer1">
         b. I WANT TO PRINT THIS TOO
        </label>
       </div>
       <div class="r0">
        <input disabled="disabled" id="q7391425:7_answer2" name="q7391425:7_answer" type="radio" value="2"/>
        <label for="q7391425:7_answer2">
         c. I WANT TO PRINT THIS ALSO
        </label>
       </div>
       <div class="r1">
        <input disabled="disabled" id="q7391425:7_answer3" name="q7391425:7_answer" type="radio" value="3"/>
        <label for="q7391425:7_answer3">
         d. I WANT TO PRINT THIS AS WELL
        </label>
       </div>
      </div>
     </div>
    </div>
    <div class="outcome">
     <h4 class="accesshide">
      Feedback
     </h4>
     <div class="feedback">
      <div class="rightanswer">
       THE CORRECT ANSWER IS: I WANT TO PRINT THIS
      </div>
     </div>
    </div>
   </div>
  </div>
'''  

from bs4 import BeautifulSoup as BS

soup = BS(data, 'html.parser')

all_questions = soup.find_all('div', class_='qtext')
all_choices = soup.find_all('label')
all_answers = soup.find_all('div', class_='rightanswer')

for x in range(len(all_questions)):
    print(all_questions[x].text.strip())

    y = x*4
    for item in all_choices[y:y+4]:
        print(item.text.strip())

    print(all_answers[x].text.strip())
    print('---')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...