BeautifulSoup анализирует содержимое HTML-файла

У меня есть 30911 html-файлов в папке. Мне нужно (1) проверить, содержит ли он тег:

<strong>123</strong>

и (2) извлечь следующее содержимое, пока этот раздел не закончится.

Но я обнаружил проблему в том, что некоторые из них закончились раньше

<strong>567</strong>

И у некоторых из них нет такого тега, который оканчивается перед

<strong>89/strong> or others(that I do not know because I cant check 30K+files)

Он также имеет разные p p_number в каждом файле и иногда не имеет идентификатора.

Итак, сначала я использую BeautifulSoup для поиска, но я не знаю, как сделать следующее извлечение содержимого.

soup = bs4.BeautifulSoup(fo, "lxml")
m = soup.find("strong", string=re.compile("123"))

Кстати, можно ли сохранить контент в формате txt, но он будет выглядеть как в формате html?

line 1
line 2
...
lin 50

Если использовать p.get_text(strip=true), все вместе.

line1 content line2 content ... 
line50 content....

person Michael Lin    schedule 28.05.2017    source источник


Ответы (1)


Если я вас правильно понял, вы можете сначала найти отправную точку - элемент p, у которого есть элемент strong с текстом «Сессия вопросов и ответов». Затем вы можете выполнить итерацию по элементу p следующие братья и сестры, пока вы не нажмете тот, который имеет элемент strong с текстом "Политика авторских прав".

Полный воспроизводимый пример:

import re

from bs4 import BeautifulSoup


data = """
<body>
    <p class="p p4" id="question-answer-session">
      <strong>
       Question-and-Answer Session
      </strong>
    </p>

    <p class="p p4">
       Hi John and Greg, good afternoon. contents....
    </p>

    <p class="p p14">
      <strong>
       Copyright policy:
      </strong>
      other content about the policy....
    </p>
</body>
"""

soup = BeautifulSoup(data, "html.parser")

def find_question_answer(tag):
    return tag.name == 'p' and tag.find("strong", text=re.compile(r"Question-and-Answer Session"))

question_answer = soup.find(find_question_answer)
for p in question_answer.find_next_siblings("p"):
    if p.find("strong", text=re.compile(r"Copyright policy")):
        break

    print(p.get_text(strip=True))

Отпечатки:

Hi John and Greg, good afternoon. contents....
person alecxe    schedule 28.05.2017
comment
Если я напишу содержимое в новый html-файл, формат будет испорчен. - person Michael Lin; 28.05.2017
comment
@MichaelLin хорошо, какую часть вы хотите записать в файл? - person alecxe; 28.05.2017
comment
Я думаю, что решаю это, я использую p.prettify().encode('ascii', 'ignore').decode('utf-8', 'ignore'), тогда он сохраняет только содержимое перед авторским правом - person Michael Lin; 28.05.2017
comment
Но, как я уже упоминал в своем вопросе, есть еще один тег, связанный с этим: так что это может быть либо авторское право, либо связанное с ним, в любом случае, чтобы решить эту проблему? - person Michael Lin; 28.05.2017
comment
@MichaelLin одним из вариантов было бы настроить регулярное выражение: re.compile(r"(Copyright policy|related)").. - person alecxe; 28.05.2017
comment
Кстати, можно ли сохранить контент в формате txt, но он будет выглядеть как в формате html? Если использовать p.get_text(strip=true), все вместе. Если удалить strip=true, которые остаются p.get_text, между каждой строкой будет от одного до трех пробелов (разрывных строк). - person Michael Lin; 28.05.2017
comment
@MichaelLin, конечно, но давайте рассмотрим это в отдельном вопросе, подумайте о его создании. Спасибо. - person alecxe; 28.05.2017
comment
Я решил это, добавив p.get_text(strip=True) + str('\n\n') - person Michael Lin; 28.05.2017
comment
У меня есть еще одна сложная задача... Я просто публикую вопрос, спасибо за вашу помощь.... stackoverflow.com/questions/44232216/ - person Michael Lin; 29.05.2017