如何为Jsoup添加代理支持?

46

我是Java的初学者,我的第一个任务是解析一些10,000个网址并从中提取一些信息,为此我使用了Jsoup,并且它运行良好。

但现在我想添加代理支持。这些代理还有用户名和密码。


嗯,你尝试过使用HtmlUnit吗?那应该可以胜任。 - raven
https://dev59.com/vnVD5IYBdhLWcg3wAWkO - swanliu
是的,我已经使用过了,但我仍然认为对于我的需求来说jsoup更好。我现在困惑的是如何使用jsoup有效地处理代理。 - Himanshu
7个回答

70

你可以轻松设置代理

System.setProperty("http.proxyHost", "192.168.5.1");
System.setProperty("http.proxyPort", "1080");
Document doc = Jsoup.connect("www.google.com").get();

1
请在调用后将其设置为null,否则不需要它的其他调用将变得非常缓慢。 - Dejell
如果你现在使用 [code]Jsoup.connect("www.google.com").get(),它会抛出一个 MalformedURLException 异常。 - Aditya K
10
无论我将代理主机(proxyHost)设置成哪个IP地址,Jsoup.connect都能够成功完成,但我似乎无法让这个设置起作用。 - vjuliano
4
以下回答介绍如何使用代理设置 Jsoup:https://dev59.com/questions/Y2s05IYBdhLWcg3wDtpn#34943161。 - Stephan
2
我同意 @jln646v 的观点。最好使用 Jsoup.proxy(proxy) - jpllosa
如果您需要连接到https,则这是唯一的解决方案。只需将“http”更改为“https”。+1。代理类不支持Proxy.Type.HTTPS,因此所有建议使用该方式的答案都不可行,如果您需要连接到https。 - Luke

54

Jsoup 1.9.1 及以上版本:(推荐方法)

// Fetch url with proxy
Document doc = Jsoup //
               .connect("http://www.example.com/") //
               .proxy("127.0.0.1", 8080) // sets a HTTP proxy
               .userAgent("Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.4; en-US; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2") //
               .header("Content-Language", "en-US") //
               .get();
您还可以使用重载方法 Jsoup#proxy,该方法接受一个Proxy类(见下文)。 在 Jsoup 1.9.1 之前的版本中: (冗长的方式)
// Setup proxy
Proxy proxy = new Proxy(                                      //
        Proxy.Type.HTTP,                                      //
        InetSocketAddress.createUnresolved("127.0.0.1", 8080) //
);

// Fetch url with proxy
Document doc = Jsoup //
               .connect("http://www.example.com/") //
               .proxy(proxy) //
               .userAgent("Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.4; en-US; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2") //
               .header("Content-Language", "en-US") //
               .get();

参考资料:


嗨,我正在使用JSoup 1.9.1 - 我尝试了答案中提到的两种方法,但没有结果。我在代理下工作,但我可以访问connect方法中提到的URL。每次都会收到相同的错误 - java.net.ConnectException: Connection refused: connect - Nakul Sharma
我也尝试了Alex在https://dev59.com/Y2s05IYBdhLWcg3wDtpn#27819164中提到的方法,但是它也没有起作用。 - Nakul Sharma
@NakulSharma 错误 java.net.ConnectException: Connection refused: connect 可能表示目标主机未监听或拒绝了某些客户端连接。 - Stephan

40

您不必通过Jsoup获取网页数据。这是我的解决方案,尽管可能不是最好的。

  URL url = new URL("http://www.example.com/");
  Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 8080)); // or whatever your proxy is
  HttpURLConnection uc = (HttpURLConnection)url.openConnection(proxy);

  uc.connect();

    String line = null;
    StringBuffer tmp = new StringBuffer();
    BufferedReader in = new BufferedReader(new InputStreamReader(uc.getInputStream()));
    while ((line = in.readLine()) != null) {
      tmp.append(line);
    }

    Document doc = Jsoup.parse(String.valueOf(tmp));

就是这样。通过代理获取HTML页面的源代码,然后使用Jsoup解析。


好的解决方案。在uc.connect之后,我能否使用基于NIO的获取方式? - Nickromancer
1
对于普通读者来说,可以直接将HttpURLConnection的inputstream传递给Jsoup。有关详细信息,请参见以下答案:https://dev59.com/Y2s05IYBdhLWcg3wDtpn#42085445 - Stephan
你能否使用这种方法来使用cookies,例如下载需要登录密码的页面?我认为应该始终使用Jsoup。 - user25

6
您在运行程序之前可能需要添加以下内容。
final String authUser = "USERNAME";
final String authPassword = "PASSWORD";



Authenticator.setDefault(
               new Authenticator() {
                  public PasswordAuthentication getPasswordAuthentication() {
                     return new PasswordAuthentication(
                           authUser, authPassword.toCharArray());
                  }
               }
            );

..

System.setProperty("http.proxyHost", "192.168.5.1");
System.setProperty("http.proxyPort", "1080");
..

5
System.setProperty("http.proxyHost", "192.168.5.1");
System.setProperty("http.proxyPort", "1080");
Document doc = Jsoup.connect("www.google.com").get();

这个解决方案是错误的,因为解析通常是多线程的,我们通常需要更改代理。这段代码为所有线程只设置了一个代理。所以最好不要使用Jsoup.Connection。


有关使用Jsoup.Connection,请参见以下答案 https://dev59.com/Y2s05IYBdhLWcg3wDtpn#34943161 - Stephan

3
v1.9.1版本以来,Jsoup支持使用代理Connection具有以下方法:

  • proxy(Proxy p)
  • proxy(String host, int port)

您可以像这样使用它:

Jsoup.connect("...url...").proxy("127.0.0.1", 8080);

如果您需要身份验证,您可以使用 Authenticator 方法,如 @Navneet Swaminathan 所提到的,或者简单地设置系统属性
System.setProperty("http.proxyUser", "username");
System.setProperty("http.proxyPassword", "password");

或者

System.setProperty("https.proxyUser", "username");
System.setProperty("https.proxyPassword", "password");

1
尝试使用以下代码:
URL url = new URL("http://www.example.com/");
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 8080)); // or whatever your proxy is

HttpURLConnection uc = (HttpURLConnection)url.openConnection(proxy);
hc.setRequestProperty("User-Agent", "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.4; en-US; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2");
uc.setRequestProperty("Content-Language", "en-US");
uc.setRequestMethod("GET");
uc.connect();

Document doc = Jsoup.parse(uc.getInputStream());

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接