scraping pagina leer espaƱol python regex html-parsing beautifulsoup lxml

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.