使用BeautifulSoup解析由
标签分隔的行吗?
我有一个页面,看起来像这样:使用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解析这个文档并提取字段?我很难过,因为我需要的那些文本不包含在段落(或类似)标签中,我可以简单地遍历它们。
一旦你有了这个HTML片段,只需用一个正则表达式代替<br />
后跟一个可选换行符换行一个换行符,然后拆分多个换行符。这应该会导致您可以手动处理的多个单独段落。
你可以在任何事情之前先做一点操作。例如,将所有换行符更改为空白,然后将<br />
中的两个或更多个替换为|
等其他分隔符。之后,你可以得到你的领域。
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|
现在,您的公司信息通过管道分开。
也许你可以使用此功能:
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
来将其他所有东西都集中在一起。请注意,您关心的事物也会混在一起 - 您基本上必须处理由生成器生成的每个第二个列表中的每个项目,从第一个包含您关心的事项开始。
您应该查看标签中找到的.strings
属性,然后在其上使用“\ n”.join()。
我slimier问题。这我是如何解决
html=html.replace('<br>','<br />')
感谢您的回答,但不幸的是它只是使用正则表达式不是那么简单。我简化了上述文档以更好地说明我的问题。实际的文档有一堆混乱的HTML格式标签等等。 – jamieb 2010-02-21 07:46:06
但是您不关心文档,只是由'
'标签分隔的部分。使用BeatifulSoup首先提取该部分。 – 2010-02-21 07:50:07
我不确定为什么有人低估了你的答案;我很感激帮助。我会根据你的建议尝试一些想法。我只是希望BeautifulSoup能够消除手动解析的需要。谢谢。 – jamieb 2010-02-21 07:58:23