python - tutorial - using beautifulsoup
Manejo de dos puntos en los selectores CSS de BeautifulSoup (2)
HTML de entrada:
<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>
El resultado deseado: todos los elementos div
exactamente debajo de <div style="display: flex">
.
Estoy tratando de localizar el div
principal con un selector de CSS :
div[style="display: flex"]
Esto arroja un error:
>>> 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.
Parece que BeautifulSoup
intenta interpretar los dos puntos como una sintaxis de pseudoclase.
Intenté seguir los consejos sugeridos en Manejo de dos puntos en un ID de elemento en un selector de CSS , pero aún arroja errores:
>>> 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 pregunta:
¿Cuál es la forma correcta de usar / escapar de dos puntos en los valores de los atributos en los selectores CSS de BeautifulSoup
?
Tenga en cuenta que puedo solucionarlo con una coincidencia de atributo parcial:
soup.select("div[style$=flex]")
O bien, con un find_all()
:
soup.find_all("div", style="display: flex")
También tenga en cuenta que entiendo que el uso de style
para localizar elementos está lejos de ser una buena técnica de localización, pero la pregunta en sí misma debe ser genérica y el código HTML provisto es solo un ejemplo.
No estoy seguro de que esto constituya una respuesta exacta, ya que definitivamente se rompe. Sin embargo, curiosamente el error no se desencadena por :
sí mismo, sino por :
seguido de un espacio. El error sugiere que está intentando usar lo que sea que esté después del espacio como selector de CSS.
Por ejemplo, al editar el HTML para eliminar el espacio, el bloque se puede seleccionar nuevamente:
>>> 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>]
Desafortunadamente, con el espacio es el estilo habitual, así que esto probablemente no te llevará muy lejos.
Actualización: el problema ahora está solucionado en BeautifulSoup 4.5.0, actualice si es necesario:
pip install --upgrade beautifulsoup4
Respuesta anterior:
Se creó un problema en el rastreador de problemas de BeautifulSoup
:
Actualizará la respuesta en caso de que haya alguna actualización en el problema del launchpad.