python - pagina - Buscar por texto y reemplazar en HTML BeautifulSoup
leer pagina web python (1)
Estoy tratando de marcar un archivo HTML (literalmente envolviendo cadenas en etiquetas "mark") usando Python y BeautifulSoup. El problema es básicamente el siguiente ...
Digamos que tengo mi documento html original:
test = "<h1>oh hey</h1><div>here is some <b>SILLY</b> text</div>"
Quiero hacer una búsqueda insensible a mayúsculas y minúsculas en este documento (ignorando HTML) y envolverlo en etiquetas de "marca". Así que digamos que quiero encontrar "aquí hay un texto tonto" en el html (ignorando las etiquetas en negrita). Me gustaría tomar el html coincidente y envolverlo en etiquetas de "marca".
Por ejemplo, si quiero buscar "aquí hay un texto tonto" en la prueba , el resultado deseado es:
"<h1>oh hey</h1><div><mark>here is some <b>SILLY</b> text</mark></div>"
¿Algunas ideas? Si es más apropiado usar expresiones lxml o regulares, también estoy abierto a esas soluciones.
>>> soup = bs4.BeautifulSoup(test)
>>> matches = soup.find_all(lambda x: x.text.lower() == ''here is some silly text''):
>>> for match in matches:
... match.wrap(soup.new_tag(''mark''))
>>> soup
<html><body><h1>oh hey</h1><mark><div>here is some <b>SILLY</b> text</div></mark></body></html>
La razón por la que tuve que pasar una función como el name
para find_all
que compara x.text.lower()
, en lugar de simplemente usar el argumento de text
con una función que compara x.lower()
, es que este último no encontrará el contenido en algunos casos que aparentemente quieres.
La función de wrap
puede no funcionar de esta manera en algunos casos. Si no lo hace, tendrá que enumerate(matches)
y establecer matches[i] = match.wrap(soup.new_tag(''mark''))
. (No puede usar replace_with
para reemplazar una etiqueta con una nueva etiqueta que se replace_with
a sí misma).
También tenga en cuenta que si su caso de uso previsto permite que alguna cadena que no sea ASCII coincida ''here is some silly text''
(o si desea ampliar el código para manejar cadenas de búsqueda que no sean ASCII), el código anterior que utiliza lower()
puede ser incorrecto Es posible que desee llamar a str.casefold()
y / o locale.strxfrm(s)
y / o usar locale.strcoll(s, t)
lugar de usar ==
, pero deberá comprender lo que desea y cómo hacerlo. haz que elija la respuesta correcta.