Wildcards en Xpath
Clase 12 de 21 • Curso de Fundamentos de Web Scraping con Python y Xpath
Contenido del curso
Carolina Acosta Muñoz
Moisés Manuel Morín Hevia
César Daniel Carrasco Gutiérrez
Alejandro Giraldo Londoño
Alan Vazquez
Kenny Emmanuel Lajara Aquino
Francisco Garcia [C6]
Luis Rogelio Reyes Hernandez
Miguel Ángel Carrillo Hernández
Diego Jurado
Saúl Alejandro Tapia Loya
Moisés Manuel Morín Hevia
Facundo Soto
Fernando Campos
Facundo Soto
Carlos Javier Guevara Contreras
Moisés Manuel Morín Hevia
Santiago Martinez Pineda
Moisés Manuel Morín Hevia
Usuario anónimo
Usuario anónimo
Andrés David Lizarazo Becerra
Moisés Manuel Morín Hevia
Dario Vergara
Alex Camacho
Julio César Zaravia Paredes
Itzel Villeda Mejía
Juan Carlos Ortiz Romero
Vikas Sharma
Flavio Abat Carrola Reta
Antonio Demarco Bonino
Usuario anónimo
Herman Castillo R
Usuario anónimo
Wilcards = comodines
Ejemplos
$x('/') <- Trae todo el documento porque representa la raíz de nuestro el html
$x('/*') <- * después de / pide que traiga todos los nodos que están debajo de / (* es el primer wildcard)
$x('/html/*') <- Trae todos los nodos que están inmediatamente después de html
$x('//*') <- // es la expresión para saltar todos los niveles y con el * en todas las direcciones. Trae todos los nodos y todos los atributos de estos nodos.
$x('//span[@class="text]/@*') <- Trae todos los span, que tengan como clase "text", con @* trae todos los atributos. Dicho de otra forma, trae todos los atributos de todos los nodos de tipo span de clase "text".
$x('/html/body//div/@*') <- Todos los atributos (usando @*) de todos los div (usando //div) que están después de body
$x('//span[@class="text" and @itemprop="text"]/node()') <- Trae todos los spam que sean de clase "text" que tengan un atributo @itemprop "text" y de ahí (usando node()) traer todo lo que esté dentro de los spam que cumplen las condiciones
node() a diferencia de * trae no solamente los nodos, sino también todo el contenido
Justo el resumen exacto.
Excelente resumen, muchas gracias :)
RESUMEN:Wildcards en Xpath
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
Son comodines que usamos cuando no tenemos claro lo que queremos extraer.
Ejemplo:
x('//span[@class="text" and @itemprop="text"]/node()').map(x => x.wholeText) # Devuelve (10) ["“The world as we have created it is a process of o…cannot be changed without changing our thinking.”", "“It is our choices, Harry, that show what we truly are, far more than our abilities.”", "“There are only two ways to live your life. One is… The other is as though everything is a miracle.”", "“The person, be it gentleman or lady, who has not …ure in a good novel, must be intolerably stupid.”", "“Imperfection is beauty, madness is genius and it'…be absolutely ridiculous than absolutely boring.”", "“Try not to become a man of success. Rather become a man of value.”", "“It is better to be hated for what you are than to be loved for what you are not.”", "“I have not failed. I've just found 10,000 ways that won't work.”", "“A woman is like a tea bag; you never know how strong it is until it's in hot water.”", "“A day without sunshine is like, you know, night.”"]
Aqui si se queda muy corto CSS Selector ya que solo tiene el wildcard del *
# Selecciona todos los elementos hijos del html $$('html > *') # Selecciona todos los documentos $$('*')
De los que me voy dado cuenta es que por si solo XPATH es mucho mas poderoso, pero con CSS ganas una sintanxis mucho mas corta y limpia, pero tienes que usar mas heramientas dadas por el lenguaje de programacion. Ya es cuestion de costumbres, pero aun asi le digo viendo mas ventajas a usar Selectores de CSS. O en su defecto puedes usar XPATH para estos tipos de casos particulares
Llevo media vida usando selectores CSS y solo puedo decir: Estoy enamorado de XPath.
gracias
$x('/*') // trae todos los nodos que estan dentro del documento $x('/html/*') // trae todos los nodos que estan inmediatamente despues del html $x('//*') // trae todos los elementos que se encuentran en el documento $x('//span[@class="text"]/@*') // trae todos los atributos de todos los span que tengan la clase texto $x('/html/body//div/@*') // trae todos los atributos de todos los elementos div que estan dentro del body $x('//span[@class="text" and @itemprop="text"]/*') // en este caso no trae nada ya que adentro solo hay texto plano no hay nodos $x('//span[@class="text" and @itemprop="text"]/node()') // en todos los span que tengan como atributo class="text" and itemprop="text" trae todo el contenido esto es distinto a usar *, ya que aqui trae el contenido y texto plano de estos elementos a pesar que no estan dentro de un elemento html
Esta genial la tabla que hiciste. El operador node() es muy poderoso.
Que buen resumen!
Xpath realmente es a html lo que expresiones regulares son a texto, ya quiero verlo en acción en un proyecto.
También yo, muychas cosas se pueden hacer.
Porque la mayoría de los códigos no me funcionan?, o sea, algo tan básico como
$x('//span[@class="text"]/@*')
me arroja un array vacío
Hola 👋🏼
¿Estás trabajando en el mismo sitio web que el profe usa de ejemplo? tal vez la estructura del html es diferente, pero al menos un spam debería de haber. Es raro, lo que podrías hacer es explorar la estructura poco a poco, primero buscar el body y de ahí continuar para probar que todo funciona bien.🙂
Sip, me di cuenta que era otra url JAJAJA, gracias por responder
Super Productiva esta clase !!!
Seeee, tantas cosas que se pueden hacer.
Es también muy extensa pero super útil.
Predicates Predicates are used to find a specific node or a node that contains a specific value.
Predicates are always embedded in square brackets.
In the table below we have listed some path expressions with predicates and the result of the expressions:
Path Expression Result /bookstore/book[1] Selects the first book element that is the child of the bookstore element. Note: In IE 5,6,7,8,9 first node is[0], but according to W3C, it is [1]. To solve this problem in IE, set the SelectionLanguage to XPath:
In JavaScript: xml.setProperty("SelectionLanguage","XPath"); /bookstore/book[last()] Selects the last book element that is the child of the bookstore element /bookstore/book[last()-1] Selects the last but one book element that is the child of the bookstore element /bookstore/book[position()<3] Selects the first two book elements that are children of the bookstore element //title[@lang] Selects all the title elements that have an attribute named lang //title[@lang='en'] Selects all the title elements that have a "lang" attribute with a value of "en" /bookstore/book[price>35.00] Selects all the book elements of the bookstore element that have a price element with a value greater than 35.00 /bookstore/book[price>35.00]/title Selects all the title elements of the book elements of the bookstore element that have a price element with a value greater than 35.00
XPath uses path expressions to select nodes or node-sets in an XML document. The node is selected by following a path or steps.
The XML Example Document We will use the following XML document in the examples below.
<?xml version="1.0" encoding="UTF-8"?> <bookstore> <book> <title lang="en">Harry Potter</title> <price>29.99</price> </book> <book> <title lang="en">Learning XML</title> <price>39.95</price> </book> </bookstore>/* : Con asterisco le estoy diciendo que me traiga todos los nodos inmediatamente después de la expresión. //* : En este caso le estoy diciendo que estoy saltando en todos los niveles en todas las direcciones. @*: Traer todos los atributos de todos los nodos /node() : Nos trae además de nodos el contenido, difiere de asterisco
Buen resumen!
¿Por qué motivo me figura error?  después del argumento. Checa bien el código que estas escribiendo y no dejes ninguna llave sin cerrar.
Hola Ruben, de tu pregunta ya han pasado algunos meses y seguramente ya la has solucionado. Igual lo comento por si alguien se cruza con lo mismo.
El motivo del error es simple, si bien el texto del error indica que falta un ')', esto no es del todo cierto ya que si vemos la expresión, esta cuenta con todos su parentesis de apertura y cierre.
El problema es debido a que estás utilizando comillas dobles tanto para agrupar la expresión como para marcar el texto 'text' dentro de tu selección de clase.
En resumen, no debes (y no puedes) usar comillas dobles dentro de comillas dobles (lo mismo para las comillas simples).
Tu expresión está escrita así: x("//span[@class="text"]/@*")
Debería estar escrita así: x("//span[@class='text']/@*")
Saludos!
Les comparto un cheatsheet que encontre de Xpath: https://devhints.io/xpath
🤖🤖🤖Wildcards🤖🤖🤖 Son comodines que usamos cuando no tenemos claro lo que queremos extraer. /* : Con asterisco le estoy diciendo que me traiga todos los nodos inmediatamente después de la expresión. //* : En este caso le estoy diciendo que estoy saltando en todos los niveles en todas las direcciones. @*: Traer todos los atributos de todos los nodos /node() : Nos trae además de nodos el contenido, difiere de asterisco.
Como recomendación para futuros videos, procuren que el video tenga margen inferior suficiente para evitar que los controles del reproductor tapen la explicación.
Me gusta mucho como enseña Facundo, excelente, pero creo que para optimizar estaría bien limpiar la consola después de uno o dos comandos para tener mayor visibilidad como espectador.
Saludos!
Encantado de poder aprender más y más de esta herramienta.
Selecting Nodes XPath uses path expressions to select nodes in an XML document. The node is selected by following a path or steps. The most useful path expressions are listed below:
Expression Description nodename Selects all nodes with the name "nodename" / Selects from the root node // Selects nodes in the document from the current node that match the selection no matter where they are . Selects the current node .. Selects the parent of the current node @ Selects attributes
En caso que se quiera ser más especifico con la búsqueda se pueden usar predicados $x('//span[@class="text" and @itemprop="text"]/node()')[0]
Selecting Unknown Nodes XPath wildcards can be used to select unknown XML nodes.
Wildcard Description