2016-01-01 15 views
6

Input HTML:Trattare con i due punti in BeautifulSoup selettori CSS

<div style="display: flex"> 
    <div class="half" style="font-size: 0.8em;width: 33%;"> apple </div> 
    <div class="half" style="font-size: 0.8em;text-align: center;width: 28%;"> peach </div> 
    <div class="half" style="font-size: 0.8em;text-align: right;width: 33%;" title="nofruit"> cucumber </div> 
</div> 

L'output desiderato: tutti gli elementi div esattamente sotto <div style="display: flex">.

sto cercando di individuare il genitore div con un CSS selector:

div[style="display: flex"] 

Questo genera un errore:

>>> soup.select('div[style="display: flex"]') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/Users/user/.virtualenvs/so/lib/python2.7/site-packages/bs4/element.py", line 1400, in select 
    'Only the following pseudo-classes are implemented: nth-of-type.') 
NotImplementedError: Only the following pseudo-classes are implemented: nth-of-type. 

Sembra BeautifulSoup cerca di interpretare i due punti come pseudo-classe sintassi.

Ho cercato di seguire i consigli suggeriti a Handling a colon in an element ID in a CSS selector, ma getta ancora errori:

>>> soup.select('div[style="display\: flex"]') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/Users/user/.virtualenvs/so/lib/python2.7/site-packages/bs4/element.py", line 1400, in select 
    'Only the following pseudo-classes are implemented: nth-of-type.') 
NotImplementedError: Only the following pseudo-classes are implemented: nth-of-type. 
>>> soup.select('div[style="display\3A flex"]') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/Users/user/.virtualenvs/so/lib/python2.7/site-packages/bs4/element.py", line 1426, in select 
    'Unsupported or invalid CSS selector: "%s"' % token) 
ValueError: Unsupported or invalid CSS selector: "div[style="displayA" 

la domanda:

Qual è il modo corretto di utilizzare/ESCAPE due punti in valori di attributo nei selettori CSS BeautifulSoup?


Nota che posso aggirare con un fiammifero di attributi parziali:

soup.select("div[style$=flex]") 

Oppure, con un find_all():

soup.find_all("div", style="display: flex") 

Si noti inoltre che ho capito che l'uso style per individuare gli elementi è ben lungi dall'essere una buona tecnica di localizzazione, ma la domanda stessa è pensata per essere generica e l'HTML fornito è solo un esempio.

+0

Suppongo che abbiate provato anche due backslash? 'soup.select ('div [style =" display \\: flex "]')' –

+0

@JoshCrozier felice anno nuovo, sì, e diverse combinazioni con stringhe raw e stringhe regolari. Grazie. Penso ancora che mi manchi solo di poco. – alecxe

+2

... wat. Parla di rotto. – BoltClock

risposta

2

Aggiornamento: il problema è stato risolto in BeautifulSoup 4.5.0, aggiornandoli se necessario:

pip install --upgrade beautifulsoup4 

Vecchia risposta:

Creato un problema al BeautifulSoup issue tracker:

aggiornerà la risposta in caso di eventuali aggiornamenti nel problema del launchpad.

1

Non sicuro che questo costituisca una risposta esattamente, poiché è decisamente rotta. Tuttavia, stranamente l'errore non viene attivato dallo stesso :, ma dallo : seguito da uno spazio. L'errore suggerisce che sta tentando di utilizzare qualsiasi cosa sia dopo lo spazio come un selettore CSS.

Ad esempio, modificando il codice HTML di abbandonare lo spazio rende il blocco di nuovo selezionabile:

>>> from bs4 import BeautifulSoup 
>>> html = """ 
... <div style="display:flex"> 
...  <div class="half" style="font-size: 0.8em;width: 33%;"> apple </div> 
...  <div class="half" style="font-size: 0.8em;text-align: center;width: 28%;"> peach </div> 
...  <div class="half" style="font-size: 0.8em;text-align: right;width: 33%;" title="nofruit"> cucumber </div> 
... </div> 
... """ 

>>> soup = BeautifulSoup(html) 
>>> soup.select('div[style="display: flex"]') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/local/lib/python3.4/dist-packages/bs4/element.py", line 1313, in select 
    'Unsupported or invalid CSS selector: "%s"' % token) 
ValueError: Unsupported or invalid CSS selector: "flex"]" 

>>> soup.select('div[style="display:flex"]') 
[<div style="display:flex"> 
<div class="half" style="font-size: 0.8em;width: 33%;"> apple </div> 
<div class="half" style="font-size: 0.8em;text-align: center;width: 28%;"> peach </div> 
<div class="half" style="font-size: 0.8em;text-align: right;width: 33%;" title="nofruit"> cucumber </div> 
</div>] 

Purtroppo, con lo spazio è il solito stile quindi questo probabilmente non porterà molto lontano a tutti!

+0

Osservazione interessante! Grazie. – alecxe