Selenium WebDriver를 사용하여 HTTP 응답 코드를 얻는 방법


109

Selenium2 / WebDriver로 테스트를 작성했으며 HTTP 요청이 HTTP 403 금지를 반환하는지 테스트하고 싶습니다.

Selenium WebDriver로 HTTP 응답 상태 코드를 얻을 수 있습니까?



파이썬의 다른 질문의 초점을하지만,이 하나가 자바에 있기 때문에 이것은 중복입니다
랄프

1
감사합니다. 그러나 마지막 질문은에 결국 webdriver의 제한 사항 및 이러한 제한은 파이썬과 자바 모두 동일)
maxkoryukov

2
@maxkoryukov :하지만 언어 dependend의 workarrounds가,
랄프

답변:


66

한마디로, 아닙니다. Selenium WebDriver API를 사용하는 것은 불가능합니다. 이는 프로젝트 의 이슈 트래커 에서 광고 구역질에 대해 논의되었으며 기능은 API에 추가되지 않습니다.


42

Selenium 및 Chrome 또는 Firefox를 사용하여 http 요청의 응답 코드를 가져올 수 있습니다. 로깅 모드에서 Chrome 또는 Firefox를 시작하기 만하면됩니다. 아래에서 몇 가지 예를 보여 드리겠습니다.

java + Selenium + Chrome 다음은 java + Selenium + Chrome 의 예이지만 모든 언어 (python, c #, ...)로 할 수 있다고 생각합니다.

chromedriver에 "Network.enable"을 지정하기 만하면됩니다. 이는 성능 로깅을 활성화하여 수행 할 수 있습니다.

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

요청이 완료된 후 수행 할 작업은 Perfomance 로그를 가져 와서 반복하고 요청 된 URL에 대해 "Network.responseReceived"를 찾는 것입니다.

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

다음은 코드입니다.

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

출력은 다음과 같습니다.

    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 드디어 Firefox 용 트릭을 찾았습니다. MOZ_LOGMOZ_LOG_FILE환경 변수를 사용하여 firefox를 시작 하고 디버그 수준에서 http 요청을 기록해야합니다 (4 = PR_LOG_DEBUG) - map.put("MOZ_LOG", "timestamp,sync,nsHttp:4"). 임시 파일에 로그를 저장하십시오. 그런 다음 저장된 로그 파일의 내용을 가져 와서 응답 코드에 대해 구문 분석합니다 (일부 간단한 정규식 사용). 먼저 요청의 시작을 감지하고 해당 ID를 식별 (nsHttpChannel::BeginConnect [this=000000CED8094000])한 다음 두 번째 단계에서 해당 요청 ID에 대한 응답 코드를 찾습니다 (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");
    }
  }
}

이에 대한 출력은 다음과 같습니다.

요청 ID = 0000007653D67000 응답 코드 200 개 발견

응답 헤더는 로그 파일에서도 찾을 수 있습니다. 원한다면 얻을 수 있습니다.

    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
이것을보고있는 사람들을 위해, chromium의 network.enable은 활성화되어있는 동안 만들어진 모든 HTTP 요청에 추가 헤더를 삽입한다는 점에 유의하십시오.
가짜 이름

2
안녕하세요, 응답 코드를받을 수 있지만 응답 본문은 어떻게받을 수 있나요? 응답 JSONObject에서 볼 수 없습니다.
LINGS

@LINGS는 driver.getPageSource ()를 사용할 수 있지만 일반적으로 Dom을 변경할 수있는 여러 측면 자바 스크립트 요청이 있기 때문에주의해야합니다. 페이지의 일부 요소가 DOM에있을 때까지 기다린 다음 페이지 소스를 가져올 수 있습니다. 또 다른 시나리오는 프레임입니다. 프레임이있는 경우 프레임으로 전환해야하며 해당 프레임의 소스 코드를 가져옵니다.-driver.switchTo (). frame ();
Stefan Matei

나는 귀하의 코드를 구현하기 위해 노력 RemoteWebDriver을 내 방법이 RemoteWebdriver에 기록 된대로. RemoteWebDriver 와 함께 사용하는 방법에 대해 알고 있습니까?
M3trix

2
@IvayloSlavov Chrome 스크립트가 4.0.0-alpha-4에서 작동합니다.이 예제를 확인하세요. github.com/smatei/SeleniumChromeHTTPResponse
Stefan Matei

16

BrowserMob 프록시를 사용하여 HttpRequestInterceptor. 다음은 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();

솔루션을 사용하고 있지만 프록시를 사용하면 페이지로드가 매우 느립니다. 어떻게 된 건지 아세요? 내 질문도 참조하십시오 : stackoverflow.com/questions/21043928/…
Charlie

1
원래 BrowserMob 프록시는 이제 지원되지 않으며 비트 썩습니다. 성능, 페이지 및 네트워크 어설 션이 내장 된 browsermob 프록시의 오픈 소스 포크가 있습니다. github.com/browserup/browserup-proxy
ebeland

13

Python을 사용하는 사람들을 위해 테스트 중에 브라우저의 요청을 검사하기 위해 개발 한 라이브러리 인 Selenium Wire를 고려할 수 있습니다 .

driver.requests속성을 통해 요청에 액세스 할 수 있습니다 .

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']
        )

인쇄물:

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
...

라이브러리는 헤더, 상태 코드, 본문 콘텐츠에 액세스 할 수있을뿐만 아니라 헤더를 수정하고 URL을 다시 작성하는 기능을 제공합니다.


webdriver.Remote와 함께 사용하려고하는데 "AttributeError : 'WebDriver'object has no attribute 'requests'"라는 메시지가 나타납니다. 원격 드라이버가 셀레늄 와이어에서 지원되지 않기 때문입니까? 공식 문서는 절망적으로 부족합니다. 감사!
Lennart Rolland

@LennartRolland Selenium Wire의 한계 중 하나 는 브라우저를 실행하는 동일한 컴퓨터에서만 작동한다는 것입니다. 현재 원격 설정 사용은 지원되지 않습니다.
윌 킬 링

1
@MohamedImran 특정 응답에 관심이있는 경우 driver.wait_for_request()메서드를 사용하여 응답에 관심이있는 요청을 찾을 수 있습니다 . 자세한 내용 은 문서 를 참조하세요.
Will Keeling

1
@MohamedImran 메서드는 정규식을 사용하므로 고유하게 일치하는 URL의 일부만 전달할 수 있습니다. 예를 들어 http://myserver.com/some/path/12345/통과 할 수 있습니다driver.wait_for_request(‘.*/12345/‘)
Will Keeling

1
@MohamedImran 당신은 for 루프가 필요하지 않습니다
Will Keeling

10

나는 또한 같은 문제가 있었고 며칠 동안 붙어 있었지만 몇 가지 조사 끝에 실제로 크롬의 "--remote-debugging-port"를 사용하여 셀레늄 웹 드라이버와 함께 요청을 가로 챌 수 있다는 것을 알아 냈습니다. 다음 의사 코드를 참조로 사용하십시오.

원격 디버깅으로 크롬 드라이버의 인스턴스 생성

int freePort = findFreePort();

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

ChromeDriver driver = new ChromeDriver(chromeOptions);`

http://127.0.0.1:freePort로 전화 걸기

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

크롬의 webSocket URL을 추출하여 듣고 응답을보고 추출 방법을 파악할 수 있습니다.

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

이 소켓에 연결하면 asyncHttp를 사용할 수 있습니다.

socket = maketSocketConnection( webSocketUrl );

네트워크 캡처 활성화

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

이제 크롬은 모든 네트워크 관련 이벤트를 보내고 다음과 같이 캡처합니다.

socket.onMessageReceived( String message ){

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

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

개발 도구 사이트에 언급 된 모든 것을 할 수 있습니다. 참조 https://chromedevtools.github.io/devtools-protocol/ 참고 : - 사용 chromedriver 2.39 이상.

누군가에게 도움이되기를 바랍니다.

참고 : Google 크롬 원격 디버깅 프로토콜 사용


이 작업을 수행 할 수있는 방법이있어 기쁩니다! 마지막 응답을 확인하는 간단한 방법을 selenium-webdriver자동으로 활성화 Network.enable하고 노출 하는 라이브러리 ( 제 경우 Ruby 용)가 있었으면 좋겠습니다 driver.response.status_code. 언젠가 나는 것을 ... :) 추가로 주위거야
타일러 릭

다른 Ruby 프로그래머가이 문제를 접할 경우 github.com/TylerRick/capybara-chrome_response_headers를 만들었습니다. 이를 통해 Capybara / RSpec 테스트에서 HTTP 상태 코드를 쉽게 가져올 수 있습니다 status_code. 이 예제와 같이 Chrome 원격 디버깅 프로토콜을 사용합니다.
Tyler Rick

고마워 친구! 나 + 셀레늄 3.141 (76)을 크롬 작동
jessez

9

모든 언어로 응답 코드 얻기 (JavaScript 사용) :

Selenium 테스트가 최신 브라우저에서 실행되는 경우 응답 코드를 얻는 쉬운 방법은 동기 XMLHttpRequest* 를 보내고 status응답을 확인하는 것 입니다.

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

assert(200, xhr.status);

Selenium이 스크립트를 실행하도록 요청하여 모든 프로그래밍 언어에서이 기술을 사용할 수 있습니다. 예를 들어 Java에서는 다음 JavascriptExecutor.executeScript()을 전송하는 데 사용할 수 있습니다 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"));

* XMLHttpRequest대신 비동기식을 보낼 수 있지만 테스트를 계속하기 전에 완료 될 때까지 기다려야합니다.

Java로 응답 코드 얻기 :

URL.openConnection()HttpURLConnection.getResponseCode()다음 을 사용하여 Java에서 응답 코드를 얻을 수 있습니다 .

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

이 메서드는 다른 언어로도 일반화 될 수 있지만 해당 언어 (또는 라이브러리)의 API에 맞게 수정해야합니다.


8

이것이 당신이 찾고있는 것인지 확실하지 않지만 조금 다른 목표는 원격 이미지가 있는지 확인하는 것이며 403 오류가 발생하지 않을 것이므로 아래와 같이 사용할 수 있습니다.

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
간단한 경우에는 편리하지만이 방법을 사용하는 브라우저 상태 (예 : 사용자 로그인)가 없습니다.
Roger Keays 2012 년

헤더 요청의 일부로 자격 증명을 보낼 수 있다고 생각합니다. 시도해 주시면 감사하겠습니다.
Volodymyr Prysiazhniuk

4

Selenium WebDriver를 직접 사용하여 HTTP 응답 코드를 가져올 수 없습니다. 코드는 Java 코드를 사용하여 얻을 수 있으며 Selenium WebDriver에서 사용할 수 있습니다.

Java로 HTTP 응답 코드를 얻으려면 다음을 수행하십시오.

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

이제 다음과 같이 Selenium WebDriver 코드를 작성할 수 있습니다.

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
POST 양식 제출 인 경우 어떻게됩니까? 쿠키가 있으면 어떻게 되나요?
nafg

1
이것은 셀레늄 외부에서 HTTP 요청을 보내는 것입니다.
Matthias Winkelmann

2

BrowserMob 프록시와 Selenium을 바인딩하는 Python 패키지 인 Mobilenium ( https://github.com/rafpyprog/Mobilenium )을 사용해 볼 수 있습니다.

사용 예 :

>>> 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'
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.