使用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 />后跟一个可选换行符换行一个换行符,然后拆分多个换行符。这应该会导致您可以手动处理的多个单独段落。

+0

感谢您的回答,但不幸的是它只是使用正则表达式不是那么简单。我简化了上述文档以更好地说明我的问题。实际的文档有一堆混乱的HTML格式标签等等。 – jamieb 2010-02-21 07:46:06

+1

但是您不关心文档,只是由'
'标签分隔的部分。使用BeatifulSoup首先提取该部分。 – 2010-02-21 07:50:07

+0

我不确定为什么有人低估了你的答案;我很感激帮助。我会根据你的建议尝试一些想法。我只是希望BeautifulSoup能够消除手动解析的需要。谢谢。 – jamieb 2010-02-21 07:58:23

你可以在任何事情之前先做一点操作。例如,将所有换行符更改为空白,然后将<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 />')