python selenium selenium-webdriver heroku selenium-chromedriver

python - ConnectionResetError:[Errno 104] Restablecimiento de la conexión entre pares y ERR_NAME_NOT_RESOLVED en heroku con pruebas móviles a través de Selenium



selenium-webdriver selenium-chromedriver (2)

Me gustaría probar múltiples agentes de usuarios móviles con selenio y cromo. Estoy usando python 3.6 y desplegando a heroku. Basado en http://chromedriver.chromium.org/mobile-emulation .

Puedes descargar mi proyecto tanto para windows como para uso heroku en:

https://github.com/kc1/mobiletest

(tenga en cuenta que si implementa en heroku debe configurar FLASK_CONFIG para producción. También tenga en cuenta que el código del proyecto es ligeramente diferente al de esta pregunta porque he estado jugando con el código durante la semana pasada).

Yo tengo:

def some_long_calculation(): driver = create_chromedriver(''kkk'') # driver = create_chromedriver() driver.get("https://www.yahoo.com/") .....

y:

def create_chromedriver(ua=False): options = webdriver.ChromeOptions() CHROMEDRIVER_PATH = os.getenv(''$HOME'') or basedir+''/chromedriver.exe'' FLASK_CONFIG = os.getenv(''FLASK_CONFIG'') if ua: mobile_emulation = {"deviceName": "Nexus 5"} options.add_experimental_option("mobileEmulation", mobile_emulation) if FLASK_CONFIG and FLASK_CONFIG == "production": CHROMEDRIVER_PATH = ''/app/.chromedriver/bin/chromedriver'' GOOGLE_CHROME_SHIM = os.getenv(''$GOOGLE_CHROME_SHIM'') or ''no path found'' options.binary_location = ''/app/.apt/usr/bin/google-chrome-stable'' options.add_argument(''--disable-gpu'') options.add_argument(''--no-sandbox'') return webdriver.Chrome(executable_path=CHROMEDRIVER_PATH, options=options)

Si lo ejecuto localmente con el navegador móvil habilitado, funciona como se esperaba:

Si lo ejecuto en heroku con el navegador móvil habilitado:

Luego lo probé en heroku con el usuario móvil deshabilitado.

Así que al menos sé que la configuración está funcionando en cuanto a Chrome y Chromedriver.

registros de heroku:

2018-07-15T17:37:53.967643+00:00 app[web.1]: driver = create_chromedriver(''kkk'') 2018-07-15T17:37:53.967637+00:00 app[web.1]: png = some_long_calculation() 2018-07-15T17:37:53.967645+00:00 app[web.1]: File "/app/app/main/cl.py", line 120, in create_chromedriver 2018-07-15T17:37:53.967640+00:00 app[web.1]: File "/app/app/main/cl.py", line 123, in some_long_calculation 2018-07-15T17:37:53.967648+00:00 app[web.1]: return webdriver.Chrome(executable_path=CHROMEDRIVER_PATH, options=options) 2018-07-15T17:37:53.967651+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/selenium/webdriver/chrome/webdriver.py", line 75, in __init__ 2018-07-15T17:37:53.967654+00:00 app[web.1]: desired_capabilities=desired_capabilities) 2018-07-15T17:37:53.967656+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/selenium/webdriver/remote/webdriver.py", line 156, in __init__ 2018-07-15T17:37:53.967659+00:00 app[web.1]: self.start_session(capabilities, browser_profile) 2018-07-15T17:37:53.967661+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/selenium/webdriver/remote/webdriver.py", line 251, in start_session 2018-07-15T17:37:53.967669+00:00 app[web.1]: response = self.command_executor.execute(driver_command, params) 2018-07-15T17:37:53.967664+00:00 app[web.1]: response = self.execute(Command.NEW_SESSION, parameters) 2018-07-15T17:37:53.967667+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/selenium/webdriver/remote/webdriver.py", line 318, in execute 2018-07-15T17:37:53.967672+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/selenium/webdriver/remote/remote_connection.py", line 472, in execute 2018-07-15T17:37:53.967674+00:00 app[web.1]: return self._request(command_info[0], url, body=data) 2018-07-15T17:37:53.967677+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/selenium/webdriver/remote/remote_connection.py", line 496, in _request 2018-07-15T17:37:53.967679+00:00 app[web.1]: resp = self._conn.getresponse() 2018-07-15T17:37:53.967682+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/http/client.py", line 1331, in getresponse 2018-07-15T17:37:53.967685+00:00 app[web.1]: response.begin() 2018-07-15T17:37:53.967687+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/http/client.py", line 297, in begin 2018-07-15T17:37:53.967695+00:00 app[web.1]: line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1") 2018-07-15T17:37:53.967690+00:00 app[web.1]: version, status, reason = self._read_status() 2018-07-15T17:37:53.967698+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/socket.py", line 586, in readinto 2018-07-15T17:37:53.967692+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/http/client.py", line 258, in _read_status 2018-07-15T17:37:53.967700+00:00 app[web.1]: return self._sock.recv_into(b) 2018-07-15T17:37:53.967712+00:00 app[web.1]: ConnectionResetError: [Errno 104] Connection reset by peer

¿Cómo puedo arreglar esto?

EDITAR:

Gracias por tu respuesta detallada. He cambiado el código para incorporar las banderas que mencionaste. La versión de Chrome es 67.0.3396.99. Chromedriver es 2.40 y el selenio es 3.13. Desafortunadamente, no hay cambio en el resultado. Todavía estoy recibiendo el mismo error. En cuanto a su etapa 2 y 3 consejos. Actualmente estoy desplegando a Heroku, por lo que no tengo control total de las variables de entorno. ¿Hay alguna forma de hacer estos cambios usando python?

EDIT 2:

Mientras lo pienso más en https://sites.google.com/a/chromium.org/chromedriver/mobile-emulation el ejemplo usa

from selenium import webdriver mobile_emulation = { "deviceName": "Nexus 5" } chrome_options = webdriver.ChromeOptions() chrome_options.add_experimental_option("mobileEmulation", mobile_emulation) driver = webdriver.Remote(command_executor=''http://127.0.0.1:4444/wd/hub'', desired_capabilities = chrome_options.to_capabilities())

¿Está sugiriendo que el navegador está en '' http://127.0.0.1:4444/wd/hub ''?


ConnectionResetError: [Errno 104] Restablecimiento de la conexión por par

En general, cuando un cliente termina abruptamente sin cerrar la conexión, la pila TCP / IP del sistema operativo subyacente envía un RST packet . Python convierte esto en una excepción con el texto Conexión restablecida por par . Según el seguimiento de la pila de errores , significa que una vez que se invocó a self._read_status() (internamente) se asumió que Python recibía algo, pero la conexión se self._read_status() repentinamente y Python le informa de este error al provocar la excepción:

ConnectionResetError: [Errno 104] Connection reset by peer

La situación es algo similar a esta expresión :

"El restablecimiento de la conexión entre pares" es el equivalente de TCP / IP de volver a colgar el teléfono. Es más cortés que simplemente no responder, dejando a uno colgado. Pero no es el FIN-ACK esperado del conversador TCP / IP verdaderamente cortés.

Puede haber múltiples probabilidades detrás de este error de la siguiente manera.

Solución Etapa A

Una solución rápida y precisa será agregar algunas ChromeOptions recomendadas junto con la existente de la siguiente manera:

options.add_argument("start-maximized"); // open Browser in maximized mode options.add_argument("disable-infobars"); // disabling infobars options.add_argument("--disable-extensions"); // disabling extensions options.add_argument("--no-sandbox") options.add_argument("--disable-dev-shm-usage"); // overcome limited resource problems

y entonces

return webdriver.Chrome(executable_path=CHROMEDRIVER_PATH, options=options)

Nota : debe eliminar el argumento options.add_argument(''--disable-gpu'') ya que solo se aplica al sistema operativo Windows.

Solución Etapa B

Un par de puntos:

  • Según la documentación en Python Chrome Mobile Emulation el par de clave y valor parece ser "deviceName": "Google Nexus 5" (no "deviceName": "Nexus 5" )
  • Puede modificar su código para invocar Remote() través de cualquiera de las siguientes formas:

    • Invocar Remote() través de DesiredCapabilities() :

      from selenium import webdriver # import DesiredCapabilities was missing in your program from selenium.webdriver.common.desired_capabilities import DesiredCapabilities mobile_emulation = { "deviceName": "Google Nexus 5" } chrome_options = webdriver.ChromeOptions() chrome_options.add_experimental_option("mobileEmulation", mobile_emulation) capabilities = DesiredCapabilities.CHROME capabilities = options.to_capabilities() driver = webdriver.Remote(command_executor=''http://127.0.0.1:4444/wd/hub'', desired_capabilities = capabilities)

    • ¿Puede encontrar una discusión similar sobre la invocación de Remote() través de ChromeOptions() en Cómo agregar las opciones de ChromeOptions() Chrome a las '' ChromeOptions() ''?

    • Invocando Remote() través de ChromeOptions() :

      from selenium import webdriver mobile_emulation = { "deviceName": "Google Nexus 5" } chrome_options = webdriver.ChromeOptions() chrome_options.add_experimental_option("mobileEmulation", mobile_emulation) driver = webdriver.Remote(command_executor=''http://127.0.0.1:4444/wd/hub'', options=chrome_options)

    • Encontrará una discusión similar sobre la invocación de Remote() través de ChromeOptions() en Remote WebDriver UnreachableBrowserException: no se pudo iniciar una nueva sesión

  • Para su referencia aquí está el enlace a la documentación en Webdriver.android
  • Para su referencia, aquí está el enlace a la documentación sobre Getting started with Selendroid

Solución Etapa C

Si aún está viendo el error, realice las siguientes tareas de actualización / limpieza:

  • Actualiza Selenium a los niveles actuales Versión 3.13.0 .
  • Actualiza ChromeDriver al nivel actual de ChromeDriver v2.40 .
  • Mantenga la versión de Chrome entre los niveles de Chrome v66-68 . ( según las notas de la versión de ChromeDriver v2.40 )
  • Limpie su Área de trabajo del proyecto a través de su IDE y Reconstruya su proyecto solo con las dependencias requeridas.
  • ( Solo WindowsOS ) Use la herramienta CCleaner para borrar todas las tareas del sistema operativo antes y después de la ejecución de su Test Suite .
  • ( Solo LinuxOS ) Libere y libere la memoria no utilizada / almacenada en caché en Ubuntu / Linux Mint antes y después de la ejecución de su Test Suite .
  • Si la versión básica de su cliente web es demasiado antigua, desinstálela a través de Revo Uninstaller e instale un GA reciente y una versión de lanzamiento del cliente web .
  • Tomar un reinicio del sistema .
  • Siempre invoque driver.quit() dentro del tearDown(){} para cerrar y destruir las instancias de WebDriver y Web Client con gracia.
  • Ejecute su @Test .

Solución Etapa D

Buscando una solución granular a un error específico entré en Amazon S3 y "Connection Reset by Peer" donde Garry Dolley resume la causa del problema como una combinación de los siguientes factores:

  • Escalado de la ventana TCP
  • Kernels de Linux 2.6.17 o más nuevos

Los kernels de Linux 2.6.17+ aumentaron el tamaño máximo de la ventana TCP / búfer, y esto comenzó a causar que otros equipos se desvanecieran, si no podía manejar ventanas TCP suficientemente grandes. El engranaje restablecería la conexión, y vemos esto como un mensaje de "Restablecimiento de conexión por parte de un par".

Una solución potencial será colocar las siguientes entradas en /etc/sysctl.conf :

  • net.ipv4.tcp_wmem = 4096 16384 512000
  • net.ipv4.tcp_rmem = 4096 87380 512000

Nota : esta solución es fácil, pero ralentizará su rendimiento máximo al intercambiar descargas más rápidas.

PD

Si corresponde, asegúrese de que / etc / hosts en su sistema contenga la siguiente entrada:

127.0.0.1 localhost.localdomain localhost

Discusiones Relacionadas

Aquí están algunas de las discusiones relacionadas:

Referencias

Aquí están las referencias de esta discusión:


El mensaje de error específico dice

La dirección IP del servidor de Android no se pudo encontrar.

Para mí, eso indica que el navegador está intentando buscar una entrada de DNS para android , que no es un TLD válido. Por casualidad, ¿el navegador intenta acceder a http://android , en lugar de algo como https://www.google.com ? Puedo replicar ese mismo mensaje de error en mi propio Chrome escribiendo http://android en la barra de direcciones. Esto me lleva a creer que la especificación de una URL correcta para el navegador debería resolver el problema.