如何使用 java 以编程方式向内部网页 link 发送 http 请求?

How to programmatically send http request to inner webpage link with java?

我正在尝试制作一个 java 应用程序,它将与服务器连接,然后尝试访问该服务器页面的 link。例如,我有一个 link "http://goodserver.com" 并且我可以通过此代码

连接到此 url
InetAddress addr = null;
          Socket sock = new Socket("http://goodserver.com", 80);
          addr = sock.getInetAddress();
          System.out.println("Connected to " + addr);

现在我也可以阅读这个页面的全部源代码了。但是有 links 的按钮。当我浏览浏览器时,我可以轻松地单击那些按钮并转到 link。例如一个名为"Test"的按钮,对应的link是“http://goodserver.com/targets/Test”。

我想通过java访问这个link,但问题是无法直接连接。我不想按 java 点击此 link,因为我已阅读此 link "Programmatically click a webpage button" 。我只想知道浏览器在加载主页后可以访问 link 的机制,但它不可能通过 java http 请求。

我已通过此代码阅读页面

URL url = new URL("http://goodserver.com");
  BufferedReader reader = new BufferedReader
  (new InputStreamReader(url.openStream()));
  BufferedWriter writer = new BufferedWriter
  (new FileWriter("data.html"));
  String line;
  while ((line = reader.readLine()) != null) {
     System.out.println(line);
     writer.write(line);
     writer.newLine();
  }
  reader.close();
  writer.close();

当用我的目标按钮 link 替换此主页 link 时,“http://goodserver.com/targets/Test” 我得到的是主页源代码而不是目标页面。

我知道浏览器也会发送 http 请求来获取页面,那么 java 应该是可以的。提前致谢。

如果第二次请求的结果取决于您是否访问了主页,则您的问题可能与cookie有关。

HTTP 是一种无状态 协议,这意味着每个请求都独立于其他请求。当您打开一个页面并单击一个按钮时,您会向另一个页面生成一个新请求 URL,但服务器不知道您是谁或您之前打开过哪些页面。

Cookie 使服务器能够 "remember" 您是谁。它们的工作方式如下:当您请求一个页面时,服务器会将该页面的内容发送给您,但它们也可以发送一些称为 cookie 的额外信息。您的浏览器会存储该信息,每次您向同一服务器发出另一个请求时,浏览器都会随该请求发送 cookie。所以,即使服务器一开始并不知道是谁在发出请求,现在它可以查看 cookie 并意识到它向你发送了该信息,你一定是你发出了那个请求.

所以,这就是您在问题中可能遗漏的部分:存储服务器在您加载主页时发送给您的 cookie,然后在您请求其他页面时再次发送它们到 "remind"您已经访问过首页的服务器。

当然,您可以通过解析 HTTP headers 来手动完成此操作,但我强烈建议您使用一些库来为您完成此操作。 Apache HTTP Client 可能是您在 Java 世界中可以找到的最好的。下面是一个关于如何跨请求保留 cookie 的简短示例:

public class CookiesExample {

    public static void main(String[] args) throws Exception {
        //This object will store your cookies:
        BasicCookieStore cookieStore = new BasicCookieStore();

        //Create a client using our cookie store:
        CloseableHttpClient httpclient = HttpClients.custom()
                .setDefaultCookieStore(cookieStore)
                .build();

        try {
            //Execute request:
            HttpGet httpget = new HttpGet("https://example.com/");
            CloseableHttpResponse response = httpclient.execute(httpget);
            try {
                //Consume the response:
                HttpEntity entity = response.getEntity();
                EntityUtils.consume(entity);
            } finally {
                response.close();
            }

            //Whatever cookies that were sent by the server in that request 
            //are now stored in our cookie store. Subsequent requests will
            //send those cookies to the server.

            httpget = new HttpGet("https://example.com/my/awesome/internal/page");
            response = httpclient.execute(httpget);
            try {
                //Consume the response:
                HttpEntity entity = response.getEntity();
                EntityUtils.consume(entity);
            } finally {
                response.close();
            }
        } finally {
            httpclient.close();
        }
    }
}

另一种可能的解决方案是使用真正的浏览器来为您处理所有这些。 JavaFX 有一个可以从 Java 控制的浏览器组件,还有 Selenium 可以让您使用 "driver" 来控制真正的浏览器(Chrome、Firefox、IE、 ...).