Выбор конкретных <tr>тегов с BeautifulSoup - PullRequest
5 голосов
/ 13 февраля 2012

Я получаю некоторые строки таблицы html с 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 в качестве атрибута.

Как я могу это сделать?
Спасибо за помощь!

1 Ответ

10 голосов
/ 13 февраля 2012

Возможно, это проще без регулярных выражений.Это работает с 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...