Tabla de contenido
-
-
- 1. Uso básico
- 2. Acerca de XPath
- 3. Personaliza xpath según tus necesidades
-
- (1) Múltiples métodos xpath pueden corresponder a la misma etiqueta HTML
- (2) Obtenga el valor xpath personalizado de acuerdo con la información del atributo de la etiqueta
- (3) Obtenga todos los elementos del elemento web que cumplan con una determinada condición xpath
- (4) Ruta relativa + valor xpath
- 4. Esperar implícitamente a que aparezca el elemento correspondiente a xpath
- 5. El método `WEBELEMENT.click()` no puede hacer clic en la solución del elemento invisible (que no se muestra en la vista actual)
-
1. Uso básico
Hay muchas maneras de usarlo en Internet , pero de acuerdo con el método relativamente nuevo find_element_by_xpath
que usé, este método ya no se puede usar y debe usarse en su lugar .selenium
webdriver
find_element_by_xpath
find_element(By.XPATH,'A XPATH Value')
web_element = driver.find_element(By.XPATH,'A XPATH Value')
2. Acerca de XPath
(1) Copie un xpath de la página web
El valor xpath estúpido utilizado en este artículo es el uso de xpath de la siguiente manera: haga clic
directamente F12
en el icono en la esquina superior izquierda de la página web
y haga clic en un elemento, y la ubicación en el código fuente se mostrará a la derecha, en el código fuente
Puede obtener un xpath haciendo , pero este tipo de xpath "no es bueno", porque si el código fuente cambia, es probable que cambie el xpath
(2) ¿Por qué xpath se ve así?
Primero, haga un análisis simple del xpath que acabamos de mencionar.
//*[@id="root"]/div/main/div/div/div/div/div[2]/div/div[1]/div/div[1]/form/div[2]/div/label/input
username = self.driver.find_element(By.XPATH,'//*[@id="root"]/div/main/div/div/div/div/div[2]/div/div[1]/div/div[1]/form/div[2]/div/label/input').text
El xpath anterior, combinado con la declaración python3 anterior, se puede interpretar como: en self.driver
este web element
, entre todas las etiquetas (debido a la primera //
), encuentre la primera (porque se usa el método find_element, que se ampliará más adelante) allí es una identificación en el atributo de la etiqueta, y su valor es cualquier (debido a *
) etiqueta de "raíz", la primera etiqueta div debajo de ella, la primera etiqueta div debajo de ella, la primera etiqueta div debajo *4, la segunda debajo it La primera etiqueta de etiqueta debajo de la etiqueta div, la primera etiqueta de entrada debajo de ella, por lo que finalmente se encuentra la etiqueta de entrada.
3. Personaliza xpath según tus necesidades
(1) Múltiples métodos xpath pueden corresponder a la misma etiqueta HTML
Después de casi comprender el principio de xpath, puede diseñar xapth de acuerdo con sus propias necesidades y cómo escribir el xpath anterior:
①
//*[@id="root"]/div/main/div/div/div/div/div[2]/div/div[1]/div/div[1]/form/div[2]/div/label/input
Cambio:
//div[@id="root"]/div/main/div/div/div/div/div[2]/div/div[1]/div/div[1]/form/div[2]/div/label/input
esto es solo un pequeño cambio
② Otro ejemplo es
el valor xpath completo de la etiqueta:
/html/body/div[1]/div/main/div/div/div/div/div[2]/div/div[1]/div/div[1]/form/div[2]/div/label/input
los /html/body/div[1]
y //div[@id="root"]
son iguales y se pueden reemplazar entre sí.
(2) Obtenga el valor xpath personalizado de acuerdo con la información del atributo de la etiqueta
Se puede notar que la input
etiqueta anterior tiene un atributo de class
, que value
es , después de buscar "Input i7cW1UcwT6ThdhTakqFm username-input"
en la consola , se encuentra que solo hay dos etiquetas con (o dos etiquetas de entrada que cumplen con esta condición), queremos obtener el teléfono de entrada número El xpath correspondiente (usado en el código de Python a continuación) puede diseñarse así:ctrl+F
Input i7cW1UcwT6ThdhTakqFm username-input
class="Input i7cW1UcwT6ThdhTakqFm username-input"
phone_number = self.driver.find_element(By.XPATH,'XPATH')
//input[@class="Input i7cW1UcwT6ThdhTakqFm username-input"]
O
//*[@class="Input i7cW1UcwT6ThdhTakqFm username-input"]
el significado es: self.driver
encuentre la primera etiqueta de entrada class="Input i7cW1UcwT6ThdhTakqFm username-input"
(condición restringida, no ignorar @
) en (en este caso, puede ser *
(cualquier etiqueta))
Como se mencionó anteriormente, el xpath copiado por la consola generalmente no es muy bueno (en mi opinión), porque si hay algunos cambios en el código fuente, es posible cambiar el xpath, pero el atributo de cierta etiqueta no suele cambiar, lo que mejora la tolerancia a fallas del código ante cambios en el código fuente de la página web.
(3) Obtenga todos los elementos del elemento web que cumplan con una determinada condición xpath
Usando el valor xpath anterior personalizado de acuerdo con el atributo de la etiqueta, puede obtener todos los elementos del elemento web que cumplen una determinada condición xpath al mismo tiempo. Esto es muy útil cuando se procesan datos similares en lotes. En el ejemplo anterior, necesita para ingresar el código de verificación después de ingresar el número de teléfono móvil. Si aún usa el método find_element + el método xpath completo, es posible que deba diseñar declaraciones de Python como esta:
phone_number = self.driver.find_element(By.XPATH,'//*[@id="root"]/div/main/div/div/div/div/div[2]/div/div[1]/div/div[1]/form/div[2]/div/label/input')
code = self.driver.find_element(By.XPATH,'//*[@id="root"]/div/main/div/div/div/div/div[2]/div/div[1]/div/div[1]/form/div[3]/div/label/input')
Cada vez que necesite copiar el valor de xpath en la página web,
y utilizando el método anterior para personalizar el valor de xpath de acuerdo con el atributo de la etiqueta, puede diseñar el siguiente código de python
input_list = self.driver.find_elements(By.XPATH,'//input[@class="Input i7cW1UcwT6ThdhTakqFm username-input"]')
phone_number = input_list[0]
code = input_list[1]
Se utiliza el método find_elements (a diferencia de find_element, find_element es find_elements[0]), y su valor de retorno es una lista de elementos web. El significado del código anterior es: input_list es una lista que contiene todo lo que está debajo de self.driver
esteweb element
class="Input i7cW1UcwT6ThdhTakqFm username-input"
web element
(4) Ruta relativa + valor xpath
A veces habrá tal requisito:
es necesario obtener el número de aprobaciones, información del título, información del contenido, etc. en toda la información de respuesta del usuario. Por supuesto, puede escribir el siguiente código:
agree_list = self.driver.find_elements(By.XPATH,'//Button[@class="Button VoteButton VoteButton--up FEfUrdfMIKpQDJDqkjte"]/span')
titles = ....
content = ...
......
for index,agree_info in enumerate(agree) :
agree = agree_list[i]
title = titles[i]
....
Pero si a veces hay más de uno class="Button VoteButton VoteButton--up FEfUrdfMIKpQDJDqkjte"]
(botón de acuerdo) en la información de la respuesta, dé un ejemplo inapropiado:
si el botón en la posición subrayada en la imagen a continuación también es class="Button VoteButton VoteButton--up FEfUrdfMIKpQDJDqkjte"]
¿cómo resolverlo? (en realidad no, solo un ejemplo)
Lo siguiente proporciona una forma de pensar:
este método en una clase determinada
list_items = self.driver.find_elements(By.XPATH,'//div[@class="List-item"]')
for list_item in list_items :
agree = list_item.find_element(By.XPATH,'.//Button[@class="Button VoteButton VoteButton--up FEfUrdfMIKpQDJDqkjte"]/span')
...
......
//
Nota: En el siguiente código, se reemplaza el comienzo del xpath ../
, y self.driver se reemplaza por otro web element
( list_item
)
para que solo se obtenga el botón list item
en este class
.
\
4. Esperar implícitamente a que aparezca el elemento correspondiente a xpath
find_element
Para evitar que el archivo python ejecute otros métodos antes de que la página se cargue por completo debido a problemas de velocidad de la red, lo que hace que el programa informe un error y se cierre de forma anormal, puede usar la siguiente instrucción para esperar a que aparezca el elemento correspondiente a xpath :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
WebDriverWait(self.driver,10000).until(EC.presence_of_element_located((By.XPATH, 'XPATH')))
Entre ellos, 1000 es el tiempo de espera más largo establecido. Si xpath
el elemento correspondiente al tiempo de espera aún no aparece, el programa seguirá informando un error. Comparado con el método utilizado , la ventaja de este método es que después de que el elemento correspondiente sleep
aparece en la página , xpath
continuará ejecutando el programa rápidamente, sin xpath
el problema de que el programa aún esté esperando la ejecución después de que aparezca.
5. WEBELEMENT.click()
La solución del método de que no se puede hacer clic en el elemento invisible (que no se muestra en la vista actual)
Puedes usar la siguiente declaración
self.driver.execute_script("arguments[0].click();", web_element_clickable)
Uno de ellos web_element_clickable
es clicable web_element
.
6. La página no carga todo el contenido de una vez
otra cosa es que la pagina no carga todo el contenido de una vez, es necesario deslizar hacia abajo la pagina para cargar mas contenido, puedes usar la siguiente sentencia de python, el siguiente ejemplo es que si la pagina actual tiene menos de
10 xpath valores //div[@class="List-item"]
, web element
enviar Desplácese hacia abajo en la página hasta que se cumplan las condiciones.
ask_answers = self.driver.find_elements(By.XPATH,'//div[@class="List-item"]')
ask_answers_count = len(ask_answers)
# Scroll down until the count is at least 10
while ask_answers_count < valid_answers_count:
# Scroll by 100 pixels
self.driver.execute_script("window.scrollBy(0, 100);")
# Get the updated ask_answers_count of div elements with class "List-item"
ask_answers = self.driver.find_elements(By.XPATH,'//div[@class="List-item"]')
ask_answers_count = len(ask_answers)