2016-08-23 3 views
5

ich habe diese Elemente im HTML teilen Ich möchte analysieren:Auswählen von Elementen nur dann, wenn zwei Klassen haben und die gleiche erste

<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> 

Wie kann ich einen CSS-Selektor machen, die Elemente mit Attributen Klasse Linie wählen und etwas anderes klassifizieren (könnte Überschrift, Text oder irgendetwas anderes sein), aber nicht nur Klassenzeile?

Ich habe versucht:

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

EDIT

ich Python und BeautifulSoup bin mit:

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') 

Ich suche in das letzte Stück zu modifizieren, nämlich td.line zu so etwas wie td.line.whateverotherclass (aber nicht td.line alleine sonst würde mein Selektor schon ausreichen)

Antwort

3

Was @BoltClock suggested ist in der Regel ein richtiger Weg, um das Problem mit CSS-Selektoren zu nähern. Das einzige Problem ist, dass BeautifulSoup supports a limited number of CSS selectors. Zum Beispiel not() selector is :not(.supported) at the moment.

Sie können es mit einer „starts-with“ Selektor Abhilfe Wenn eine Klasse mit line gefolgt von einem Leerzeichen beginnt zu überprüfen (es ziemlich zerbrechlich ist, sondern arbeitet auf Ihren Beispieldaten):

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

Oder Sie können lösen sie die find_all() verwenden und ein searching function das class Attribut Überprüfung mit line und einigen anderen Klassen zu haben:

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)) 

Drucke:

I WANT THAT 
I WANT THAT 
+0

Großartig! Das ist ein guter Workaround. Vielen Dank! –

+0

Welche Lambda-Funktion sollte ich schreiben, um untergeordnete Tags auf die gleiche Weise wie die folgende Codezeile zu erhalten: DicoSoup.select ('body div # somed tr td') –

+0

@MthClv könnten Sie sagen, zuerst das Elternteil 'div' lokalisieren , zB: 'div = supp.select_one (" body div # somed ")' und dann die 'div'-Variable anstelle von' suppen' verwenden, wenn man mit der Suchfunktion nach 'td'-Elementen sucht? So ähnlich wie eine kontextspezifische Suche. – alecxe

0

Sie können CSS-Klassen für einen Klassenselektor verketten.

.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

Ich denke, der Punkt war, * one * Selektor zu haben ... nicht mehrere. Ich bin mir nicht sicher, ob es möglich ist, aber –

+0

Korrekt Paulie, ich bin auf der Suche nach einer Möglichkeit, es in einem Selektor zu wickeln; etwas wie td.line.whateverOtherClass –

+0

Es tut mir leid, ich hätte erwähnen sollen: Ich möchte es in Python mit der Bibliothek BeautifulSoup tun, ich dachte, ich würde nur ein Stück Syntax in Bezug auf CSS-Selektoren fehlt und dass es für alle anwendbar wäre Programme –

Verwandte Themen