No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Operadores en Xpath

11/21
Recursos

Aportes 22

Preguntas 2

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

o inicia sesi贸n.

RESUMEN:Operadores en Xpath

鈻犫枲鈻犫枲鈻犫枲鈻犫枲鈻犫枲鈻犫枲鈻犫枲鈻犫枲鈻犫枲鈻犫枲鈻犫枲鈻犫枲鈻犫枲鈻犫枲鈻犫枲鈻犫枲鈻犫枲鈻犫枲鈻犫枲鈻犫枲鈻犫枲

Hay una forma de filtrar m谩s avanzada y es con operadores l贸gicos.

Operadores l贸gicos en Xpath :
Cabe notar que los operadores se est谩n usando dentro del predicado.

  • !=
  • <>
  • and
  • or
  • not

Ejemplo:

#Usando el operador != diferente, le estoy diciendo que me
traiga todos los nodos span que tienen clase diferente a Texto.

$x('//span[@class!="text"]')

# Usando operador not me devuelve todos los nodos que no tienen
el atributo class.

$x('//span[not(@class)]'

XPATH CSS Selector
!= :not(attr = value)
position()
attr1 AND attr2 [attr1][attr2]
selector[attr1 OR attr2] selector1, selector2
NOT() :not(attr or selector)
# span con clase diferente de text
$$('span[class]:not(.text)')

# span de clase text y atributo itemprop
$$('span.text[itemprop]')

# span con clase text o tag-item
$$('span.text, span.tag-item')

# span que no tienen atributo de clase
$$('span:not([class])')

*Css no tiene un forma nativa de usar el position de xpath, pero se pueden herramientas del lenguaje de programacion, como los slices de python

Hay un div en el html el cual tiene ambas clases (row y header-box), pero no me funciona de esta forma, no deberia servir?

$x('//div[@class="row" and @class="header-box"]')

Me funciona si lo hago de esta forma solo si estan en este orden inclusive

$x('//div[@class="row header-box"]')```
$x('//span[@class!="text"]') // todos los span que tenga una clase distinta de "text"

$x('/html/body/div/div[position()=1]') // trae los elementos en la posicion 1

$x('/html/body/div/div[position()>1]') // trae todos los elementos que se encuentran despues de la posicion 1

$x('//span[@class="text" and @class="tag-item"]') // trae los elementos que tengan como clase a "text" Y a "tag-item"

$x('//span[@class="text" or @class="tag-item"]') // trae los elementos que tengan como clase a "text" O a "tag-item"

$x('//span[not(@class)]') // trae todos los span que NO tengan una clase

Quer铆a practicar un poco. Mi objetivo fue obtener el primer tag de cada quote. Les comparto mi c贸digo:

$x('/html/body/div/div[@class="row"]/div[1]/div[@class="quote"]/div[@class="tags"]/a[@class="tag"][1]/text()').map(item => item.wholeText)

驴Alguien sabe por qu茅 en este caso las posiciones arrancan en 1 y no en 0?, siendo que est谩 escribiendo en JS.

$x('//div[@class="quote"][1]/span[@class="text"]/text()').map(x => x.wholeText)
# Traer la primera Quote de toda la p谩gina

//div[@class="tags"]/a[position()<=3]/text()
# Top 3 de Tags por Quotes

Lista de operadores y su descripci贸n

Interesante

Para llamar cierta cantidad de elementos, se usa position()
$x(鈥//div[@class=鈥渜uote鈥 or position()=2]鈥)
En este ejemplo, llamamos a los divs que tengan la class quote o que est茅n en la posici贸n dos (la cual es relativa a su nodo padre.)

Siempre me he preguntado por qu茅 una plataforma como Platzi no puede hasta la fecha darse cuenta que la barra siempre presente de 鈥榩lay鈥, 鈥榩ause鈥, etc. disminuye la calidad de experiencia en los usuarios. Es un problema que lo he visto y vivido desde que entr茅 a la plataforma y que muchas otras personas tambi茅n lo han padecido; sin embargo, a la fecha el inconveniente persiste.

Operadores en XPath

  • ! = : indica que debe ser distinto
$x('//span[@class!="text"]')
--> (11)聽[span.tag-item, span.tag-item, span.tag-item, span.tag-item, span.tag-item, span.tag-item, span.tag-item, span.tag-item, span.tag-item, span.tag-item, span.sh-red]
# 11 nodos span que tiene clase de tipo tag-item y no de tipo texto
  • < : permite obtener las etiquetas segun sea mayor o menor a un determinado valor

$x('/html/body/div/div[position()>1]')
--> [div.row]
#obtiene las etiquetas que estan despues de la primera.
  • and : indica que trae las etiquetas que cumplen dos condiciones a la vez
$x('//span[@class="text" and @class="tag-item"]')
#obtiene los nodos con clases de tipo text y tag-item
  • or : trae los nodos que cumplan con alguna de dos condiciones
$x('//span[@class="text" or @class="tag-item"]')
--> (20)聽[span.text, span.text, span.text, span.text, span.text, span.text, span.text, span.text, span.text, span.text, span.tag-item, span.tag-item, span.tag-item, span.tag-item, span.tag-item, span.tag-item, span.tag-item, span.tag-item, span.tag-item, span.tag-item]
#obtiene los nodos que tengan clases de tipo text o de tipo tag-item
  • not : trae los nodos que no cumplen una condicion
$x('//span[not(@class)]')
--> (11)聽[span, span, span, span, span, span, span, span, span, span, span]
#trae los nodos que no tienen atributos de tipo clase

Otra clase rompe cabezas que te hace salir de tu zona de confort y saber m谩s del tema. Una maquina de incorporar nuevo conocimiento.

C贸digo para traer los 3 elementos del top ten de tags:

$x('//span[@class="tag-item"][position()<4]/a/text()').map(x => x.wholeText)
$x('/html/body/div/div[@class="row"]/div[1]/div[@class="quote"]/div[@class="tags"]/a[@class="tag"][1]/text()').map(item => item.wholeText)

馃馃馃
Operadores l贸gicos en Xpath :
Cabe notar que los operadores se est谩n usando dentro del predicado.
!=
<>
and
or
not

Para traer a todos los autores de las citas

$x('//span/small[@class = "author"]/text()').map(x =>x.wholeText)
import requests
import lxml.html as html
import os #nos sirve para crear una carpeta con la fecha de hoy#
import datetime #nos sirve para TRAER la fecha de hoy#

HOME_URL = 'https://www.larepublica.co/'

XPATH_LINK_TO_ARTICLE = '//div[contains(@class, "V") or contains(@class, "col")]/a[contains(@class, "kicker")]/@href'
XPATH_TITLE = '//div[@class="mb-auto"]/text-fill/span/text()'
XPATH_SUMMARY = '//div[@class="lead"]/p/text()'
XPATH_BODY = '//div[@class="html-content"]/p[not(@class)]/text()'


def parse_notice(link, today):
    try:
        response = requests.get(link)
        if response.status_code == 200:
            notice = response.content.decode('utf-8')
            parsed = html.fromstring(notice)

            try:
                title = parsed.xpath(XPATH_TITLE)[0]
                title = title.replace('\"','')
                summary = parsed.xpath(XPATH_SUMMARY)[0]
                body = parsed.xpath(XPATH_BODY)            
            except IndexError:
                return

            with open(f'{today}/{title}.text', 'w', encoding='utf-8') as f:
                f.write(title)
                f.write('\n\n')
                f.write(summary)
                f.write('\n\n')
                for p in body:
                    f.write(p)
                    f.write('\n')
        else:
            raise ValueError(f'Error: {response.status_code}')
    except ValueError as ve:
        print(ve)


def parse_home():
    try:
        response = requests.get(HOME_URL)
        if response.status_code == 200:
            home = response.content.decode('utf-8') #response.content devuelve el documento html de la respuesta y .decode es un metodo que transforma todo los caracteres especiales en algo que python puede leer#
            parsed = html.fromstring(home)     #toma el contenido de html que ya se tiene en texto y se transforma en un documento especial en el cual se puede hacer XPATH#
            links_to_notices = parsed.xpath(XPATH_LINK_TO_ARTICLE)   #obtener la lista de links#
            #print(links_to_notices)#

            today = datetime.date.today().strftime('%d-%m-%Y') #nos TRAE la fecha de hoy#
            if not os.path.isdir(today):
                os.mkdir(today)     #esta linea de codigo crea una carpeta con la fecha de hoy, solo la crea si esa carpeta no existe#
            for link in links_to_notices:
                parse_notice(link, today) #Se va a entrar a cada link y se va a extraer toda la informacion del XPATH y eso lo va a guardar en con la fecha de hoy#
        else:
            raise ValueError(f'Error: {response.status_code}')
    except ValueError as ve:
        print(ve)               #este bloque de codigo sirve para detectar errores y devuelve el status code#


def run():
    parse_home()


if __name__ == '__main__':
    run()

Muy interesante

Operadores
= , !=, <, >, and, or, not.

Hola a todos, os dejo mis apuntes de esta clase, sin embargo, he creado un respositorio en github donde estan todos los apuntes de este curso: https://github.com/fer2002743/web-scraping

<h1>Operadores en Xpath</h1>

Para ser capaces de filtrar de una forma mas avanzada nos vamos a valer de operadores. Supongamos que quiero traer todos los elementos de spam que tienen una clase distinta a texto, para ello hacemos esto:

$x('//span[@class != "text"]')

Si recordamos clases anteriores, cuando usamos el predicado [1] o [last()] traemos el ultimo o el primer elemento, sin embargo, que pasa cuando tengo mucho elementos??. En este caso puedo usar un operador para filtrar que elementos quiero, por ejemplo:

$x('/HTML/body/div/div[position()>1]')
#esta expresion me trae los elementos que estan de uno para arriba

Por otro lado, tambien podemos usar los operadores logicos 鈥渁nd鈥 y 鈥渙r鈥, por ejemplo

#operador logico and
$x('//span[@class="text and @class="tag-item"]')

#operador logico or
$x('//span[@class="text" or @class="tag-item"]')

#operador not

$x('//span[not (@class="text")]')

Facundo sos groso!!!