web-dev-qa-db-ja.com

ConnectionResetError:[Errno 104] Seleniumを介したモバイルテストで、herokuでピアおよびERR_NAME_NOT_RESOLVEDによって接続がリセットされました

Seleniumとchromeで複数のモバイルユーザーエージェントをテストしたいと思います。私はpython 3.6を使用してherokuにデプロイしています。 http://chromedriver.chromium.org/mobile-emulation に基づいています。

私のプロジェクトは、windowsとherokuの使用の両方でダウンロードできます:

https://github.com/kc1/mobiletest

(herokuにデプロイする場合は、FLASK_CONFIGを本番に設定する必要があることに注意してください。また、プロジェクトのコードはこの質問とは少し異なることに注意してください。

私が持っています:

def some_long_calculation():
    driver = create_chromedriver('kkk')
    # driver = create_chromedriver()

    driver.get("https://www.yahoo.com/")
    .....

および:

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)  

モバイルブラウザを有効にしてローカルで実行すると、期待どおりに動作します。

enter image description here

モバイルブラウザを有効にしてherokuで実行する場合:

enter image description here

次に、モバイルユーザーを無効にしてherokuで試しました。

enter image description here

少なくとも、chrome and chromedriver。

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

どうすれば修正できますか?

編集:

詳細な回答をありがとう。あなたが言及したフラグを組み込むようにコードを変更しました。 Chromeバージョンは67.0.3396.99です。Chromedriverは2.40、Seleniumは3.13です。残念ながら、結果に変更はありません。同じエラーが引き続き発生します。ステージ2と3アドバイス:現在herokuにデプロイしているため、環境変数を完全に制御することはできませんが、Pythonを使用してこれらの変更を行う方法はありますか?

編集2:

https://sites.google.com/a/chromium.org/chromedriver/mobile-emulation でさらに考えると、この例では

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())

ブラウザが「 http://127.0.0.1:4444/wd/hub 」にあることを提案していますか

8
user61629

ConnectionResetError:[Errno 104]ピアによる接続のリセット

一般に、クライアントが接続を閉じずに突然終了すると、RST packetが基盤OSのTCP/IPスタックによって送信されます。 Pythonこれをテキストの例外に変換しますpeerによってリセットされた接続。あなたのエラースタックに従ってtraceこれは、[内部で)self._read_status()が呼び出されたことを意味しますPython何かを受信すると想定されていますが、接続が突然切断され、Python通知します例外を発生させることによるエラー:

ConnectionResetError: [Errno 104] Connection reset by peer

状況は this expression に多少似ています:

「ピアによる接続リセット」は、電話をフックにバタンと戻すTCP/IPに相当します。単に返事をしないよりも丁寧で、1つだけぶら下がっています。しかし、それは本当に丁寧なTCP/IPコンバーサーに期待されるFIN-ACKではありません。

次のように、このエラーの背後には複数の確率があります。


ソリューションステージA

迅速かつ正確な解決策は、いくつかの推奨されるChromeOptionsを既存のものとともに次のように追加することです。

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

その後

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

:Windows OSのみに適用されるため、引数options.add_argument('--disable-gpu')を削除する必要があります。


ソリューションステージB

いくつかのポイント:

  • Python Chrome Mobile Emulation 内のドキュメントによると、KeyおよびValueペアは"deviceName": "Google Nexus 5""deviceName": "Nexus 5"ではない)
  • 次のいずれかの方法で、コードを微調整してRemote()を呼び出すことができます。

    • Remote()から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)
      
    • [Selenium chrome optionsを 'desiredCapabilities'に追加する方法? ]でRemote()からChromeOptions()を呼び出すことに関する同様の議論を見つけます。

    • Remote()から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)
      
    • リモートWebDriver UnreachableBrowserException:新しいセッションを開始できませんでしたRemote()からChromeOptions()の呼び出しに関する同様の議論があります。

  • 参考のために、 Webdriver.Android のドキュメントへのリンクを参照してください。
  • 参考のために、 Getting started with Selendroid のドキュメントへのリンクを参照してください。

ソリューションステージC

それでもエラーが表示される場合は、次のアップグレード/クリーンアップタスクを実行します。

  • Seleniumを現在のレベルにアップグレード バージョン3.13.0 .
  • ChromeDriverを現在の ChromeDriver v2.40 レベルにアップグレードします。
  • Chromeバージョン間Chrome v66-68レベルを維持します。 ( ChromeDriver v2.40リリースノートによる
  • Clean your Project Workspace through your [〜#〜] ide [〜#〜] and Rebuild with with必要な依存関係のみ。
  • WindowsOSのみCCleaner ツールを使用して、テストスイートの実行前後にすべてのOSの雑用を拭き取ります=。
  • LinuxOSのみbuntu/Linux Mintの未使用/キャッシュメモリの解放と解放テストスイートの実行前後。
  • ベースのWeb Clientバージョンが古すぎる場合は、 Revo Uninstaller を使用してアンインストールし、最新のGA =およびWeb Clientのリリースバージョン。
  • System Rebootを実行します。
  • 常にdriver.quit()メソッド内でtearDown(){}を呼び出して、WebDriverおよびWeb Clientインスタンスを正常に閉じて破棄します。
  • @Testを実行します。

ソリューションステージD

Amazon S3と「ピアによる接続リセット」 Garry Dolleyがサマライズする特定のエラーの詳細な解決策を探しました問題の原因は、以下の要因の組み合わせです。

  • TCPウィンドウのスケーリング
  • Linuxカーネル2.6.17以降

Linuxカーネル2.6.17以降では、TCPウィンドウ/バッファの最大サイズが大きくなり、十分に大きなTCP windows。ギアは接続をリセットし、これは「ピアによる接続リセット」メッセージと見なされます。

潜在的な解決策は、/etc/sysctl.conf内に次のエントリを配置することです。

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

:この修正は簡単ですが、高速ダウンロードと引き換えに最大スループットが低下します。


PS

該当する場合、システムの/ etc/hostsに次のエントリが含まれていることを確認します。

127.0.0.1               localhost.localdomain localhost

関連する議論

関連するディスカッションの一部を次に示します。


参照資料

この議論の参考文献は次のとおりです。

8
DebanjanB

特定のエラーメッセージは言う

AndroidのサーバーIPアドレスが見つかりませんでした。

私にとって、これはブラウザがAndroidのDNSエントリを検索しようとしていることを示しています。これは有効なTLDではありません。偶然、ブラウザはhttp://Androidのようなものではなく、https://www.google.comにアクセスしようとしていますか?アドレスバーにhttp://Androidと入力することで、同じエラーメッセージを自分のChromeで複製できます。これにより、ブラウザに適切なURLを指定すると問題が解決するはずです。

2
Josh W Lewis