2016-10-02 43 views
2

我颳了所有具有相似格式的多個頁面,但它在這裏和那裏稍微變化,並且沒有用於搜索我需要的類。Beautifulsoup基於nextSibling標記名稱獲取文本

的格式如下:

<div id="mainContent"> 

    <p>Some Text I don't want</p> 
    <p>Some Text I don't want</p> 
    <p>Some Text I don't want</p> 
    <span> More text I don't want</span> 
    <ul>...unordered-list items..</ul> 

    <p>Text I WANT</p> 
    <ol>...ordered-list items..</ol> 

    <p>Text I WANT</p> 
    <ol>...ordered-list items..</ol> 

</div> 

有序/無序列表和其他標籤的變化取決於在頁面上的數量,但什麼保持不變的是我總是想從<p>標籤是文本<ol>標記的前一個兄弟。

我想要什麼(不工作)是:

main = soup.find("div", {"id":"mainContent"}) 

for d in main.children: 
    if d.name == 'p' and d.nextSibling.name == 'ol': 
     print(d.text) 
    else: 
     print("fail") 

的放出來的,這是fail每次迭代。在試圖弄清楚這是爲什麼不工作我想:

for d in main.children: 
    if d.name == 'p': 
     print(d.nextSibling.name) 
    else: 
     print("fail") 

這樣做的輸出是一樣的東西:

fail 
None 
fail 
None 
fail 
None 
fail 
fail 
fail 
fail 
fail 
None 
fail 

等等

這是爲什麼不喜歡工作我認爲會呢?如果下一個標籤是<ol>,我怎樣才能從<p>元素只得到

回答

2

您只需要p標籤,其標籤爲ol之前的標籤。首先找到ol標籤,然後找到之前的Tag對象,即p標籤。現在您的代碼不起作用,因爲Tag元素是NavigableString類型對象之間有一個換行符。並且d.nextSibling也會產生這些換行符。所以你必須在這裏檢查對象的類型。

from bs4 import Tag 
# create soup 
# find the ols 
ols = soup.find_all('ol') 
for ol in ols: 
    prev = ol.previous_sibling 
    while(not isinstance(prev, Tag)): 
     prev = prev.previous_sibling 
    print(prev.text) 

這會給你你想要的文字。

Text I WANT 
Text I WANT 
+0

啊哈!謝謝。我發現我可以通過使用'if d.nextSibling.nextSibling.name =='ol'來準確找到它:'但我無法弄清楚爲什麼我必須去兩個兄弟姐妹才能獲得下一個兄弟姐妹。 – DjH

+0

是的,在這種情況下,這也會起作用。但是,如果只遍歷兩個兄弟姐妹是不夠的?因爲'html'可能是不可預知的。我認爲在這裏檢查對象類型是個好主意。 –

+1

我絕對同意。謝謝 – DjH

2

您可以使用CSS選擇,即ul ~ p找到所有由UL之前的p標籤:

html = """<div id="mainContent"> 

    <p>Some Text I don't want</p> 
    <p>Some Text I don't want</p> 
    <p>Some Text I don't want</p> 
    <span> More text I don't want</span> 
    <ul>...unordered-list items..</ul> 

    <p>Text I WANT</p> 
    <ol>...ordered-list items..</ol> 

    <p>Text I WANT</p> 
    <ol>...ordered-list items..</ol> 

</div>""" 

from bs4 import BeautifulSoup 

soup = BeautifulSoup(html) 


print([p.text for p in soup.select("#mainContent ul ~ p")]) 

,這將給你:

['Text I WANT', 'Text I WANT'] 

或找到ol的,然後尋找以前的兄弟姐妹電話號碼:

print([ol.find_previous_sibling("p").text for ol in soup.select("#mainContent ol")]) 

這也會給你:

['Text I WANT', 'Text I WANT'] 
+0

'print([p.text for p在soup.select(「#mainContent ul〜p」)])'工作,+1爲單行。你在'soup.select(「#mainContent ol」)]給'print'([ol.find_previous_sibling(「p」)。) ''給出'TypeError:'NavigableString'對象不可調用' – DjH

+0

@ DjH,你確定你使用了'find_previous_sibling(「p」)',那個錯誤看起來更像'previous_sibling(「p」)'。 –

+1

哦,廢話吧。 > – DjH