2012-02-12 63 views
4

我的讀取與BeautifulSoup一些HTML錶行這段代碼:選擇特定<tr>標籤與BeautifulSoup

from bs4 import BeautifulSoup 
import urllib2 
import re 

page = urllib2.urlopen('www.something.bla') 
soup = BeautifulSoup(page) 
rows = soup.findAll('tr', attrs={'class': re.compile('class1.*')}) 

這是我得到的結果:

<tr class="class1 class2 class3">...</tr> 
<tr class="class1 class2 class3">...</tr> 
<tr class="class1 class5">...</tr> 
<tr class="class1_a class5_a">...</tr> 
<tr class="class1 class5">...</tr> 
<tr class="class1_a class5_a">...</tr> 
<!-- etc. --> 

然而,我'想排除(或不首先選擇它們)那些具有class1 class2 class3作爲屬性的行。

我該怎麼做?
感謝您的幫助!

+0

那麼'class1_a'可以抓取而不是'class1'嗎? – serk 2012-02-12 23:24:24

+0

我應該抓住所有以'class1 *'開頭但沒有'class2 class3'的人...... – errata 2012-02-12 23:25:58

回答

8

也許沒有正則表達式更容易。這適用於BeautifulSoup 3:

from BeautifulSoup import BeautifulSoup 

page = """ 
<tr class="class1 class2 class3">1</tr> 
<tr class="class1 class2 class3">2</tr> 
<tr class="class1 class5">3</tr> 
<tr class="class1_a class5_a">4</tr> 
<tr class="class1 class5">5</tr> 
<tr class="class1_a class5_a">6</tr> 
<tr>7</tr>""" 

def cond(x): 
    if x: 
     return x.startswith("class1") and not "class2 class3" in x 
    else: 
     return False 

soup = BeautifulSoup(page) 
rows = soup.findAll('tr', {'class': cond}) 

for row in rows: 
    print row 

=>

<tr class="class1 class5">3</tr> 
<tr class="class1_a class5_a">4</tr> 
<tr class="class1 class5">5</tr> 
<tr class="class1_a class5_a">6</tr> 

隨着BeautifulSoup 4,我能使其工作如下:

import re 
from bs4 import BeautifulSoup 

page = """ 
<tr class="class1 class2 class3">1</tr> 
<tr class="class1 class2 class3">2</tr> 
<tr class="class1 class5">3</tr> 
<tr class="class1_a class5_a">4</tr> 
<tr class="class1 class5">5</tr> 
<tr class="class1_a class5_a">6</tr> 
<tr>7</tr>""" 

soup = BeautifulSoup(page) 
rows = soup.find_all('tr', {'class': re.compile('class1.*')}) 

for row in rows: 
    cls = row.attrs.get("class") 
    if not ("class2" in cls or "class3" in cls): 
     print row 

=>

<tr class="class1 class5">3</tr> 
<tr class="class1_a class5_a">4</tr> 
<tr class="class1 class5">5</tr> 
<tr class="class1_a class5_a">6</tr> 

在BS4中,像class這樣的多值屬性具有字符串列表作爲它們的值,而不是字符串。見http://www.crummy.com/software/BeautifulSoup/bs4/doc/#id12

+0

啊,是的,lambda :)看起來很優雅:)但是,我得到了一個錯誤:'' AttributeError:'NoneType'對象沒有屬性'startswith'' ...我從來沒有使用過lamba函數,並試圖'修復'這個錯誤,但實際上沒有得到任何答案: -/ – errata 2012-02-14 10:16:48

+1

它沒有成爲拉姆達。當代碼沒有'class'屬性和x ='None'時,代碼更新以處理案例(例如,在我的示例中爲''7)。 – mzjn 2012-02-14 16:29:04

+0

感謝您對此的幫助,但無論您嘗試使用哪一個示例,我在控制檯中始終獲得與您的不同的回報 - 除第7行外,我獲得了所有行。:/ – errata 2012-05-01 01:18:56