問題背景
最近工作上有開發爬蟲的任務,對目標網站數據進行抓取,由於大部分網站都在國外,無法直接訪問,需要通過代理才能登錄。爬蟲部署的服務器在香港,所以爬蟲部署到服務器后,是可以訪問目標網站的,但本地開發調試程序時,需要通過代理才能訪問。
這篇文章就帶大家了解一下如何在Java程序中使用代理訪問網絡。
解決方案
-
你需要一個代理服務器,和一個可以連接到此服務器的客戶端。
花點銀子買一個穩定的賬號,或者自己搭建一個。
這里我使用自己搭建的Shadowsocks
代理服務器,使用Shadowsocks-Windows
作為本地代理的客戶端,並開啟默認的1080
端口,以供本地其他程序通過代理訪問網絡。
-
指定 Java 程序的代理服務器地址和端口
有兩種指定方式:- 通過 命令行參數 指定
如果只需要考慮代理 HTTP 協議請求,只需添加如下命令行參數:
-Dhttp.proxyHost=127.0.0.1 -Dhttp.proxyPort=1080
想要 HTTP 和 HTTPS 協議的請求都通過代理訪問網絡,可以追加上:
-Dhttps.proxyHost=127.0.0.1 -Dhttps.proxyPort=1080
最終填寫的值為:
-Dhttp.proxyHost=127.0.0.1 -Dhttp.proxyPort=1080 -Dhttps.proxyHost=127.0.0.1 -Dhttps.proxyPort=1080
- 在程序中使用System.setProperty(String, String)
同樣很簡單,這里直接上代碼:
String proxyHost = "127.0.0.1"; String proxyPort = "1080"; System.setProperty("http.proxyHost", proxyHost); System.setProperty("http.proxyPort", proxyPort); // 對https也開啟代理 System.setProperty("https.proxyHost", proxyHost); System.setProperty("https.proxyPort", proxyPort);
- 通過 命令行參數 指定
推薦使用第一種方案,通過VM Option 的方式,對代碼沒有任何侵入,綠色環保。
測試
這里我在Eclipse中使用第一種方法進行測試。
- 測試代碼
import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.net.URLConnection; public class Test { public static void main(String[] args) throws IOException { URL url = new URL("https://google.com"); URLConnection connection = url.openConnection(); connection.connect(); InputStream inputStream = connection.getInputStream(); byte[] bytes = new byte[1024]; while (inputStream.read(bytes) >= 0) { System.out.println(new String(bytes)); } } }
- 測試結果,可以正常訪問Google等網站。
總結
除了上述 http.proxyHost
和 http.proxyPort
,以及 https.proxyHost
和 https.proxyPort
在代理時比較有用外,還有一個屬性也比較有用,那就是 http.nonProxyHosts
,它用來指定哪些主機不使用代理,如果有多個,用英文豎線(|
)分隔,可以使用星號 (*
)作為通配符。
下表是常用協議對應的代理屬性:
協議 | 屬性(代理主機/代理端口/不使用代理的主機列表) | 默認值 |
---|---|---|
HTTP | http.proxyHost | <none> |
http.proxyPort | 80 | |
http.nonProxyHosts | <none> | |
HTTPS | https.proxyHost | <none> |
https.proxyPort | 443 | |
https.nonProxyHosts | <none> | |
FTP | ftp.proxyHost | <none> |
ftp.proxyPort | 80 | |
ftp.nonProxyHosts | <none> | |
SOCKS | socksProxyHost | <none> |
socksProxyPort | 1080 |
詳細介紹請參考官方說明:Java Networking and Proxies