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 deDesiredCapabilities()
: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 deChromeOptions()
en Cómo agregar las opciones deChromeOptions()
Chrome a las ''ChromeOptions()
''? -
Invocando
Remote()
través deChromeOptions()
: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 deChromeOptions()
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 deltearDown(){}
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:
- Python socket.error: [Errno 104] Restablecimiento de la conexión por par
- Sin embargo, otro error de ''Conexión restablecida por par''
- Restablecimiento de la conexión por par [errno 104] en Python 2.7
- WebDriver UnreachableBrowserException remoto: no se pudo iniciar una nueva sesión
- ¿Cómo agregar opciones de cromo de selenio a las ''capacidades deseadas''?
Referencias
Aquí están las referencias de esta discusión:
- Ejemplo: Prueba automatizada de unidades de emulación móvil de Python Chrome con Selenium 2 WebDriver ChromeDriver
- Amazon S3 y "Connection Reset by Peer"
- Cómo: Sintonización de red / TCP / UDP
- Cómo: Liberar y liberar la memoria no utilizada / almacenada en caché en Ubuntu / Linux Mint
- https://sites.google.com/a/chromium.org/chromedriver/mobile-emulation
- Webdriver.android
- Empezando con Selendroid
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.