Как заставить BeautifulSoup анализировать содержимое тегов textarea как HTML?

До версии 3.0.5 BeautifulSoup обрабатывал содержимое ‹textarea> как HTML. Теперь он воспринимает это как текст. В документе, который я разбираю, есть HTML внутри тегов textarea, и я пытаюсь его обработать.

Я пробовал:

    for textarea in soup.findAll('textarea'):
        contents = BeautifulSoup.BeautifulSoup(textarea.contents)
        textarea.replaceWith(contents.html(text=True))

Но я получаю ошибки. Я не могу найти этого в документации, и альтернативные парсеры не помогают. Кто-нибудь знает, как я могу анализировать текстовые поля как HTML?

Редактировать:

Пример HTML:

<textarea class="ks-lazyload-custom">
  <div class="product-view product-view-rug">
    Foobar Womble
    <div class="product-view-head">
      <img src="tps/i1/fo-25.gif" />
    </div>
  </div>
</textarea>

Ошибка:

File "D:\src\cross\tserver\src\tools\sitecrawl\BeautifulSoup.py", line 1913, 
in _detectEncoding '^<\?.*encoding=[\'"](.*?)[\'"].*\?>').match(xml_data)
TypeError: expected string or buffer

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

Что касается реального мира и спецификаций, здесь это на самом деле не особенно актуально. Данные нужно проанализировать, я ищу способ это сделать.


person brofield    schedule 19.04.2010    source источник
comment
Можете ли вы добавить небольшой фрагмент HTML?   -  person Eddy Pronk    schedule 19.04.2010
comment
Вы пытаетесь заставить HTML-синтаксический анализатор поддерживать структуру данных, запрещенную спецификацией HTML. Вероятно, вам следует сделать шаг назад и найти другой способ решения проблемы (т.е. тот, который не зависит от текстовых полей, содержащих что-то иное, кроме CDATA)   -  person Quentin    schedule 19.04.2010
comment
не могли бы вы опубликовать сообщение об ошибке? Без него нам нечем заняться.   -  person Jared Forsyth    schedule 19.04.2010


Ответы (2)


Кажется, это работает довольно хорошо (если я правильно понял, что вы хотели):

for textarea in soup.findAll('textarea'):
    contents = BeautifulSoup.BeautifulSoup(textarea.contents[0]).renderContents()
    textarea.replaceWith(contents)
person Justin Peel    schedule 19.04.2010
comment
Спасибо, похоже, это то, что мне нужно. - person brofield; 20.04.2010

Сейчас я использую следующий код, который в основном работает. Ваш пробег может отличаться.

def _extractText(self, data, encoding):
    if self.isDebug: self._output("_extractText")
    soup = BeautifulSoup.BeautifulSoup(data, fromEncoding=encoding)
    comments = soup.findAll(text=lambda text:isinstance(text, BeautifulSoup.Comment))
    [comment.extract() for comment in comments]
    [script.extract() for script in soup.findAll('script')]
    [css.extract() for css in soup.findAll('style')]
    for textarea in soup.findAll('textarea'):
        textarea.string = self._extractText(textarea.renderContents(), 'UTF-8')
    text = unicode('')
    for line in soup.findAll(text=True):
        line = line.replace('&nbsp;', ' ').strip()  
        if line == '': continue
        if line.startswith('doctype'): continue
        if line.startswith('DOCTYPE'): continue
        text = text + line + '\n'
    return text
person brofield    schedule 19.04.2010