使用BeautifulSoup解析由<br/>标签分隔的行?

时间:2010-02-21 07:30:07

标签: python parsing beautifulsoup

我有一个看起来像这样的页面:

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解析此文档并提取字段?我很难过,因为我需要的文本位不包含在我可以简单地遍历的段落(或类似)标签中。

5 个答案:

答案 0 :(得分:6)

您应该查看标记中找到的.strings属性,然后在其上使用“\ n”.join()。

答案 1 :(得分:2)

获得此HTML片段后,只需使用正则表达式替换<br />,然后使用单个换行符替换可选换行符,然后拆分多个换行符。这应该会产生多个单独的段落,您可以手动处理。

答案 2 :(得分:0)

你可以先做任何操作。例如,将所有换行符更改为空格,然后将<br />的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)

输出

$ ./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|

现在您的公司信息由管道分隔。

答案 3 :(得分:0)

也许您可以使用此功能:

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

添加内容以检查是否为<br />标记或换行符:

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一起用来将其他所有东西混为一谈。请注意,您关心的事情也会被集中在一起 - 您基本上必须处理由生成的生成器生成的每个第二个列表中的每个项目,从包含您关注的内容的第一个列表开始。

答案 4 :(得分:0)

我有更苗条的问题。这是我如何解决的

html=html.replace('<br>','<br />')