python - with - Trattare con due punti nei selettori CSS BeautifulSoup




web scraping in python 3 (2)

Non sono sicuro che ciò costituisca una risposta esatta, in quanto è decisamente infranta. Tuttavia, stranamente l'errore non è innescato da : se stesso, ma dal : seguito da uno spazio. L'errore suggerisce che sta tentando di utilizzare qualsiasi cosa sia dopo lo spazio come un selettore CSS.

Ad esempio, la modifica dell'HTML per eliminare lo spazio rende nuovamente il blocco 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>]

Sfortunatamente, con lo spazio è il solito stile quindi questo probabilmente non ti porterà molto lontano!

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

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

Sto cercando di individuare il div genitore con un selettore CSS :

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 che BeautifulSoup cerchi di interpretare i due punti come una sintassi pseudo-classe.

Ho provato a seguire i consigli suggeriti a Gestire i due punti in un ID elemento in un selettore CSS , ma genera 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 usare / sfuggire ai due punti nei valori degli attributi nei selettori CSS di BeautifulSoup ?

Nota che posso risolvere il problema con una corrispondenza di attributo parziale:

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

Oppure, con un find_all() :

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

Nota anche che capisco che usare lo style per localizzare gli elementi è ben lungi dall'essere una buona tecnica di localizzazione, ma la domanda stessa deve essere generica e l'HTML fornito è solo un esempio.


Aggiornamento: il problema è ora risolto in BeautifulSoup 4.5.0, aggiornamento se necessario:

pip install --upgrade beautifulsoup4

Vecchia risposta:

Creato un problema sul tracker dei problemi di BeautifulSoup :

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





html-parsing