2010-02-21 235 views
9

我有一個頁面,看起來像這樣:使用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解析這個文檔並提取字段?我很難過,因爲我需要的那些文本不包含在段落(或類似)標籤中,我可以簡單地遍歷它們。

回答

2

一旦你有了這個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

0

你可以在任何事情之前先做一點操作。例如,將所有換行符更改爲空白,然後將<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| 

現在,您的公司信息通過管道分開。

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來將其他所有東西都集中在一起。請注意,您關心的事物也會混在一起 - 您基本上必須處理由生成器生成的每個第二個列表中的每個項目,從第一個包含您關心的事項開始。

6

您應該查看標籤中找到的.strings屬性,然後在其上使用「\ n」.join()。

0

我slimier問題。這我是如何解決

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