【问题标题】:How to get status code by using selenium.py (python code)如何使用 selenium.py(python 代码)获取状态码
【发布时间】:2011-08-13 13:01:11
【问题描述】:

我正在用 python 编写一个 selenium 脚本,但我想我没有看到任何关于:

如何从 selenium Python 代码中获取 http 状态码

或者我错过了什么。如果有人发现,请随时发布。

【问题讨论】:

    标签: python selenium


    【解决方案1】:

    永远不要说什么是不可能的。票数最高的答案是可怕的。还有许多其他答案可以导致可能的解决方案,但我将分享我个人是如何实现这一点的,它基于another Stack Overflow answer

    使用谷歌浏览器测试。 Firefox 或 PhantomJS 的细节可能有点不同。

    我创建了一个方法来检查您访问过的任何 URL 的响应状态代码。我确信它可能会被清理干净,但它确实有效:

    import json
    from selenium import webdriver
    from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
    
    capabilities = DesiredCapabilities.CHROME
    capabilities['goog:loggingPrefs'] = {'performance': 'ALL'}
    
    driver = webdriver.Chrome(desired_capabilities=capabilities)
    
    
    def get_status_code(url):
        for entry in driver.get_log('performance'):
            for k, v in entry.items():
                if k == 'message' and 'status' in v:
                    msg = json.loads(v)['message']['params']
                    for mk, mv in msg.items():
                        if mk == 'response':
                            response_url = mv['url']
                            response_status = mv['status']
                            if response_url == url:
                                return response_status
    
    
    print(get_status_code(driver.current_url))
    

    输出:

    200

    【讨论】:

      【解决方案2】:
      import json
      from selenium.webdriver.chrome.webdriver import WebDriver
      from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
      
      chromedriver_path = "YOUR/PATH/TO/chromedriver.exe"
      url = "https://selenium-python.readthedocs.io/api.html"
      capabilities = DesiredCapabilities.CHROME.copy()
      capabilities['goog:loggingPrefs'] = {'performance': 'ALL'}
      
      browser = WebDriver(chromedriver_path, desired_capabilities=capabilities)
      
      browser.get(url)
      logs = browser.get_log('performance')
      

      选项1:如果您只是想返回状态码,假设您想要状态码的页面...存在于包含'text/html内容类型的日志中

      def get_status(logs):
          for log in logs:
              if log['message']:
                  d = json.loads(log['message'])
                  try:
                      content_type = 'text/html' in d['message']['params']['response']['headers']['content-type']
                      response_received = d['message']['method'] == 'Network.responseReceived'
                      if content_type and response_received:
                          return d['message']['params']['response']['status']
                  except:
                      pass
      

      用法:

      >>> get_status(logs)
      200
      

      选项 2:如果您想查看相关日志中的所有状态代码

      def get_status_codes(logs):
          statuses = []
          for log in logs:
              if log['message']:
                  d = json.loads(log['message'])
                  if d['message'].get('method') == "Network.responseReceived":
                      statuses.append(d['message']['params']['response']['status'])
          return statuses
      

      用法:

      >>> get_status_codes(logs)
      [200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200]
      

      注意 1:其中大部分是基于 @Stefan Matei 的回答,但是,Chrome 版本之间发生了一些变化,我提供了如何解析日志的想法。

      注 2:['content-type'] 不完全可靠。外壳可以更换。检查您的用例。

      【讨论】:

        【解决方案3】:

        我通过使用请求使用以下技巧来确保服务器首先响应。然后我使用了驱动程序:

        resp = requests.get(link)
        while resp.status_code != 200:
            resp = requests.get(link)
            if resp.status_code == 200:
                break
        
        html = driver.page_source
        
        soup = BeautifulSoup(html)
        

        【讨论】:

          【解决方案4】:

          为了使用 Selenium 从 url 获取状态代码,您可以使用 javascript 和 XMLHttpRequest 对象。 WebDriver 类有一个execute_async_script() 方法,你可以调用它来在浏览器中执行一段javascript代码:

          from selenium import webdriver
          
          driver = webdriver.Chrome(executable_path="C:\ChromeDriver\chromedriver.exe")
          driver.get('https://stackoverflow.com/')
          
          js = '''
          let callback = arguments[0];
          let xhr = new XMLHttpRequest();
          xhr.open('GET', 'https://stackoverflow.com/', true);
          xhr.onload = function () {
              if (this.readyState === 4) {
                  callback(this.status);
              }
          };
          xhr.onerror = function () {
              callback('error');
          };
          xhr.send(null);
          '''
          
          status_code = driver.execute_async_script(js)
          print(status_code)    # 200
          
          driver.close()
          

          有关execute_async_script 方法的更多信息。

          【讨论】:

          • GET 方法似乎不错。但是有什么方法可以在使用 POST 方法的页面中检查表单提交的响应代码吗?
          【解决方案5】:

          您可以从标题中获取状态码

          例如,来自 nginx 的 403 Forbidden response。

          <html>
              <head>
                  <title>403 Forbidden</title>
              </head>
              <body></body>
          </html>
          

          硒代码:

          text = driver.find_element_by_tag_name('title').text
          if '403 Forbidden' in text:
              print('[INFO] status code is 403')
          

          当然,这个决定并不涵盖所有情况。

          【讨论】:

            【解决方案6】:

            您还可以检查日志中的最后一条消息以获取错误状态代码: print browser.get_log('browser')[-1]['message']

            【讨论】:

              【解决方案7】:

              似乎可以通过API从日志中获取响应状态码。

              from selenium import webdriver
              import json
              browser = webdriver.PhantomJS()
              browser.get('http://www.google.fr')
              har = json.loads(browser.get_log('har')[0]['message'])
              har['log']['entries'][0]['response']['status']
              har['log']['entries'][0]['response']['statusText']
              

              【讨论】:

              • 浏览器是否有任何关于“日志”的特定内容,或者该代码是否适用于所有浏览器?
              • 我只用 PhantomJS 测试过。我不了解 IE,但我认为 Chrome 应该可以。
              • 我收到了selenium.common.exceptions.WebDriverException: Message: unknown error: log type 'har' not found
              • @etayluz 这意味着har 不是你定义的。你可以通过capabilities['loggingPrefs'] = {'har': 'ALL'} 来添加它。 :-)
              • @atb00ker 您将如何以及在代码中的何处放置capabilities['loggingPrefs'] = {'har': 'ALL'}
              【解决方案8】:

              我已经在网上冲浪了大约 3 个小时,但我发现没有一种方法可以使用 web-driver 来做到这一点。我从来没有直接使用过硒。我想到的唯一建议是像这样使用模块“请求”:

              import requests
              from selenium import webdriver
              
              driver = webdriver.get("url")
              r = requests.get("url")
              print r.status_code
              

              关于使用请求的完整教程是here,您可以使用命令pip install requests安装模块。

              但是有一个问题可能并不总是发生,但是你应该关注驱动的响应和请求的响应是不一样的;所以你只是得到请求的状态码,如果 url 响应不稳定,它可能会导致错误的结果。

              【讨论】:

              • 太有问题了。除了所有这些问题之外,您 GET 请求两次,此外,如果您计划使用 Selenium GET 或 POST url,则不能使用它。
              • 感谢您的精彩回答。 pypi.python.org/pypi/selenium-requests 也做同样的事情。
              • 很遗憾,有些网站会对这些不同的模块给出不同的响应码。需要注意的事情(如果您依赖 Selenium 中使用的状态代码请求,请尝试用户代理欺骗)
              • 其实用HTTP请求判断URL是否有效是个好主意。
              • 当一个页面阻止直接请求并且只允许通过浏览器加载页面时,你会得到 403,所以在这种情况下没有帮助
              【解决方案9】:

              我对python没有太多经验。我这里有一个更详细的 java 示例:

              https://stackoverflow.com/a/39979509/5703420

              这个想法是启用性能日志记录。这会在 chromedriver 上触发“Network.enable”。然后获取性能日志条目并解析它们以获取“Network.responseReceived”消息。

                  from selenium import webdriver
              
                  from selenium.webdriver.common.desired_capabilities import DesiredCapabilities    
                  # enable browser logging
                  d = DesiredCapabilities.CHROME
                  d['loggingPrefs'] = { 'performance':'ALL' }
              
                  driver = webdriver.Chrome(executable_path="c:\\windows\\chromedriver.exe", service_args=["--verbose", "--log-path=D:\\temp3\\chromedriverxx.log"], desired_capabilities=d)
              
                  driver.get('https://api.ipify.org/?format=text')
              
                  print(driver.title)
              
                  print(driver.page_source)
              
                  performance_log = driver.get_log('performance')
                  print (str(performance_log).strip('[]'))
              
                  for entry in driver.get_log('performance'):
                      print (entry)
              

              输出将包含您的网址的“Network.responseReceived”、页面加载完成的其他请求或重定向网址。您所要做的就是解析日志条目。

              '{"message":{"method":"Network.responseReceived","params":{"frameId":"9488.1","loaderId":"9488.1","requestId":"9488.1","response":{"connectionId":14,"connectionReused":false,"encodedDataLength":-1,"fromDiskCache":false,"fromServiceWorker":false,"headers":{"Connection":"keep-alive","Content-Length":"13","Content-Type":"text/plain","Date":"Wed, 12 Oct 2016 06:15:47 GMT","Server":"Cowboy","Via":"1.1 vegur"},"headersText":"HTTP/1.1 200 OK\\r\\nServer: Cowboy\\r\\nConnection: keep-alive\\r\\nContent-Type: text/plain\\r\\nDate: Wed, 12 Oct 2016 06:15:47 GMT\\r\\nContent-Length:13\\r\\nVia:1.1vegur\\r\\n\\r\\n","mimeType":"text/plain","protocol":"http/1.1","remoteIPAddress":"54.197.246.207","remotePort":443,"requestHeaders":{"Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8","Accept-Encoding":"gzip, deflate, sdch, br","Accept-Language":"en-GB,en-US;q=0.8,en;q=0.6","Connection":"keep-alive","Host":"api.ipify.org","Upgrade-Insecure-Requests":"1","User-Agent":"Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36"},"requestHeadersText":"GET /?format=text HTTP/1.1\\r\\nHost: api.ipify.org\\r\\nConnection: keep-alive\\r\\nUpgrade-Insecure-Requests: 1\\r\\nUser-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36\\r\\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\\r\\nAccept-Encoding: gzip, deflate, sdch, br\\r\\nAccept-Language: en-GB,en-US;q=0.8,en;q=0.6\\r\\n\\r\\n","securityDetails":{"certificateId":1,"certificateValidationDetails":{"numInvalidScts":0,"numUnknownScts":0,"numValidScts":0},"cipher":"AES_128_GCM","keyExchange":"ECDHE_RSA","protocol":"TLS 1.2","signedCertificateTimestampList":[]},"securityState":"secure","status":200,"statusText":"OK","timing":{"connectEnd":320.508999997401,"connectStart":3.08100000256673,"dnsEnd":3.08100000256673,"dnsStart":0,"proxyEnd":-1,"proxyStart":-1,"pushEnd":0,"pushStart":0,"receiveHeadersEnd":465.725000001839,"requestTime":78246.775045,"sendEnd":320.995999994921,"sendStart":320.825999995577,"sslEnd":320.435000001453,"sslStart":141.675999999279,"workerReady":-1,"workerStart":-1},"url":"https://api.ipify.org/?format=text"},"timestamp":78247.242716,"type":"Document"}},"webview":"6e8a3b1d-e5aa-40fb-a695-280cbb0ee420"}'}, {'timestamp': 1476252948094, 'level': 'INFO', 'message': '{"message":{"method":"Network.dataReceived","params":{"dataLength":13,"encodedDataLength":171,"requestId":"9488.1","timestamp":78247.243137}},"webview":"6e8a3b1d-e5aa-40fb-a695-280cbb0ee420"}'}, {'timestamp': 1476252948094, 'level': 'INFO', 'message': '{"message":{"method":"Page.frameNavigated","params":{"frame":{"id":"9488.1","loaderId":"9488.1","mimeType":"text/plain","securityOrigin":"https://api.ipify.org","url":"https://api.ipify.org/?format=text"}}},"webview":"6e8a3b1d-e5aa-40fb-a695-280cbb0ee420"}'}, {'timestamp': 1476252948095, 'level': 'INFO', 'message': '{"message":{"method":"Network.loadingFinished","params":{"encodedDataLength":171,"requestId":"9488.1","timestamp":78247.242066}},"webview":"6e8a3b1d-e5aa-40fb-a695-280cbb0ee420"}'}, {'timestamp': 1476252948115, 'level': 'INFO', 'message': '{"message":{"method":"Page.loadEventFired","params":{"timestamp":78247.264169}},"webview":"6e8a3b1d-e5aa-40fb-a695-280cbb0ee420"}'}, {'timestamp': 1476252948115, 'level': 'INFO', 'message': '{"message":{"method":"Page.frameStoppedLoading","params":{"frameId":"9488.1"}},"webview":"6e8a3b1d-e5aa-40fb-a695-280cbb0ee420"}'}, {'timestamp': 147625298116, 'level': 'INFO', 'message': '{"message":{"method":"Page.domContentEventFired","params":{"timestamp":78247.276475}},"webview":"6e8a3b1d-e5aa-40fb-a695-280cbb0ee420"}'}, {'timestamp': 1476252948122, 'level': 'INFO', 'message': '{"message":{"method":"Network.requestWillBeSent","params":{"documentURL":"https://api.ipify.org/?format=text","frameId":"9488.1","initiator":{"type":"other"},"loaderId":"9488.1","request":{"headers":{"Referer":"https://api.ipify.org/?format=text","User-Agent":"Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36"},"initialPriority":"High","method":"GET","mixedContentType":"none","url":"https://api.ipify.org/favicon.ico"},"requestId":"9488.2","timestamp":78247.280131,"type":"Other","wallTime":1476252948.11805}},"webview":"6e8a3b1d-e5aa-40fb-a695-280cbb0ee420"}'}
              

              并从 json 响应中获取 "status":200。您还可以解析响应“标头”。

              【讨论】:

              • 在 mac 上获取错误:selenium.common.exceptions.WebDriverException: Message: POST /session/4fd2b36a-6c9a-e34d-8e9a-022424c7f36f/log did not match a known command
              • @user305883 它仅适用于 Chrome。通常在使用其他浏览器(如 Firefox)时会抛出此错误。对于 Firefox,您必须转储一个日志文件,然后解析它 java example
              • 这在 Chrome todavy 中不起作用,至少在 perl 中是这样。说这不是 W3C 命令。
              【解决方案10】:

              这是不可能的。

              很遗憾,Selenium 并非有意提供此信息。对此有a very lengthy 的讨论,但不足之处在于:

              1. Selenium 是一种浏览器仿真工具,不一定是测试工具。
              2. Selenium 在呈现页面并为其添加接口的过程中执行许多 GET 和 POST,这会使 API 变得复杂,作者反对。

              我们留下了类似的黑客:

              1. 在返回的 HTML 中查找错误信息。
              2. 请改用其他工具,例如 Requests(但请在 @Zeinab 的回答中查看该方法的缺点。

              【讨论】:

              【解决方案11】:

              我将向您推荐我之前提出的一个问题:How to detect when Selenium loads a browser's error page

              简而言之,除非您想通过 squid 代理或 browsermob 之类的东西获得超级喜欢,否则您必须采用如下所示的肮脏解决方案。

              替换

              driver.get( "http://google.com" )
              

              def goTo( url ):
                  if "errorPageContainer" in [ elem.get_attribute("id") for elem in driver.find_elements_by_css_selector("body > div") ]:
                      raise Exception( "this page is an error" )
                  else:
                      driver.get( url )
              

              您可以根据实际浏览器中显示的文字进行创意并获取错误代码。这必须根据浏览器进行定制;上面的一个适用于Firefox。

              这成为问题的唯一方法是 404(找不到页面),因为许多网站都有自己的错误页面,您必须为每个页面自定义它。

              【讨论】:

                【解决方案12】:

                我在这里使用 java,因为我在 Python 方面没有太多经验。另外,我不知道如何仅获取 http 状态代码。以下将为您提供整个网络流量,您可以从中捕获状态代码。

                首先启动你的服务器

                selenium.start("captureNetworkTraffic=true");
                

                然后将您的流量捕获为

                String traffic = selenium.captureNetworkTraffic("xml");
                

                你也可以得到 json 格式的输出。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2021-09-30
                  • 2011-02-26
                  • 2018-10-28
                  • 2020-01-10
                  • 1970-01-01
                  • 1970-01-01
                  • 2022-06-23
                  • 2017-01-22
                  相关资源
                  最近更新 更多