Используя BeautifulSoup для парсинга строк, разделенных <br> теги?

У меня есть страница, которая похожа на это:

Company A<br />
123 Main St.<br />
Suite 101<br />
Someplace, NY 1234<br />
<br />
<br />
<br />
Company B<br />
456 Main St.<br />
Someplace, NY 1234<br />
<br />
<br />
<br />

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

9
задан Cœur 22 January 2017 в 05:41
поделиться

3 ответа

Когда у вас есть этот фрагмент HTML, просто используйте regex для замены
, за которым следует необязательная новая строка, на одну новую строку, затем разделите на несколько новых строк. В результате должно получиться несколько отдельных абзацев, которые можно обработать вручную.

2
ответ дан 3 November 2019 в 03:47
поделиться

Возможно, вы могли бы использовать эту функцию:

def partition_by(pred, iterable):
    current = None
    current_flag = None
    chunk = []
    for item in iterable:
        if current is None:
            current = item
            current_flag = pred(current)
            chunk = [current]
        elif pred(item) == current_flag:
            chunk.append(item)
        else:
            yield chunk
            current = item
            current_flag = not current_flag
            chunk = [current]
    if len(chunk) > 0:
        yield chunk

Добавьте что-нибудь для проверки на то, что это
тег или новая строка:

def is_br(bs):
    try:
        return bs.name == u'br'
    except AttributeError:
        return False

def is_br_or_nl(bs):
    return is_br(bs) or u'\n' == bs

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

Затем используйте partition_by(is_br_or_nl, cs) для получения результата (для cs, установленного в BeautifulSoup.BeautifulSoup(your_example_html).childGenerator())

[[u'Company A'],
 [<br />],
 [u'\n123 Main St.'],
 [<br />],
 [u'\nSuite 101'],
 [<br />],
 [u'\nSomeplace, NY 1234'],
 [<br />, u'\n', <br />, u'\n', <br />, u'\n', <br />],
 [u'\nCompany B'],
 [<br />],
 [u'\n456 Main St.'],
 [<br />],
 [u'\nSomeplace, NY 1234'],
 [<br />, u'\n', <br />, u'\n', <br />, u'\n', <br />]]

Это должно быть достаточно просто для обработки.

Чтобы обобщить это, вам, вероятно, придется написать предикат для проверки того, является ли его аргумент чем-то, о чем вы заботитесь... Затем вы можете использовать его с partition_by, чтобы объединить все остальное. Обратите внимание, что вещи, о которых вы заботитесь, также объединяются вместе - вам, по сути, придется обрабатывать каждый элемент каждого второго списка, создаваемого результирующим генератором, начиная с первого, который включает вещи, о которых вы заботитесь.

0
ответ дан 3 November 2019 в 03:47
поделиться

Вы можете сделать небольшую манипуляцию, прежде чем что-либо делать. например, заменить все новые строки на пробелы, затем заменить 2 и более вхождения
на какой-либо другой разделитель, например |. после этого вы можете получить ваши поля.

html="""
Company A<br />
123 Main St.<br />
Suite 101<br />
Someplace, NY 1234<br />
<br />
<br />
<br />
Company B<br />
456 Main St.<br />
Someplace, NY 1234<br />
<br />
<br />
<br />
"""
import re
newhtml=html.replace("\n","")
pat=re.compile("(<br \/>){2,}",re.DOTALL|re.M)
print pat.sub("|",newhtml)

output

$ ./python.py
Company A<br />123 Main St.<br />Suite 101<br />Someplace, NY 1234|Company B<br />456 Main St.<br />Someplace, NY 1234|

Теперь информация о вашей компании разделена трубами.

0
ответ дан 3 November 2019 в 03:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: