Java Selenium 获取 JSON 响应正文

Posted

技术标签:

【中文标题】Java Selenium 获取 JSON 响应正文【英文标题】:Java Selenium get JSON response body 【发布时间】:2018-02-03 03:53:44 【问题描述】:

我将 Java 与 Selenium webdriver 一起使用,我想知道是否可以获得 JSON 正文响应?我问是因为可以使用此代码获取 JSON 请求正文:

driver.manage().logs().get(LogType.PERFORMANCE);

但我无法从响应中获取正文,但此日志中也存在响应。有什么方法可以获得响应正文吗?

【问题讨论】:

数据在 JSON 响应中 comimg .. 你想要实现的目标 请澄清您的具体问题或添加其他详细信息以准确突出您的需要。正如目前所写的那样,很难准确地说出你在问什么。请参阅How to Ask 页面以获得澄清此问题的帮助。 【参考方案1】:

我建议您查看用于跟踪网络活动的专用工具,例如 Browsermob Proxy,它可以轻松地与 Selenium 集成。内部 Selenium 日志不适用于此类目的。

【讨论】:

感谢您的帮助,但是当我将这个库实现到我的 FIrefox 浏览器项目中时,会出现错误 org.openqa.selenium.SessionNotCreatedException: InvalidArgumentError: Expected [object Undefined] undefined to be an integer @MateuszSobczak 可能更好地检查 BMP 问题跟踪器。最新的 FF 版本/驱动程序可能存在一些问题。 什么是 BMP?我使用 geckodriver 0.18.0 和 FIrefox ver 54.0.1 @MateuszSobczak BMP = Browsermob 代理。检查问题:github.com/lightbody/browsermob-proxy/issues @MateuszSobczak,这是 Geckodriver 的一个已知问题。您现在需要直接在 FirefoxProfile 中设置代理以获得解决方法【参考方案2】:

Edit-2

由于 Geckodriver 的一个未解决问题,https://github.com/mozilla/geckodriver/issues/764

因此,您需要使用解决方法并执行 GeckoDriver 在后台为您执行的操作

import net.lightbody.bmp.BrowserMobProxyServer;
import net.lightbody.bmp.client.ClientUtil;
import net.lightbody.bmp.core.har.Har;
import net.lightbody.bmp.proxy.CaptureType;
import org.openqa.selenium.Proxy;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxProfile;

import java.io.File;
import java.io.IOException;

/**
 * Created by tarun.lalwani on 08/29/17.
 */
public class TestApp 


    public static void main(String [] args) 

        BrowserMobProxyServer proxyServer = new BrowserMobProxyServer();
        proxyServer.start();
        proxyServer.setHarCaptureTypes(CaptureType.getAllContentCaptureTypes());
        proxyServer.enableHarCaptureTypes(CaptureType.REQUEST_CONTENT, CaptureType.RESPONSE_CONTENT);
        Proxy proxy = ClientUtil.createSeleniumProxy(proxyServer);
        FirefoxProfile profile = new FirefoxProfile();

        String host = proxy.getHttpProxy().split(":")[0];
        int port = Integer.parseInt(proxy.getHttpProxy().split(":")[1]);


        profile.setPreference("network.proxy.type", 1);
        profile.setPreference("network.proxy.http", host);
        profile.setPreference("network.proxy.http_port", port);
        profile.setPreference("network.proxy.ssl", host);
        profile.setPreference("network.proxy.ssl_port", port);
        FirefoxDriver driver = new FirefoxDriver(profile);

        proxyServer.newHar("mysite");

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

        Har har = proxyServer.getHar();
        try 
            har.writeTo(new File("har.json"));
         catch (IOException e) 
            e.printStackTrace();
        
    

Edit-1

因为您想在 Java 中执行此操作。您需要为 Java 使用 BrowserMobProxy 库,下面的代码应该适合您

import net.lightbody.bmp.BrowserMobProxy;
import net.lightbody.bmp.BrowserMobProxyServer;
import net.lightbody.bmp.client.ClientUtil;
import net.lightbody.bmp.core.har.Har;
import net.lightbody.bmp.proxy.CaptureType;


.....

BrowserMobProxy proxy = new BrowserMobProxyServer();
proxy.start(0);

Proxy selProxy = ClientUtil.createSeleniumProxy(proxy);

DesiredCapabilities cap = new DesiredCapabilities();
cap.setCapability(CapabilityType.PROXY, selProxy);


WebDriver driver = new FirefoxDriver(capabilities);

proxy.enableHarCaptureTypes(CaptureType.REQUEST_CONTENT, CaptureType.RESPONSE_CONTENT);

proxy.newHar("mysite");

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


Har har = proxy.getHar();

原答案

您需要在 Firefox 上设置 BrowserMobProxy。下面的代码将为您工作

import time
from selenium import webdriver

from browsermobproxy import Server
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

server = Server("/path/to/bin/browsermob-proxy")
server.start()
# If sleep is not added sometime `create_proxy` throws an error
time.sleep(2)
proxy = server.create_proxy()

sel_proxy = proxy.selenium_proxy()

profile = FirefoxProfile()
profile.set_proxy(sel_proxy)
driver = webdriver.Firefox(firefox_profile=profile)
proxy.new_har("mysite", options='captureHeaders': True, 'captureContent': True )
driver.get("http://tarunlalwani.com")
print(proxy.har)

这将给出如下输出

'version': '1.2',
'creator': 
  'name': 'BrowserMob Proxy',
  'version': '2.1.4',
  'comment': ''
,
'pages': [
  
    'id': 'mysite',
    'startedDateTime': '2017-08-25T21:38:08.934+05:30',
    'title': 'mysite',
    'pageTimings': 
      'comment': ''
    ,
    'comment': ''
  
],
'entries': [
  
    'pageref': 'mysite',
    'startedDateTime': '2017-08-25T21:38:09.367+05:30',
    'request': 
      'method': 'GET',
      'url': 'http://tarunlalwani.com/',
      'httpVersion': 'HTTP/1.1',
....

    'response': 
      'status': 200,
      'statusText': 'OK',
      'httpVersion': 'HTTP/1.1',
      'cookies': [

      ],
      'content': 
        'size': 21336,
        'mimeType': 'text/html; charset=utf-8',
        'text': '<!DOCTYPE html>\n<html lang="en">\n<head prefix="og: http://ogp.me/ns# article: http://ogp.me/ns/article# website: http://ogp.me/ns/website#">\n    <meta http-equiv="content-type" content="text/html; charset=utf-8">\n    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1">\n    \n    \n      <meta name="description" content="TARUN LALWANI">\n      <meta name="twitter:description" content="TARUN LALWANI">\n    \n\n    <meta property="og:title" content="TARUN LALWANI">\n    <meta property="twitter:title" content="TARUN LALWANI">\n    \n    <meta property="og:type" content="website">\n    \n    <meta property="og:description" content="">\n    <meta property="og:url" content="http://tarunlalwani.com/">\n    <meta property="og:site_name" content="TARUN LALWANI">\n   \n\n    \n\n    \n\n    <meta name="generator" content="Hugo 0.25.1" />\n    <title>TARUN LALWANI &middot; TARUN LALWANI</title>\n    \n    <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.3.0/css/font-awesome.min.css">\n    <link rel="stylesheet" href="http://tarunlalwani.com/css/style.css">\n\n    \n\n    \n    <link href="http://tarunlalwani.com/index.xml" rel="alternate" type="application/rss+xml" title="TARUN LALWANI" />\n    \n    \n\n    \n    \n</head>\n<body>\n\n<nav class="navbar navbar-default navbar-fixed-top visible-xs">\n\t<div class="container-fluid">\n\t\t<div class="navbar-header">\n\t\t\t<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">\n\t\t\t\t<span class="sr-only">Toggle navigation</span>\n\t\t\t\t<span class="icon-bar"></span>\n\t\t\t\t<span class="icon-bar"></span>\n\t\t\t\t<span class="icon-bar"></span>\n\t\t\t</button>\n\t\t\t\n\t\t\t\t<a class="navbar-brand" href="http://tarunlalwani.com/">TARUN LALWANI</a>\n\t\t\t\n\t\t</div>\n\t\t<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">\n\t\t\t<ul class="nav navbar-nav">\n\t\t\t\t\n\t\t\t\t\n\t\t\t</ul>\n\t\t</div>\n\t</div>\n</nav>\n<div class="container-fluid">\n\t<div class="row">\n\t\t<div id="menu" class="hidden-xs col-sm-4 col-md-3">\n\t<div id="menu-content" class="vertical-align">\n\t\t\n\t\t\t<

【讨论】:

我不懂这门语言,我用的是Java。在 java FirefoxProfile 我们没有函数 set_proxy 此代码不起作用。您可以查看***.com/questions/45915525/… 好吧,我也可以解决这个问题 你有c#版本吗? 你能帮帮我吗? ***.com/questions/65583253/… 或这里***.com/questions/66211829/…【参考方案3】:

我能够使用以下代码(使用 Selenium 4)使其为自己工作:

    File file = new File("C:\\Program Files (x86)\\ChromeDriver\\chromedriver.exe");
    ChromeDriverService service = new ChromeDriverService.Builder()
            .usingDriverExecutable(file)
            .usingAnyFreePort().build();
    ChromeOptions options = new ChromeOptions().addArguments("--incognito");
    ChromeDriver driver = new ChromeDriver(service, options);
    DevTools chromeDevTools = driver.getDevTools();
    
    chromeDevTools.createSession();
    chromeDevTools.send(Network.enable(Optional.empty(), Optional.empty(), Optional.empty()));
    chromeDevTools.addListener(Network.loadingFinished(),
            entry -> 
                System.out.println("Body: " + chromeDevTools.send(Network.getResponseBody(entry.getRequestId())).getBody());
            );  

    driver.get("https://www.yoururlhere.com");
    
    chromeDevTools.send(Network.disable());
    driver.quit();

我的进口:

    import org.openqa.selenium.chrome.ChromeDriver;
    import org.openqa.selenium.chrome.ChromeDriverService;
    import org.openqa.selenium.chrome.ChromeOptions;
    import org.openqa.selenium.devtools.DevTools;
    import org.openqa.selenium.devtools.v96.network.Network;

    import java.io.File;
    import java.util.*;

我的 Selenium 依赖项:

    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-java</artifactId>
        <version>4.1.0</version>
    </dependency>

有用的资源,帮助我找到解决方案:

https://applitools.com/blog/selenium-4-chrome-devtools/

https://chromedevtools.github.io/devtools-protocol/1-3/Network/

【讨论】:

driver.get(url); 应该在Network.disable() 之前调用,提示各种Network 版本会增加价值,谢谢。 @AhmedAshour 我添加了 driver.get,感谢您指出。您能否详细说明网络版本提示? (您可以在我列出的导入中看到我使用的版本) import org.openqa.selenium.devtools.v96.network.Network;v96 可能会因为IDE 自动导入而丢失。例如v85

以上是关于Java Selenium 获取 JSON 响应正文的主要内容,如果未能解决你的问题,请参考以下文章

使用 Laravel 从 API 获取 JSON 响应

在Java中从JSON响应中获取字符串

获取Web表中的行数 - Selenium WebDriver Java

java语言,如何获取服务器响应发来的json网页(或代码)

如何从 Java 中的 Apple 公钥 JSON 响应中获取公钥?

使用 Selenium WebDriver 和 Java 从页面源中获取所有 href 链接