Introducción y principio de funcionamiento de Selenium/webdriver

 He estado mirando algunas cosas de bajo nivel últimamente. La traducción de conductor es conducir, el significado del conductor. Si compara webdriver con un controlador, es muy apropiado.

Podemos comparar WebDriver conduciendo un navegador con un taxista conduciendo un taxi. Hay tres roles al conducir un taxi:

· Pasajero: Le dice al taxista a dónde ir y cómo llegar.

· Taxista: Conduce el taxi a petición de los pasajeros.

· Taxi: El taxi completa la conducción real según el control del conductor y envía a los pasajeros al destino.

Hay tres roles similares en WebDriver:

· Código de prueba automatizado: el código de prueba automatizado envía solicitudes a los controladores del navegador (como el controlador de Firefox, el controlador de Google).

· Controlador del navegador: Analiza los códigos de estas pruebas automatizadas y los envía al navegador después del análisis.

· Navegador: Ejecuta las instrucciones enviadas por el controlador del navegador, y finalmente completa la operación que el ingeniero desea.

Así que en esta analogía:

· El código de prueba automatizado escrito por el maquinista es equivalente al del pasajero.

· Los controladores de navegador son equivalentes a los taxistas.

· El navegador es como un taxi.

Expliquemos técnicamente el principio de funcionamiento de WebDriver:

Técnicamente hablando, los mismos tres roles anteriores:

· API WebDriver (basada en Java, Python, C# y otros lenguajes).

· Para el lenguaje Java, es el paquete Jar de selenium descargado, como el paquete selenium-java-3.8.1.zip, que representa la versión de Selenium3.8.1.

· Controlador de navegador (controlador de navegador), cada navegador tiene su propio controlador, que existe en forma de archivos exe. Por ejemplo, chromedriver.exe de Google, geckodriver.exe de Firefox y el navegador IEDriverServer.exe de IE.

El navegador es, por supuesto, los navegadores de uso común con los que estamos familiarizados. ¿Cómo se comunican entre sí cuando se ejecuta el script de WebDriver? ¿Por qué el mismo controlador de navegador puede manejar scripts de java y python? Echemos un vistazo a lo que sucede en el backend cuando se ejecuta un script de Selenium:

· Para cada secuencia de comandos de Selenium, se crea una solicitud http y se envía al controlador del navegador.

· El controlador del navegador contiene un servidor HTTP para recibir estas solicitudes http.

Después de recibir la solicitud, el servidor HTTP controla el navegador correspondiente de acuerdo con la solicitud.

El navegador ejecuta pasos de prueba específicos
y devuelve los resultados de la ejecución del paso al servidor HTTP. El servidor HTTP devuelve el resultado al script de Selenium, si es un código http incorrecto, veremos el mensaje de error correspondiente en la consola.

¿Por qué usar el protocolo HTTP?

Debido a que el protocolo HTTP es un protocolo estándar para la comunicación entre un navegador y un servidor web, casi todos los lenguajes de programación proporcionan ricas bibliotecas http, por lo que es conveniente manejar solicitudes y solicitudes entre el cliente y el servidor. la estructura de WebDriver es una estructura típica de C/S, la API de WebDriver es equivalente al cliente y el pequeño controlador del navegador es el servidor.

El protocolo basado en WebDriver: protocolo JSON Wire.

El protocolo JSON Wire se basa en el protocolo http, estandarizando aún más los datos en la parte del cuerpo de la solicitud y respuesta http.

Sabemos que las solicitudes y respuestas HTTP a menudo incluyen las siguientes partes: método de solicitud http, cuerpo de contenido de solicitud y respuesta http, código de estado de respuesta http, etc.

Métodos comunes de solicitud de http:
GET: se utiliza para obtener información del servidor. Por ejemplo, para obtener la información del título de una página web.

POST: Envía una solicitud de operación al servidor. Como findElement, Click, etc.

código de estado de respuesta http:

Para brindarles a los usuarios información de retroalimentación más clara, WebDriver proporciona códigos de estado de respuesta http más detallados, como:

7:NingúnElemento

11:Elemento no visible

200:Todo bien

Ahora viene la parte del cuerpo de respuesta y solicitud http más crítica:

La parte del cuerpo transmite principalmente datos específicos. En WebDriver, estos datos existen y se transmiten en forma de JSON. Este es el protocolo JSON Wire.

Selenium es una API de controlador web que encapsula las API de varios navegadores en "un protocolo diseñado y definido por el mismo Selenium, llamado The WebDriver Wire Protocol".

Nivel de operación:
1. Los evaluadores escriben scripts de prueba de automatización de la interfaz de usuario (java, python, etc.) Después de ejecutar los scripts, el programa abrirá el navegador webdriver especificado.

El navegador webdriver actúa como un servidor remoto para aceptar comandos de script, y el servicio web abrirá un puerto: http://localhost:9515 y el navegador escuchará este puerto.

2. El servicio web traducirá el lenguaje de script al formato json y lo pasará al navegador para ejecutar el comando de operación.

Nivel lógico:
1. Después de que el probador ejecuta el script de prueba, se crea una sesión y se envía una solicitud de descanso al servicio web a través de la solicitud http.

2. El servicio web traduce la solicitud de descanso en una secuencia de comandos que el navegador puede entender y luego acepta el resultado de la ejecución de la secuencia de comandos.

3. El servicio web encapsula el resultado: json en el script de prueba/cliente del cliente, y luego el cliente sabe si la operación fue exitosa y la prueba también se puede verificar.

Podemos verificarlo:
descargue el controlador de cromo, colóquelo en la variable de entorno, preste atención para que coincida con la versión del navegador Chrome y luego ejecute el controlador de cromo

Como puede ver, se iniciará un servidor y se abrirá el puerto 9515:

andersons-iMac:~ anderson$ chromedriver

Iniciando ChromeDriver 2.39.562713 (dd642283e958a93ebf6891600db055f1f1b4f3b2) en el puerto 9515

Solo se permiten conexiones locales.

Información de GVA: Conectado con éxito al complemento de Intel, sin conexión Gen9

Destaca que solo se permiten conexiones locales. Como se mencionó anteriormente, el pasajero envía una solicitud al conductor y el comportamiento es construir una solicitud http. La solicitud construida se ve así:

Método de solicitud: POST

Dirección de solicitud: http://localhost:9515/session

Cuerpo de la solicitud:

capabilities = {
 
      "capabilities": {
 
          "alwaysMatch": {
 
              "browserName": "chrome"
 
          },
 
          "firstMatch": [
 
              {}
 
          ]
 
      },
 
      "desiredCapabilities": {
 
          "platform": "ANY",
 
          "browserName": "chrome",
 
          "version": "",
 
          "chromeOptions": {
 
              "args": [],
 
              "extensions": []
 
          }
 
      }
 
  }
 
  我们可以尝试使用python requests 向 ChromeDriver发送请求
 
  import requests
 
  import json
 
  session_url = 'http://localhost:9515/session'
 
  session_pars = {"capabilities": {"firstMatch": [{}], \
 
                        "alwaysMatch": {"browserName": "chrome",\
 
                                        "platformName": "any", \
 
                                        "goog:chromeOptions": {"extensions": [], "args": []}}}, \
 
                  "desiredCapabilities": {"browserName": "chrome", \
 
                               "version": "", "platform": "ANY", "goog:chromeOptions": {"extensions": [], "args": []}}}
 
  r_session = requests.post(session_url,json=session_pars)
 
  print(json.dumps(r_session.json(),indent=2))
 
  结果:
 
  {
 
    "sessionId": "44fdb7b1b048a76c0f625545b0d2567b",
 
    "status": 0,
 
    "value": {
 
      "acceptInsecureCerts": false,
 
      "acceptSslCerts": false,
 
      "applicationCacheEnabled": false,
 
      "browserConnectionEnabled": false,
 
      "browserName": "chrome",
 
      "chrome": {
 
        "chromedriverVersion": "2.40.565386 (45a059dc425e08165f9a10324bd1380cc13ca363)",
 
        "userDataDir": "/var/folders/yd/dmwmz84x5rj354qkz9rwwzbc0000gn/T/.org.chromium.Chromium.RzlABs"
 
      },
 
      "cssSelectorsEnabled": true,
 
      "databaseEnabled": false,
 
      "handlesAlerts": true,
 
      "hasTouchScreen": false,
 
      "javascriptEnabled": true,
 
      "locationContextEnabled": true,
 
      "mobileEmulationEnabled": false,
 
      "nativeEvents": true,
 
      "networkConnectionEnabled": false,
 
      "pageLoadStrategy": "normal",
 
      "platform": "Mac OS X",
 
      "rotatable": false,
 
      "setWindowRect": true,
 
      "takesHeapSnapshot": true,
 
      "takesScreenshot": true,
 
      "unexpectedAlertBehaviour": "",
 
      "version": "71.0.3578.80",
 
      "webStorageEnabled": true
 
    }
 
  }

Cómo abrir una página web, similar a driver.get(url)

Entonces la petición construida es:

Método de solicitud: POST

Dirección de solicitud: http://localhost:9515/session/:sessionId/url

Nota: ":sessionId" en la dirección anterior

El valor de sessionId en el resultado devuelto por la solicitud para iniciar el navegador

Por ejemplo: acabo de enviar una solicitud, inicié el navegador y devolví el resultado "sessionId": "44fdb7b1b048a76c0f625545b0d2567b"  

Luego solicita la dirección URL

Dirección de solicitud: http://localhost:9515/session/b2801b5dc58b15e76d0d3295b04d295c/url

Cuerpo del cuerpo: {"url": "https://www.baidu.com", "sessionId": "44fdb7b1b048a76c0f625545b0d2567b"}

即: URL
de solicitudes de importación
 
= 'http://localhost:9515/session/44fdb7b1b048a76c0f625545b0d2567b/url'
 
pars = {"url": "https://www.baidu.com", "sessionId": "44fdb7b1b048a76c0f625545b0d2567b"}
 
r = solicitudes.post(url,json=pars)
 
print(r.json())

Cómo localizar elementos, similar a driver.finde_element_by_xx:

Método de solicitud: POST

Dirección de solicitud: http://localhost:9515/session/:sessionId/element

Nota: ":sessionId" en la dirección anterior

El valor de sessionId en el resultado devuelto por la solicitud para iniciar el navegador.

Por ejemplo: acabo de enviar una solicitud, inicié el navegador y devolví el resultado "sessionId": "b2801b5dc58b15e76d0d3295b04d295c"  

Luego construyo la dirección de solicitud para encontrar el elemento de la página.

Dirección de solicitud: http://localhost:9515/session/b2801b5dc58b15e76d0d3295b04d295c/element

Cuerpo del cuerpo: {"usando": "selector css", "valor": ".postTitle a", "sessionId": "b2801b5dc58b15e76d0d3295b04d295c"}

Ahora mismo:

solicitudes de importación

url = 'http://localhost:9515/sesión/b2801b5dc58b15e76d0d3295b04d295c/elemento'

pars = {"usando": "selector css", "valor": ".postTitle a", "sessionId": "b2801b5dc58b15e76d0d3295b04d295c"}

r = solicitudes.post(url,json=pars)

imprimir (r. json ())

Cómo manipular elementos: similar a click()

Método de solicitud: POST

Dirección de solicitud: http://localhost:9515/session/:sessionId/element/:id/click

Nota: ":sessionId" en la dirección anterior

El valor de sessionId en el resultado devuelto por la solicitud para iniciar el navegador

:id devuelve el valor de ELEMENT después de solicitar localizar el elemento

Por ejemplo: acabo de enviar una solicitud, inicié el navegador y devolví el resultado "sessionId": "b2801b5dc58b15e76d0d3295b04d295c"  

Posicionamiento de elementos, devuelve el valor de ELEMENT "0.11402119390850629-1"

Luego construyo la dirección de solicitud para hacer clic en el elemento de la página.

Dirección de solicitud: http://localhost:9515/session/b2801b5dc58b15e76d0d3295b04d295c/element/0.11402119390850629-1/click

Cuerpo del cuerpo: {"id": "0.11402119390850629-1", "sessionId": "b2801b5dc58b15e76d0d3295b04d295c"}

Ahora mismo:

import requests
 
  url = 'http://localhost:9515/session/b2801b5dc58b15e76d0d3295b04d295c/element/0.11402119390850629-1/click'
 
  pars ={"id": "0.5930642995574296-1", "sessionId": "b2801b5dc58b15e76d0d3295b04d295c"}
 
  r = requests.post(url,json=pars)
 
  print(r.json())

 Como se puede ver en lo anterior, la automatización de la interfaz de usuario en realidad se puede escribir como automatización de API.

  solo solo

  Es tan engorroso, no hay un comando wedriver empaquetado para usar, se siente un poco como quitarse los pantalones y tirarse un pedo.

  Escribamos un fragmento de código para sentir:

  import requests
 
  import time
 
  capabilities = {
 
      "capabilities": {
 
          "alwaysMatch": {
 
              "browserName": "chrome"
 
          },
 
          "firstMatch": [
 
              {}
 
          ]
 
      },
 
      "desiredCapabilities": {
 
          "platform": "ANY",
 
          "browserName": "chrome",
 
          "version": "",
 
          "chromeOptions": {
 
              "args": [],
 
              "extensions": []
 
          }
 
      }
 
  }

# Abra el navegador http://127.0.0.1:9515/session

res = solicitudes.post('http://127.0.0.1:9515/sesión', json=capacidades).json()

sesión_id = res['sesiónId']

#Abrir Baidu

solicitudes.post('http://127.0.0.1:9515/session/%s/url' % session_id,

              json={"url": "http://www.baidu.com", "sessionId": session_id})

tiempo.dormir(3)

# Cierra el navegador y borra la sesión

request.delete('http://127.0.0.1:9515/session/%s' % session_id, json={"sessionId": session_id})

De hecho, para comprender el principio real, es decir, para la conveniencia de resolver problemas, es más conveniente ver y resolver problemas durante la depuración.

Por supuesto, si también necesita llamar a una pequeña cantidad de automatización de la interfaz de usuario en la automatización de la interfaz, puede considerar este método.

Los amigos que están estudiando para el examen pueden hacer clic en la tarjeta pequeña a continuación

Supongo que te gusta

Origin blog.csdn.net/2301_76643199/article/details/131897671
Recomendado
Clasificación