Cách lấy Mã phản hồi HTTP bằng Selenium WebDriver


109

Tôi đã viết các bài kiểm tra với Selenium2 / WebDriver và muốn kiểm tra xem HTTP Request có trả về HTTP 403 Forbidden hay không.

Có thể nhận mã trạng thái phản hồi HTTP với Selenium WebDriver không?



Đây không phải là bản sao, bởi vì câu hỏi khác tập trung vào Python, nhưng câu hỏi này là trong java,
Ralph.

1
Cảm ơn tôi đã nhận nó. Nhưng cuối cùng là câu hỏi kết thúc trên webdrivergiới hạn 's, và những hạn chế này là như nhau cho cả hai Python và Java;)
maxkoryukov

2
@maxkoryukov: nhưng có những cách giải quyết phụ thuộc vào ngôn ngữ,
Ralph

Câu trả lời:


66

Nói tóm lại, không. Không thể sử dụng API Selenium WebDriver. Điều này đã được thảo luận về ad nauseam trong trình theo dõi vấn đề cho dự án và tính năng này sẽ không được thêm vào API.


42

Có thể lấy mã phản hồi của một yêu cầu http bằng Selenium và Chrome hoặc Firefox. Tất cả những gì bạn phải làm là khởi động Chrome hoặc Firefox ở chế độ ghi nhật ký. Tôi sẽ chỉ cho bạn một số ví dụ dưới đây.

java + Selenium + Chrome Đây là một ví dụ về java + Selenium + Chrome, nhưng tôi đoán rằng nó có thể được thực hiện bằng bất kỳ ngôn ngữ nào (python, c #, ...).

Tất cả những gì bạn cần làm là ra lệnh cho chromedriver thực hiện "Network.enable". Điều này có thể được thực hiện bằng cách bật Ghi nhật ký hiệu suất.

LoggingPreferences logPrefs = new LoggingPreferences();
logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
cap.setCapability(CapabilityType.LOGGING_PREFS, logPrefs);

Sau khi yêu cầu được thực hiện, tất cả những gì bạn phải làm là lấy và lặp lại các bản ghi Perfomance và tìm "Network.responseReceive" cho url được yêu cầu:

LogEntries logs = driver.manage().logs().get("performance");

Đây là mã:

import java.util.Iterator;
import java.util.logging.Level;

import org.json.JSONException;
import org.json.JSONObject;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;

public class TestResponseCode
{
    public static void main(String[] args)
    {
        // simple page (without many resources so that the output is
        // easy to understand
        String url = "http://www.york.ac.uk/teaching/cws/wws/webpage1.html";

        DownloadPage(url);
    }

    private static void DownloadPage(String url)
    {
        ChromeDriver driver = null;

        try
        {
            ChromeOptions options = new ChromeOptions();
            // add whatever extensions you need
            // for example I needed one of adding proxy, and one for blocking
            // images
            // options.addExtensions(new File(file, "proxy.zip"));
            // options.addExtensions(new File("extensions",
            // "Block-image_v1.1.crx"));

            DesiredCapabilities cap = DesiredCapabilities.chrome();
            cap.setCapability(ChromeOptions.CAPABILITY, options);

            // set performance logger
            // this sends Network.enable to chromedriver
            LoggingPreferences logPrefs = new LoggingPreferences();
            logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
            cap.setCapability(CapabilityType.LOGGING_PREFS, logPrefs);

            driver = new ChromeDriver(cap);

            // navigate to the page
            System.out.println("Navigate to " + url);
            driver.navigate().to(url);

            // and capture the last recorded url (it may be a redirect, or the
            // original url)
            String currentURL = driver.getCurrentUrl();

            // then ask for all the performance logs from this request
            // one of them will contain the Network.responseReceived method
            // and we shall find the "last recorded url" response
            LogEntries logs = driver.manage().logs().get("performance");

            int status = -1;

            System.out.println("\nList of log entries:\n");

            for (Iterator<LogEntry> it = logs.iterator(); it.hasNext();)
            {
                LogEntry entry = it.next();

                try
                {
                    JSONObject json = new JSONObject(entry.getMessage());

                    System.out.println(json.toString());

                    JSONObject message = json.getJSONObject("message");
                    String method = message.getString("method");

                    if (method != null
                            && "Network.responseReceived".equals(method))
                    {
                        JSONObject params = message.getJSONObject("params");

                        JSONObject response = params.getJSONObject("response");
                        String messageUrl = response.getString("url");

                        if (currentURL.equals(messageUrl))
                        {
                            status = response.getInt("status");

                            System.out.println(
                                    "---------- bingo !!!!!!!!!!!!!! returned response for "
                                            + messageUrl + ": " + status);

                            System.out.println(
                                    "---------- bingo !!!!!!!!!!!!!! headers: "
                                            + response.get("headers"));
                        }
                    }
                } catch (JSONException e)
                {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

            System.out.println("\nstatus code: " + status);
        } finally
        {
            if (driver != null)
            {
                driver.quit();
            }
        }
    }
}

Đầu ra trông như thế này:

    Navigate to http://www.york.ac.uk/teaching/cws/wws/webpage1.html

    List of log entries:

    {"webview":"3b8eaedb-bd0f-4baa-938d-4aee4039abfe","message":{"method":"Page.frameAttached","params":{"parentFrameId":"172.1","frameId":"172.2"}}}
    {"webview":"3b8eaedb-bd0f-4baa-938d-4aee4039abfe","message":{"method":"Page.frameStartedLoading","params":{"frameId":"172.2"}}}
    {"webview":"3b8eaedb-bd0f-4baa-938d-4aee4039abfe","message":{"method":"Page.frameNavigated","params":{"frame":{"securityOrigin":"://","loaderId":"172.1","name":"chromedriver dummy frame","id":"172.2","mimeType":"text/html","parentId":"172.1","url":"about:blank"}}}}
    {"webview":"3b8eaedb-bd0f-4baa-938d-4aee4039abfe","message":{"method":"Page.frameStoppedLoading","params":{"frameId":"172.2"}}}
    {"webview":"3b8eaedb-bd0f-4baa-938d-4aee4039abfe","message":{"method":"Page.frameStartedLoading","params":{"frameId":"3928.1"}}}
    {"webview":"3b8eaedb-bd0f-4baa-938d-4aee4039abfe","message":{"method":"Network.requestWillBeSent","params":{"request":{"headers":{"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"},"initialPriority":"VeryHigh","method":"GET","mixedContentType":"none","url":"http://www.york.ac.uk/teaching/cws/wws/webpage1.html"},"frameId":"3928.1","requestId":"3928.1","documentURL":"http://www.york.ac.uk/teaching/cws/wws/webpage1.html","initiator":{"type":"other"},"loaderId":"3928.1","wallTime":1.47619492749007E9,"type":"Document","timestamp":20226.652971}}}
    {"webview":"3b8eaedb-bd0f-4baa-938d-4aee4039abfe","message":{"method":"Network.responseReceived","params":{"frameId":"3928.1","requestId":"3928.1","response":{"headers":{"Accept-Ranges":"bytes","Keep-Alive":"timeout=4, max=100","Cache-Control":"max-age=300","Server":"Apache/2.2.22 (Ubuntu)","Connection":"Keep-Alive","Content-Encoding":"gzip","Vary":"Accept-Encoding","Expires":"Tue, 11 Oct 2016 14:13:47 GMT","Content-Length":"1957","Date":"Tue, 11 Oct 2016 14:08:47 GMT","Content-Type":"text/html"},"connectionReused":false,"timing":{"pushEnd":0,"workerStart":-1,"proxyEnd":-1,"workerReady":-1,"sslEnd":-1,"pushStart":0,"requestTime":20226.65335,"sslStart":-1,"dnsStart":0,"sendEnd":31.6569999995409,"connectEnd":31.4990000006219,"connectStart":0,"sendStart":31.5860000009707,"dnsEnd":0,"receiveHeadersEnd":115.645999998378,"proxyStart":-1},"encodedDataLength":-1,"remotePort":80,"mimeType":"text/html","headersText":"HTTP/1.1 200 OK\r\nDate: Tue, 11 Oct 2016 14:08:47 GMT\r\nServer: Apache/2.2.22 (Ubuntu)\r\nAccept-Ranges: bytes\r\nCache-Control: max-age=300\r\nExpires: Tue, 11 Oct 2016 14:13:47 GMT\r\nVary: Accept-Encoding\r\nContent-Encoding: gzip\r\nContent-Length: 1957\r\nKeep-Alive: timeout=4, max=100\r\nConnection: Keep-Alive\r\nContent-Type: text/html\r\n\r\n","securityState":"neutral","requestHeadersText":"GET /teaching/cws/wws/webpage1.html HTTP/1.1\r\nHost: www.york.ac.uk\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\r\nAccept-Language: en-GB,en-US;q=0.8,en;q=0.6\r\n\r\n","url":"http://www.york.ac.uk/teaching/cws/wws/webpage1.html","protocol":"http/1.1","fromDiskCache":false,"fromServiceWorker":false,"requestHeaders":{"Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8","Upgrade-Insecure-Requests":"1","Connection":"keep-alive","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","Host":"www.york.ac.uk","Accept-Encoding":"gzip, deflate, sdch","Accept-Language":"en-GB,en-US;q=0.8,en;q=0.6"},"remoteIPAddress":"144.32.128.84","statusText":"OK","connectionId":11,"status":200},"loaderId":"3928.1","type":"Document","timestamp":20226.770012}}}
    ---------- bingo !!!!!!!!!!!!!! returned response for http://www.york.ac.uk/teaching/cws/wws/webpage1.html: 200
    ---------- bingo !!!!!!!!!!!!!! headers: {"Accept-Ranges":"bytes","Keep-Alive":"timeout=4, max=100","Cache-Control":"max-age=300","Server":"Apache/2.2.22 (Ubuntu)","Connection":"Keep-Alive","Content-Encoding":"gzip","Vary":"Accept-Encoding","Expires":"Tue, 11 Oct 2016 14:13:47 GMT","Content-Length":"1957","Date":"Tue, 11 Oct 2016 14:08:47 GMT","Content-Type":"text/html"}
    {"webview":"3b8eaedb-bd0f-4baa-938d-4aee4039abfe","message":{"method":"Network.dataReceived","params":{"dataLength":2111,"requestId":"3928.1","encodedDataLength":1460,"timestamp":20226.770425}}}
    {"webview":"3b8eaedb-bd0f-4baa-938d-4aee4039abfe","message":{"method":"Page.frameNavigated","params":{"frame":{"securityOrigin":"http://www.york.ac.uk","loaderId":"3928.1","id":"3928.1","mimeType":"text/html","url":"http://www.york.ac.uk/teaching/cws/wws/webpage1.html"}}}}
    {"webview":"3b8eaedb-bd0f-4baa-938d-4aee4039abfe","message":{"method":"Network.dataReceived","params":{"dataLength":1943,"requestId":"3928.1","encodedDataLength":825,"timestamp":20226.782673}}}
    {"webview":"3b8eaedb-bd0f-4baa-938d-4aee4039abfe","message":{"method":"Network.loadingFinished","params":{"requestId":"3928.1","encodedDataLength":2285,"timestamp":20226.770199}}}
    {"webview":"3b8eaedb-bd0f-4baa-938d-4aee4039abfe","message":{"method":"Page.loadEventFired","params":{"timestamp":20226.799391}}}
    {"webview":"3b8eaedb-bd0f-4baa-938d-4aee4039abfe","message":{"method":"Page.frameStoppedLoading","params":{"frameId":"3928.1"}}}
    {"webview":"3b8eaedb-bd0f-4baa-938d-4aee4039abfe","message":{"method":"Page.domContentEventFired","params":{"timestamp":20226.845769}}}
    {"webview":"3b8eaedb-bd0f-4baa-938d-4aee4039abfe","message":{"method":"Network.requestWillBeSent","params":{"request":{"headers":{"Referer":"http://www.york.ac.uk/teaching/cws/wws/webpage1.html","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":"http://www.york.ac.uk/favicon.ico"},"frameId":"3928.1","requestId":"3928.2","documentURL":"http://www.york.ac.uk/teaching/cws/wws/webpage1.html","initiator":{"type":"other"},"loaderId":"3928.1","wallTime":1.47619492768527E9,"type":"Other","timestamp":20226.848174}}}

    status code: 200

java + Selenium + Firefox Cuối cùng tôi cũng đã tìm thấy thủ thuật cho Firefox. Bạn cần bắt đầu sử dụng firefox MOZ_LOGMOZ_LOG_FILEcác biến môi trường, đồng thời ghi nhật ký các yêu cầu http ở mức gỡ lỗi (4 = PR_LOG_DEBUG) - map.put("MOZ_LOG", "timestamp,sync,nsHttp:4"). Lưu nhật ký vào một tệp tạm thời. Sau đó, lấy nội dung của tệp nhật ký đã lưu và phân tích cú pháp nó cho mã phản hồi (sử dụng một số biểu thức chính quy đơn giản). Trước tiên, hãy phát hiện điểm bắt đầu của yêu cầu, xác định id của nó (nsHttpChannel::BeginConnect [this=000000CED8094000]), sau đó ở bước thứ hai, tìm mã phản hồi cho id yêu cầu đó (nsHttpChannel::ProcessResponse [this=000000CED8094000 httpStatus=200]).

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.io.FileUtils;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.GeckoDriverService;

public class TestFirefoxResponse
{
  public static void main(String[] args)
      throws InterruptedException, IOException
  {
    GeckoDriverService service = null;

    // tell firefox to log http requests
    // at level 4 = PR_LOG_DEBUG: debug messages, notices
    // you could log everything at level 5, but the log file will 
    // be larger. 
    // create a temporary log file that will be parsed for
    // response code
    Map<String, String> map = new HashMap<String, String>();
    map.put("MOZ_LOG", "timestamp,sync,nsHttp:4");
    File tempFile = File.createTempFile("mozLog", ".txt");    
    map.put("MOZ_LOG_FILE", tempFile.getAbsolutePath());      

    GeckoDriverService.Builder builder = new GeckoDriverService.Builder();
    service = builder.usingAnyFreePort()
      .withEnvironment(map)
      .build();

    service.start();      

    WebDriver driver = new FirefoxDriver(service);

    // test 200
     String url = "https://api.ipify.org/?format=text";
    // test 404
    // String url = "https://www.advancedwebranking.com/lsdkjflksdjfldksfj";
    driver.get(url);

    driver.quit();

    String logContent = FileUtils.readFileToString(tempFile);

    ParseLog(logContent, url);
  }

  private static void ParseLog(String logContent, String url) throws MalformedURLException
  {
    // this is how the log looks like when the request starts
    // I have to get the id of the request using a regular expression
    // and use that id later to get the response
    //
    //    2017-11-02 14:14:01.170000 UTC - [Main Thread]: D/nsHttp nsHttpChannel::BeginConnect [this=000000BFF27A5000]
    //    2017-11-02 14:14:01.170000 UTC - [Main Thread]: D/nsHttp host=api.ipify.org port=-1
    //    2017-11-02 14:14:01.170000 UTC - [Main Thread]: D/nsHttp uri=https://api.ipify.org/?format=text
    String pattern = "BeginConnect \\[this=(.*?)\\](?:.*?)uri=(.*?)\\s";

    Pattern p = Pattern.compile(pattern, Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
    Matcher m = p.matcher(logContent);

    String urlID = null;
    while (m.find())
    {
      String id = m.group(1);
      String uri = m.group(2);

      if (uri.equals(url))
      {
        urlID = id;
        break;
      }      
    }

    System.out.println("request id = " + urlID);

    // this is how the response looks like in the log file
    // ProcessResponse [this=000000CED8094000 httpStatus=200]
    // I will use another regular espression to get the httpStatus
    //
    //    2017-11-02 14:45:39.296000 UTC - [Main Thread]: D/nsHttp nsHttpChannel::OnStartRequest [this=000000CED8094000 request=000000CED8014BB0 status=0]
    //    2017-11-02 14:45:39.296000 UTC - [Main Thread]: D/nsHttp nsHttpChannel::ProcessResponse [this=000000CED8094000 httpStatus=200]    

    pattern = "ProcessResponse \\[this=" + urlID + " httpStatus=(.*?)\\]";

    p = Pattern.compile(pattern, Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
    m = p.matcher(logContent);

    if (m.find())
    {
      String responseCode = m.group(1);
      System.out.println("response code found " + responseCode);
    }
    else
    {
      System.out.println("response code not found");
    }
  }
}

Đầu ra cho điều này sẽ là

yêu cầu id = 0000007653D67000 mã phản hồi được tìm thấy 200

Các tiêu đề phản hồi cũng có thể được tìm thấy trong tệp nhật ký. Bạn có thể lấy chúng nếu bạn muốn.

    2017-11-02 14:54:36.775000 UTC - [Socket Thread]: I/nsHttp http response [
    2017-11-02 14:54:36.775000 UTC - [Socket Thread]: I/nsHttp   HTTP/1.1 404 Not Found
    2017-11-02 14:54:36.775000 UTC - [Socket Thread]: I/nsHttp   Accept-Ranges: bytes
    2017-11-02 14:54:36.775000 UTC - [Socket Thread]: I/nsHttp   Cache-control: no-cache="set-cookie"
    2017-11-02 14:54:36.775000 UTC - [Socket Thread]: I/nsHttp   Content-Type: text/html; charset=utf-8
    2017-11-02 14:54:36.775000 UTC - [Socket Thread]: I/nsHttp   Date: Thu, 02 Nov 2017 14:54:36 GMT
    2017-11-02 14:54:36.775000 UTC - [Socket Thread]: I/nsHttp   ETag: "7969-55bc076a61e80"
    2017-11-02 14:54:36.775000 UTC - [Socket Thread]: I/nsHttp   Last-Modified: Tue, 17 Oct 2017 16:17:46 GMT
    2017-11-02 14:54:36.775000 UTC - [Socket Thread]: I/nsHttp   Server: Apache/2.4.23 (Amazon) PHP/5.6.24
    2017-11-02 14:54:36.775000 UTC - [Socket Thread]: I/nsHttp   Set-Cookie: AWSELB=5F256FFA816C8E72E13AE0B12A17A3D540582F804C87C5FEE323AF3C9B638FD6260FF473FF64E44926DD26221AAD2E9727FD739483E7E4C31784C7A495796B416146EE83;PATH=/
    2017-11-02 14:54:36.775000 UTC - [Socket Thread]: I/nsHttp   Content-Length: 31081
    2017-11-02 14:54:36.775000 UTC - [Socket Thread]: I/nsHttp   Connection: keep-alive
    2017-11-02 14:54:36.775000 UTC - [Socket Thread]: I/nsHttp     OriginalHeaders
    2017-11-02 14:54:36.775000 UTC - [Socket Thread]: I/nsHttp   Accept-Ranges: bytes
    2017-11-02 14:54:36.775000 UTC - [Socket Thread]: I/nsHttp   Cache-control: no-cache="set-cookie"
    2017-11-02 14:54:36.775000 UTC - [Socket Thread]: I/nsHttp   Content-Type: text/html; charset=utf-8
    2017-11-02 14:54:36.775000 UTC - [Socket Thread]: I/nsHttp   Date: Thu, 02 Nov 2017 14:54:36 GMT
    2017-11-02 14:54:36.775000 UTC - [Socket Thread]: I/nsHttp   ETag: "7969-55bc076a61e80"
    2017-11-02 14:54:36.775000 UTC - [Socket Thread]: I/nsHttp   Last-Modified: Tue, 17 Oct 2017 16:17:46 GMT
    2017-11-02 14:54:36.775000 UTC - [Socket Thread]: I/nsHttp   Server: Apache/2.4.23 (Amazon) PHP/5.6.24
    2017-11-02 14:54:36.775000 UTC - [Socket Thread]: I/nsHttp   Set-Cookie: AWSELB=5F256FFA816C8E72E13AE0B12A17A3D540582F804C87C5FEE323AF3C9B638FD6260FF473FF64E44926DD26221AAD2E9727FD739483E7E4C31784C7A495796B416146EE83;PATH=/
    2017-11-02 14:54:36.775000 UTC - [Socket Thread]: I/nsHttp   Content-Length: 31081
    2017-11-02 14:54:36.775000 UTC - [Socket Thread]: I/nsHttp   Connection: keep-alive
    2017-11-02 14:54:36.775000 UTC - [Socket Thread]: I/nsHttp ]
    2017-11-02 14:54:36.775000 UTC - [Main Thread]: D/nsHttp nsHttpChannel::OnStartRequest [this=0000008A65D85000 request=0000008A65D1F900 status=0]
    2017-11-02 14:54:36.775000 UTC - [Main Thread]: D/nsHttp nsHttpChannel::ProcessResponse [this=0000008A65D85000 httpStatus=404]

2
Đối với những người đang xem xét vấn đề này, hãy lưu ý rằng network.enable của chromium sẽ chèn thêm một tiêu đề vào mỗi yêu cầu HTTP được thực hiện khi nó được bật.
Tên giả

2
Xin chào, tôi có thể nhận mã phản hồi, nhưng làm cách nào để lấy nội dung phản hồi? Tôi không thấy nó trong JSONObject phản hồi.
LINGS

@LINGS bạn có thể sử dụng driver.getPageSource (), nhưng hãy cẩn thận vì thường có một số yêu cầu javascript bên có thể thay đổi Dom. Bạn có thể đợi một số phần tử của trang của bạn hiện diện trong dom và sau đó lấy nguồn trang. Một kịch bản khác là với các khung. Nếu bạn có khung, bạn phải chuyển sang khung, sau đó lấy mã nguồn của khung đó - driver.switchTo (). Frame ();
Stefan Matei

Tôi đã cố gắng triển khai mã của bạn bằng RemoteWebDriver , vì các phương pháp của tôi được viết bằng RemoteWebdriver. bạn có ý kiến ​​gì về cách sử dụng nó với RemoteWebDriver không?
M3trix

2
@IvayloSlavov Tập lệnh Chrome hoạt động với tôi với 4.0.0-alpha-4, vui lòng xem ví dụ này github.com/smatei/SeleniumChromeHTTPResponse
Stefan Matei

16

Bạn có thể sử dụng proxy BrowserMob để nắm bắt các yêu cầu và phản hồi bằng một HttpRequestInterceptor. Đây là một ví dụ trong Java:

// Start the BrowserMob proxy
ProxyServer server = new ProxyServer(9978);
server.start();

server.addResponseInterceptor(new HttpResponseInterceptor()
{
    @Override
    public void process(HttpResponse response, HttpContext context)
        throws HttpException, IOException
    {
        System.out.println(response.getStatusLine());
    }
});

// Get selenium proxy
Proxy proxy = server.seleniumProxy();

// Configure desired capability for using proxy server with WebDriver
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(CapabilityType.PROXY, proxy);

// Set up driver
WebDriver driver = new FirefoxDriver(capabilities);

driver.get("http://stackoverflow.com/questions/6509628/webdriver-get-http-response-code");

// Close the browser
driver.quit();

Tôi đang sử dụng giải pháp của bạn nhưng với proxy, trang tải rất chậm. Bất kỳ ý tưởng làm thế nào nó đến? xem thêm câu hỏi của tôi: stackoverflow.com/questions/21043928/…
Charlie

1
Proxy BrowserMob ban đầu hiện không được hỗ trợ và bị mục nát. Chúng tôi có một nhánh mã nguồn mở của proxymob trình duyệt cũng có xác nhận hiệu suất, trang và mạng được tích hợp sẵn. github.com/browserup/browserup-proxy
ebeland 30-07-19

13

Đối với những người sử dụng Python, bạn có thể xem xét Selenium Wire , một thư viện mà tôi đã phát triển để kiểm tra các yêu cầu do trình duyệt đưa ra trong quá trình thử nghiệm.

Bạn có quyền truy cập vào các yêu cầu thông qua driver.requeststhuộc tính:

from seleniumwire import webdriver  # Import from seleniumwire

# Create a new instance of the Firefox driver
driver = webdriver.Firefox()

# Go to the Google home page
driver.get('https://www.google.com')

# Access requests via the `requests` attribute
for request in driver.requests:
    if request.response:
        print(
            request.url,
            request.response.status_code,
            request.response.headers['Content-Type']
        )

Bản in:

https://www.google.com/ 200 text/html; charset=UTF-8
https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_120x44dp.png 200 image/png
https://consent.google.com/status?continue=https://www.google.com&pc=s&timestamp=1531511954&gl=GB 204 text/html; charset=utf-8
https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png 200 image/png
https://ssl.gstatic.com/gb/images/i2_2ec824b0.png 200 image/png
https://www.google.com/gen_204?s=webaft&t=aft&atyp=csi&ei=kgRJW7DBONKTlwTK77wQ&rt=wsrt.366,aft.58,prt.58 204 text/html; charset=UTF-8
...

Thư viện cung cấp cho bạn khả năng truy cập tiêu đề, mã trạng thái, nội dung phần nội dung, cũng như khả năng sửa đổi tiêu đề và viết lại URL.


Tôi đang thử sử dụng cái này với webdriver.Remote nhưng tôi nhận được "AttributeError: Đối tượng 'WebDriver' không có thuộc tính 'yêu cầu'" Điều này có phải do trình điều khiển từ xa không được selenium-wire hỗ trợ? Tài liệu chính thức đang thiếu một cách vô vọng. Cảm ơn!
Lennart Rolland

@LennartRolland một trong những hạn chế của Selenium Wire là nó sẽ chỉ hoạt động trên cùng một máy chạy trình duyệt. Sử dụng thiết lập từ xa hiện không được hỗ trợ.
Will Keeling

1
@MohamedImran nếu bạn quan tâm đến một phản hồi cụ thể thì bạn có thể sử dụng driver.wait_for_request()phương pháp này để xác định yêu cầu có phản hồi mà bạn quan tâm. Xem tài liệu để biết thêm thông tin.
Will Keeling

1
@MohamedImran phương thức này có regex, vì vậy bạn có thể chỉ chuyển một phần của URL khớp duy nhất. Ví dụ: để phù hợp với http://myserver.com/some/path/12345/bạn có thể vượt quadriver.wait_for_request(‘.*/12345/‘)
Will Keeling

1
@MohamedImran bạn không cần vòng lặp for
Will Keeling

10

Tôi cũng gặp vấn đề tương tự và bị mắc kẹt trong một số ngày, nhưng sau một số nghiên cứu, tôi đã phát hiện ra rằng chúng tôi thực sự có thể sử dụng "--remote-debugging-port" của chrome để chặn các yêu cầu kết hợp với trình điều khiển web selen. Sử dụng Mã giả sau làm tham chiếu: -

tạo phiên bản trình điều khiển chrome với gỡ lỗi từ xa

int freePort = findFreePort();

chromeOptions.addArguments("--remote-debugging-port=" + freePort);

ChromeDriver driver = new ChromeDriver(chromeOptions);`

thực hiện cuộc gọi tới http://127.0.0.1:freePort

String response = makeGetCall( "http://127.0.0.1" + freePort  + "/json" );

Giải nén Url webSocket của chrome để nghe, bạn có thể xem phản hồi và tìm ra cách giải nén

String webSocketUrl = response.substring(response.indexOf("ws://127.0.0.1"), response.length() - 4);

Kết nối với ổ cắm này, bạn có thể sử dụng asyncHttp

socket = maketSocketConnection( webSocketUrl );

Bật chụp mạng

socket.send( { "id" : 1, "method" : "Network.enable" } );

Bây giờ chrome sẽ gửi tất cả các sự kiện liên quan đến mạng và ghi lại chúng như sau

socket.onMessageReceived( String message ){

    Json responseJson = toJson(message);
    if( responseJson.method == "Network.responseReceived" ){
       //extract status code
    }
}

driver.get("http://stackoverflow.com");

bạn có thể làm mọi thứ được đề cập trong trang công cụ dành cho nhà phát triển. xem https://chromedevtools.github.io/devtools-protocol/ Lưu ý: - sử dụng chromedriver 2.39 trở lên.

Tôi hi vọng nó giúp ích cho ai đó.

tham khảo: Sử dụng giao thức gỡ lỗi từ xa của Google Chrome


Thật tuyệt, tôi rất vui vì có một cách để làm điều này! Tôi chỉ ước có một thư viện (đối với Ruby selenium-webdriver, trong trường hợp của tôi) tự động kích hoạt Network.enablevà hiển thị một cách đơn giản để kiểm tra phản hồi cuối cùng ... giống như driver.response.status_code. Có lẽ một ngày nào đó tôi sẽ nhận được xung quanh để thêm rằng ... :)
Tyler Rick

Trong trường hợp bất kỳ lập trình viên Ruby nào khác gặp phải điều này, tôi đã tạo một viên ngọc, github.com/TylerRick/capybara-chrome_response_headers , cho phép bạn dễ dàng lấy mã trạng thái HTTP từ kiểm tra Capybara / RSpec bằng cách gọi đơn giản status_code. Nó sử dụng giao thức gỡ lỗi từ xa của Chrome như trong ví dụ này.
Tyler Rick

cảm ơn anh bạn! làm việc cho tôi chrome 76 + selen 3,141
jessez

9

Lấy mã phản hồi bằng bất kỳ ngôn ngữ nào (Sử dụng JavaScript):

Nếu các bài kiểm tra Selenium của bạn chạy trong một trình duyệt hiện đại, một cách dễ dàng để lấy mã phản hồi là gửi một mã phản hồi XMLHttpRequest* đồng bộ và kiểm tra statusphản hồi:

var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://exampleurl.ex', false);
xhr.send(null);

assert(200, xhr.status);

Bạn có thể sử dụng kỹ thuật này với bất kỳ ngôn ngữ lập trình nào bằng cách yêu cầu Selenium thực thi tập lệnh. Ví dụ, trong Java, bạn có thể sử dụng JavascriptExecutor.executeScript()để gửi XMLHttpRequest:

final String GET_RESPONSE_CODE_SCRIPT =
    "var xhr = new XMLHttpRequest();" +
    "xhr.open('GET', arguments[0], false);" +
    "xhr.send(null);" +
    "return xhr.status";
JavascriptExecutor javascriptExecutor = (JavascriptExecutor) webDriver;
Assert.assertEquals(200,
    javascriptExecutor.executeScript(GET_RESPONSE_CODE_SCRIPT, "http://exampleurl.ex"));

* XMLHttpRequestThay vào đó, bạn có thể gửi một tệp không đồng bộ , nhưng bạn cần phải đợi quá trình này hoàn tất trước khi tiếp tục thử nghiệm của mình.

Lấy mã phản hồi trong Java:

Bạn có thể lấy mã phản hồi trong Java bằng cách sử dụng URL.openConnection()HttpURLConnection.getResponseCode():

URL url = new URL("http://exampleurl.ex");
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestMethod("GET");

// You may need to copy over the cookies that Selenium has in order
// to imitate the Selenium user (for example if you are testing a
// website that requires a sign-in).
Set<Cookie> cookies = webDriver.manage().getCookies();
String cookieString = "";

for (Cookie cookie : cookies) {
    cookieString += cookie.getName() + "=" + cookie.getValue() + ";";
}

httpURLConnection.addRequestProperty("Cookie", cookieString);
Assert.assertEquals(200, httpURLConnection.getResponseCode());

Phương thức này cũng có thể được khái quát hóa cho các ngôn ngữ khác nhưng sẽ cần được sửa đổi để phù hợp với API của ngôn ngữ (hoặc thư viện).


8

Không chắc đây là những gì bạn đang tìm kiếm, nhưng tôi có một mục tiêu khác là kiểm tra xem hình ảnh từ xa có tồn tại hay không và tôi sẽ không gặp lỗi 403, vì vậy bạn có thể sử dụng một cái gì đó như bên dưới:

public static boolean linkExists(String URLName){
    try {
        HttpURLConnection.setFollowRedirects(false);
        HttpURLConnection con = (HttpURLConnection) new URL(URLName).openConnection();
        con.setRequestMethod("HEAD");
        return (con.getResponseCode() == HttpURLConnection.HTTP_OK);
    }
    catch (Exception e) {
        e.printStackTrace();
        return false;
    }
}

4
Tiện dụng cho các trường hợp đơn giản nhưng bạn không có bất kỳ trạng thái trình duyệt nào sử dụng phương pháp này (ví dụ: thông tin đăng nhập của người dùng).
Roger Keays

Tôi tin rằng bạn có thể gửi thông tin đăng nhập như một phần của yêu cầu tiêu đề, tôi sẽ đánh giá cao nếu bạn có thể thử điều đó.
Volodymyr Prysiazhniuk

4

Không thể nhận mã Phản hồi HTTP bằng cách sử dụng trực tiếp Selenium WebDriver. Mã có thể được lấy bằng cách sử dụng mã Java và có thể được sử dụng trong Selenium WebDriver.

Để nhận mã phản hồi HTTP bằng java:

public static int getResponseCode(String urlString) throws MalformedURLException, IOException{
    URL url = new URL(urlString);
    HttpURLConnection huc = (HttpURLConnection)url.openConnection();
    huc.setRequestMethod("GET");
    huc.connect();
    return huc.getResponseCode();
}

Bây giờ bạn có thể viết mã Selenium WebDriver của mình như sau:

private static int statusCode;
public static void main(String... args) throws IOException{
    WebDriver driver = new FirefoxDriver();
    driver.manage().window().maximize();
    driver.get("https://www.google.com/");
    driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

    List<WebElement> links = driver.findElements(By.tagName("a"));
    for(int i = 0; i < links.size(); i++){
        if(!(links.get(i).getAttribute("href") == null) && !(links.get(i).getAttribute("href").equals(""))){
            if(links.get(i).getAttribute("href").contains("http")){
                statusCode= getResponseCode(links.get(i).getAttribute("href").trim());
                if(statusCode == 403){
                    System.out.println("HTTP 403 Forbidden # " + i + " " + links.get(i).getAttribute("href"));
                }
            }
        }   
    }   
}

1
Điều gì sẽ xảy ra nếu đó là một biểu mẫu POST? Nếu có cookie thì sao?
nafg

1
Đây chỉ là gửi một yêu cầu HTTP bên ngoài selen.
Matthias Winkelmann

2

Bạn có thể thử Mobilenium ( https://github.com/rafpyprog/Mobilenium ), một gói python liên kết BrowserMob Proxy và Selenium.

Một ví dụ sử dụng:

>>> from mobilenium import mobidriver
>>>
>>> browsermob_path = 'path/to/browsermob-proxy'
>>> mob = mobidriver.Firefox(browsermob_binary=browsermob_path)
>>> mob.get('http://python-requests.org')
301
>>> mob.response['redirectURL']
'http://docs.python-requests.org'
>>> mob.headers['Content-Type']
'application/json; charset=utf8'
>>> mob.title
'Requests: HTTP for Humans \u2014 Requests 2.13.0 documentation'
>>> mob.find_elements_by_tag_name('strong')[1].text
'Behold, the power of Requests'
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.