Не ставьте теги html, head и body автоматически, beautifulsoup
используя beautifulsoup с html5lib, он автоматически помещает теги html, head и body:
BeautifulSoup('<h1>FOO</h1>', 'html5lib') # => <html><head></head><body><h1>FOO</h1></body></html>
есть ли какой-либо параметр, который я могу установить, отключить это поведение?
Ответы
Ответ 1
In [35]: import bs4 as bs
In [36]: bs.BeautifulSoup('<h1>FOO</h1>', "html.parser")
Out[36]: <h1>FOO</h1>
Этот анализирует HTML с помощью встроенного HTML-анализатора Python.
Цитирование документов:
В отличие от html5lib, этот анализатор не пытается создать хорошо сформированный HTML, добавив тег <body>
. В отличие от lxml, он даже не добавьте тег <html>
.
В качестве альтернативы вы можете использовать парсер html5lib
и просто выбрать элемент после <body>
:
In [61]: soup = bs.BeautifulSoup('<h1>FOO</h1>', 'html5lib')
In [62]: soup.body.next
Out[62]: <h1>FOO</h1>
Ответ 2
Ваш единственный вариант - не использовать html5lib
для анализа данных.
Это функция библиотеки html5lib
, она исправляет недостающий HTML-код, например, добавление обратно в отсутствующие требуемые элементы.
Ответ 3
Давайте сначала создадим образец супа:
soup=BeautifulSoup("<head></head><body><p>content</p></body>")
Вы можете получить html и body child, указав soup.body.<tag>
:
# python3: get body first child
print(next(soup.body.children))
# if first child tag is rss
print(soup.body.rss)
Также вы можете использовать unwrap() для удаления тела, головы и HTML
soup.html.body.unwrap()
if soup.html.select('> head'):
soup.html.head.unwrap()
soup.html.unwrap()
Если вы загрузите XML файл, bs4.diagnose(data)
скажет вам использовать lxml-xml
, который не обернет ваш суп с html+body
>>> BS('<foo>xxx</foo>', 'lxml-xml')
<foo>xxx</foo>
Ответ 4
Еще одно решение:
from bs4 import BeautifulSoup
soup = BeautifulSoup('<p>Hello <a href="http://google.com">Google</a></p><p>Hi!</p>', 'lxml')
# content handling example (just for example)
# replace Google with StackOverflow
for a in soup.findAll('a'):
a['href'] = 'http://stackoverflow.com/'
a.string = 'StackOverflow'
print ''.join([unicode(i) for i in soup.html.body.findChildren(recursive=False)])
Ответ 5
Если вы хотите, чтобы это выглядело лучше, попробуйте это:
BeautifulSoup ([содержимое, которое вы хотите проанализировать] .prettify())