BeautifulSoup не видит теги, вложенные в тег
Проблема описана в заголовке. Больше и сказать нечего. 2 дня бился на рабочем сайте - ничего понять не мог. В конце-концов создал минимально воспроизводимый пример.
Имеем HTML файл:
<!DOCTYPE html>
<html>
<head>
<title>Что внутри тега h4 ?</title>
<meta charset="utf-8">
</head>
<body>
<h4>
111
<p>(1880-1938)</p>
222
<p>Возчик артели возчиков, герой Русско-Японской и Первой мировой войн,
полный Георгиевский кавалер;
Расстрелян в г. Томске в 1938 году.</p>
333
</h4>
</body>
</html>
И крохотную программку на Python, которая ведёт себя очень странно:
#!/usr/bin/python3
from bs4 import BeautifulSoup
with open("index.html", "r") as f:
contents = f.read()
soup = BeautifulSoup(contents, 'lxml')
print(f"HTML:")
print(f"Тег Н4 полностью: {soup.h4}")
print(f"Имя тега: {soup.h4.name}")
print(f"Текст внутри тега: {soup.h4.text}")
Попробуйте запустить программку. В качестве содержимого тега <h4> она покажет строку 111. Т.е., содержимое тегов <p> не видно. Ладно, пусть так. Но и строки 222 и 333 тоже не видны! Мало того, если я вызову метод .finf_all('p4') то ничего не будет найдено!
Это что - ошибка в библиотеке? Или существует какой-то запрет на размещение любых тегов внутри тегов <h?>?
Ответы (2 шт):
Этот код рабочий:
from bs4 import BeautifulSoup
html = '''
<!DOCTYPE html>
<html>
<head>
<title>Что внутри тега h4 ?</title>
<meta charset="utf-8">
</head>
<body>
<h4>
111
<p>(1880-1938)</p>
222
<p>Возчик артели возчиков, герой Русско-Японской и Первой мировой войн,
полный Георгиевский кавалер;
Расстрелян в г. Томске в 1938 году.</p>
333
</h4>
</body>
</html>
'''
soup = BeautifulSoup(html, 'html.parser')
h4 = soup.find('h4')
for item in h4.findAll('p'):
print(item)
Действительно, с lxml не работает. Для него тег h4 закрыт до первого вложенного тега p:
html = """
...
</html>
"""
soup = BeautifulSoup(html, 'lxml')
print(soup.body)
Результат:
<body>
<h4>
111
</h4><p>(1880-1938)</p>
...
Попробуйте с html.parser - с ним работает и он еще поставляется с питоном:
from bs4 import BeautifulSoup
html = """
<!DOCTYPE html>
<html>
<head>
<title>Что внутри тега h4 ?</title>
<meta charset="utf-8">
</head>
<body>
<h4>
111
<p>(1880-1938)</p>
222
<p>Возчик артели возчиков, герой Русско-Японской и Первой мировой войн,
полный Георгиевский кавалер;
Расстрелян в г. Томске в 1938 году.</p>
333
</h4>
</body>
</html>
"""
soup = BeautifulSoup(html, 'html.parser')
print(soup.body.h4.p)
# <p>(1880-1938)</p>
print(soup.find('h4').p)
# <p>(1880-1938)</p>
print(soup.select_one('h4 > p'))
# <p>(1880-1938)</p>
