使用 HttpURLConnection 的 Cookie session

Cookie session using HttpURLConnection

我正在开发一个登录网站的应用程序。我遇到了问题,因为当我读取浏览器的请求 header 时,浏览器发送了一个 cookie。我需要知道如何在我的应用程序中执行此操作,我的意思是,当我启动连接时,它会自行定义请求的 cookie。我尝试使用此 CookieHandler.setDefault( new CookieManager( null, CookiePolicy.ACCEPT_ALL ) ); 但没有用。

来源:

CookieHandler.setDefault( new CookieManager( null, CookiePolicy.ACCEPT_ALL ) );
URL url2 = new URL("https://m.example.com.br/login.jhtml");
        HttpURLConnection conn = (HttpURLConnection) url2.openConnection();
        conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
        conn.setRequestMethod("POST");
        conn.setRequestProperty("User-Agent","User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:58.0) Gecko/20100101 Firefox/58.0");
        conn.setRequestProperty("Content-Length", parameters + Integer.toString(parameters.getBytes().length));
        conn.setFollowRedirects(true);
        conn.setDoInput(true);
        conn.setDoOutput(true);
        conn.setUseCaches(false);
        DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
        wr.writeBytes(parameters);
        wr.flush();
        wr.close();
        if (conn.getResponseCode()== 200){
            InputStream in =  conn.getInputStream();
            BufferedReader rd = new BufferedReader(new InputStreamReader(in));
            String line=null;
            StringBuffer response = new StringBuffer();
            while((line = rd.readLine()) != null) {
                response.append(line);
                response.append('\r');
            }
            rd.close();
            System.out.println(response.toString());
        }

请求 Header 我的申请:

Content-Type: application/x-www-form-urlencoded
User-Agent: User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:58.0) Gecko/20100101 Firefox/58.0
Connection: Keep-Alive
Accept-Encoding: gzip
Cookie: TS0163e05c="01ed0a5ec20a04efb37decf4185e55cfe68e06164c32f1a95d1d5b8f12c72abbee029ed64985c09681a55832e444c61821a1eb6fb22d6ed9880314fa0c342074316e309642";$Path="/";$Domain="example.com"; ps-website-switching-v2=%7B%22ps-website-switching%22%3A%22ps-website%22%7D; TS015a85bd=01ed0a5ec25aecf271e4e08c02f852e9ea6199a117a0a8e0339b3e98fd1d51518e5f09ead481039d4891f66e9cc48a13ced14792de
Content-Length: 198

请求 Header 浏览器:

Host: m.example.com
Connection: keep-alive
Content-Length: 197
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Linux; Android 5.0.2; LG-D337 Build/LRX22G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.137 Mobile Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Cookie: _ga=GA1.3.313511484.1517525889; _gid=GA1.3.507266479.1517525889; DEretargeting=563; CSASF=; JS_SESS=; BT=%3B106%3B; DN....

注意Cookies,为什么差别这么大?如果不使用 conn.setRequestProperty("Cookie",cookie); 进行设置,我该怎么做才能发送这样的 cookie?

HttpURLConnection 不是一种非常可靠的抓取网站或与网站互动的方式,原因如下:

  • HttpURLConnection 不理解 JavaScript。 JavaScript 可以设置 cookie 以及提供网站的主要部分功能。
  • HttpURLConnection 不会下载与页面关联的所有资源,就像其他 .html 帧中的文件、图像(0 像素图像有时也可以添加 cookie,但如果您从未获得它们,您将永远不会得到 cookie),JavaScript,等等。
  • CookieHandler 仅适用于在 HTTP 响应 Headers 中直接 传递给您的 cookie。如果网站 content 中的任何内容(包括图像等嵌入内容)会导致创建更多 cookie,则您无法使用 CookieHandler 获取它们,因为它不理解 HTML/JS/etc.

您应该改用 Selenium。 Selenium 自动化了一个 真正的 网络浏览器(或者至少是更接近真正的网络浏览器的东西),它可以解析 HTML 并根据网络标准的期望运行。

至于使用哪个浏览器 driver(后端),这里有几个选项:

  • HtmlUnit,这可能是最快的 driver(至少它的内存开销最少),但缺点是并非所有最新的 Web 标准和技术都受支持。如果它适用于您的网站,它可能是最佳选择,因为它不需要任何本机 driver 组件。它确实支持相当多的 JavaScript(参见 link),但与最新的 Firefox 或 Chrome 相比,可能支持的 up-to-date 功能更少。 HtmlUnit 是无头的。
  • PhantomJS,它基于相当过时的 WebKit 版本。您的 Web 标准支持将在 2013 年左右生效,这对大多数网站来说可能没问题,但某些 cutting-edge 功能将无法使用。它在某些类型的内容中也有相当多的错误。然而,它也是无头的,拥有相当大的用户群,并且通常比 full-blown 浏览器的开销更低。
  • Firefox、Chrome、Edge、Opera 或 IE。 Firefox 和 Chrome 现在可以选择无头支持。

"headless" 和 "not headless"(或 "headed",如果您愿意的话)之间的区别是无头浏览器不会创建任何 GUI windows。如果您 运行ning 在无头 Linux 机器上,这实际上是一个要求,除非您想创建一个 Xvfb 虚拟 X 服务器或其他东西。如果您 运行 从具有图形界面(Windows、MacOS 或桌面 Linux)的计算机上执行此操作,则是否要在以下时间弹出浏览器取决于您你 运行 你的代码。

无头浏览器确实往往相对更快,并且您可以并行扩展它们的更多实例,因为它们在您使用它们时不会占用您系统上的任何图形资源。他们只是使用浏览器引擎本身来处理网络内容,并允许您通过 Selenium access/drive 它。

如果您确实想要无头,但需要最新的网络平台功能和标准支持,请考虑使用无头 Chrome 或无头 Firefox。

无头Chrome简介:https://developers.google.com/web/updates/2017/04/headless-chrome

无头 Firefox 介绍:https://developer.mozilla.org/en-US/Firefox/Headless_mode