BeautifulSoup: анализировать только часть страницы

Я хочу проанализировать часть html-страницы, скажем

my_string = """
<p>Some text. Some text. Some text. Some text. Some text. Some text.
   <a href="#">Link1</a>
   <a href="#">Link2</a>
</p>
<img src="image.png" />
<p>One more paragraph</p>
"""

Я передаю эту строку в BeautifulSoup:

soup = BeautifulSoup(my_string)
# add rel="nofollow" to <a> tags
# return comment to the template

Но во время синтаксического анализа BeautifulSoup добавляет теги <html>, <head> и <body> (при использовании парсеров lxml или html5lib), и мне они не нужны в моем коде. Единственный способ, который я нашел до сих пор, чтобы избежать этого, - это использовать html.parser.

Интересно, есть ли способ избавиться от лишних тегов с помощью lxml — самого быстрого парсера.

ОБНОВЛЕНИЕ

Изначально мой вопрос был задан некорректно. Теперь я удалил обертку <div> из своего примера, так как обычный пользователь не использует этот тег. По этой причине мы не можем использовать метод .extract() для избавления от тегов <html>, <head> и <body>.


person Vlad T.    schedule 30.06.2012    source источник
comment
Вы пробовали использовать MinimalSoup вместо BeautifulSoup? (Та же библиотека, другой конструктор). В таких вещах должно быть меньше строгости.   -  person Andrew Gorcester    schedule 01.07.2012
comment
Я пытался, но не мог понять, как это работает.   -  person Vlad T.    schedule 12.07.2012


Ответы (3)


Использовать

soup.body.renderContents()
person Antony Hatchkins    schedule 05.12.2012

lxml всегда будет добавлять эти теги, но вы можете использовать Tag.extract() для удаления ваш тег <div> внутри них:

comment = soup.body.div.extract()
person Leonard Richardson    schedule 01.07.2012

Я мог бы решить проблему, используя свойство .contents:

try:
    children = soup.body.contents
    string = ''
    for child in children:
        string += str(item)
    return string
except AttributeError:
    return str(soup)

Я думаю, что ''.join(soup.body.contents) было бы более аккуратным преобразованием списка в строку, но это не работает, и я получаю

TypeError: элемент последовательности 0: ожидаемая строка, тег найден

person Vlad T.    schedule 11.07.2012