2016-08-23 17 views
5

mam te elementy w HTML chcę analizować:wybierania elementów tylko wtedy, gdy mają dwie klasy i mają te same pierwsza

<td class="line"> GARBAGE </td> 
<td class="line text"> I WANT THAT </td> 
<td class="line heading"> I WANT THAT </td> 
<td class="line"> GARBAGE </td> 

Jak mogę zrobić selektor CSS, który wybrać elementy z linii klasy atrybutów i klasy coś innego (może być nagłówek, tekst lub cokolwiek innego) ALE nie atrybut linii klasy tylko?

Próbowałem:

td[class=line.*] 
td.line.* 
td[class^=line.] 

EDIT

używam Python i BeautifulSoup:

url = 'http://www.somewebsite' 
res = requests.get(url) 
res.raise_for_status() 
DicoSoup = bs4.BeautifulSoup(res.text, "lxml") 
elems = DicoSoup.select('body div#someid tr td.line') 

szukam do modyfikowania ostatni element, a mianowicie td.line do czegoś td.line.whateverotherclass (ale nie td.line, w przeciwnym razie mój selektor wystarczyłby)

Odpowiedz

3

Co @BoltClock suggested jest ogólnie poprawny sposób podejścia do problemu z selektorów CSS. Jedynym problemem jest to, że BeautifulSoup supports a limited number of CSS selectors. Na przykład: not() selector is :not(.supported) at the moment.

można obejść go z „starts-with” wybieraka, aby sprawdzić, czy klasa zaczyna line następnie przestrzeni (jest to dość kruche, ale działają na dane próbki):

for td in soup.select("td[class^='line ']"): 
    print(td.get_text(strip=True)) 

Lub można rozwiązać go za pomocą find_all() i posiadające searching function sprawdzanie atrybut class mieć line i jakaś inna klasa:

from bs4 import BeautifulSoup 

data = """ 
<table> 
    <tr> 
     <td class="line"> GARBAGE </td> 
     <td class="line text"> I WANT THAT </td> 
     <td class="line heading"> I WANT THAT </td> 
     <td class="line"> GARBAGE </td> 
    </tr> 
</table>""" 
soup = BeautifulSoup(data, 'html.parser') 

for td in soup.find_all(lambda tag: tag and tag.name == "td" and 
            "class" in tag.attrs and "line" in tag["class"] and 
            len(tag["class"]) > 1): 
    print(td.get_text(strip=True)) 

Drukuje:

I WANT THAT 
I WANT THAT 
+0

Świetnie! To dobre obejście. Dziękuję Ci! –

+0

Jaką funkcję lambda powinienem napisać, aby uzyskać znaczniki podrzędne w taki sam sposób, jak poniższy wiersz kodu: DicoSoup.select ("body div # somed tr td") –

+0

@MthClv mógłbyś, na przykład, zlokalizować rodzica 'div' najpierw , np .: 'div = soup.select_one (" body div # somed ")', a następnie użyj zmiennej 'div' zamiast' soup' podczas wyszukiwania elementów 'td' za pomocą funkcji wyszukiwania? Coś jak wyszukiwanie kontekstowe. – alecxe

0

Możesz łączyć klasy CSS dla selektora klasy.

.line { 
 
    color: green; 
 
} 
 
.line.text { 
 
    color: red; 
 
} 
 
.line.heading { 
 
    color: blue; 
 
}
<p class="line">GARBAGE</p> 
 
<p class="line text">I WANT THAT</p> 
 
<p class="line heading">I WANT THAT</p> 
 
<p class="line">GARBAGE</p>

+0

Myślę, że chodziło o to, żeby mieć * jeden * selektor ... nie ten jeden. Nie jestem pewien, czy to możliwe, ale –

+0

Popraw Paulie, szukam sposobu na owijanie go w jeden selektor; coś takiego jak td.line.whateverOtherClass –

+0

Przykro mi, powinienem był wspomnieć: chcę to zrobić w Pythonie używając biblioteki BeautifulSoup, Myślałem, że właśnie brakowało mi jakiejś składni dotyczącej selektorów CSS i że to by pasowało do wszystkich programy –

Powiązane problemy