Поиск и замена в HTML с помощью BeautifulSoup

Я хочу использовать BeautfulSoup для поиска и замены <\a> на <\a><br>. Я знаю, как открывать с помощью urllib2, а затем анализировать, чтобы извлечь все теги <a>. Что я хочу сделать, так это найти и заменить закрывающий тег закрывающим тегом плюс разрыв. Любая помощь, очень ценится.

ИЗМЕНИТЬ

Я бы предположил, что это будет что-то похожее на:

soup.findAll('a').

В документации есть:

find(text="ahh").replaceWith('Hooray')

Поэтому я бы предположил, что это будет примерно так:

soup.findAll(tag = '</a>').replaceWith(tag = '</a><br>')

Но это не работает, и python help() мало что дает.


person Kevin    schedule 15.01.2010    source источник


Ответы (3)


Это вставит тег <br> после конца каждого элемента <a>...</a>:

from BeautifulSoup import BeautifulSoup, Tag

# ....

soup = BeautifulSoup(data)
for a in soup.findAll('a'):
    a.parent.insert(a.parent.index(a)+1, Tag(soup, 'br'))

Вы не можете использовать soup.findAll(tag = '</a>'), потому что BeautifulSoup не работает с конечными тегами отдельно — они считаются частью одного и того же элемента.


Если вы хотите поместить элементы <a> внутри элемента <p>, как вы просите в комментарии, вы можете использовать это:

for a in soup.findAll('a'):
    p = Tag(soup, 'p') #create a P element
    a.replaceWith(p)   #Put it where the A element is
    p.insert(0, a)     #put the A element inside the P (between <p> and </p>)

Опять же, вы не создаете <p> и </p> отдельно, потому что они являются частью одного и того же.

person interjay    schedule 15.01.2010
comment
Будет ли это добавлено к каждому открывающему тегу ‹a›? - person Kevin; 15.01.2010
comment
См. мое редактирование. Он будет добавлен после всего элемента ‹a›...‹/a›, поэтому эффективно он будет только после ‹/a›. - person interjay; 15.01.2010
comment
Является ли BeautifulSoup.Tag действительным? Я получаю сообщение об ошибке при попытке использовать этот код. - person Kevin; 15.01.2010
comment
Это зависит от того, как вы импортируете модуль. Я отредактировал, чтобы показать, как это может работать — попробуйте прямо сейчас. - person interjay; 16.01.2010
comment
FWIW это должно быть a.parent.content.index - person Lombo; 06.12.2010
comment
@Lombo a.parent.index тоже работает, по крайней мере, на BS 3.0.8. В более старых версиях этот метод может отсутствовать. - person interjay; 06.12.2010

предположим, что у вас есть элемент, который, как вы знаете, содержит теги разметки «br», один из способов удалить и заменить теги «br» другой строкой выглядит следующим образом:

originalSoup = BeautifulSoup("your_html_file.html")
replaceString = ", " # replace each <br/> tag with ", "
# Ex. <p>Hello<br/>World</p> to <p>Hello, World</p>
cleanSoup = BeautifulSoup(str(originalSoup).replace("<br/>", replaceString))
person Achintya Ashok    schedule 07.07.2015
comment
Это помогло. Спасибо :) - person subodhkalika; 06.02.2018

Вы не заменяете конечный тег; в BeautifulSoup вы имеете дело с объектной моделью документа, как в браузере, а не со строкой, полной HTML. Таким образом, вы не можете «заменить» конечный тег, не заменив также начальный тег.

Что вы хотите сделать, так это вставить новый элемент <br> сразу после элемента <a>...</a>. Для этого вам нужно узнать индекс элемента <a> внутри его родительского элемента и вставить новый элемент сразу после этого индекса. например.

soup= BeautifulSoup('<body>blah <a href="foo">blah</a> blah</body>')
for link in soup.findAll('a'):
    br= Tag(soup, 'br')
    index= link.parent.contents.index(link)
    link.parent.insert(index+1, br)
# soup now serialises to '<body>blah <a href="foo">blah</a><br /> blah</body>'
person bobince    schedule 15.01.2010
comment
Смогу ли я добавлять теги раньше с -1. Скажем, я хотел сделать ‹p› и ‹/p›. Могу ли я добавить ‹p› перед использованием индекса -1 и ‹/p› после использования +1? - person Kevin; 15.01.2010
comment
Вы бы добавили элемент перед выбранным элементом, используя только index, ничего не прибавляя и не минусуя. - person bobince; 16.01.2010