需求:根據Url抓取并解析HTML
1、開發過程中一直連接配接逾時:
String url = "http://www.xinhuanet.com";
Document doc = Jsoup.connect(url).get();
java.net.ConnectException: Connection timed out: connect
本人小白一個,經老員工指點,才知道公司通路外網中間有一層代理
2、通過HttpURLConnection使用代理通路外網
經大神指明方向,多方百度後,問題變為由HttpURLConnection使用代理爬取資源,然後再用jsoup解析。
且HttpURLConnection支援http和https
String url = "http://www.xinhuanet.com";
System.getProperties().put("proxySet", "true");
//這裡設定IP,不要用域名
System.getProperties().setProperty("http.proxyHost", "代理IP");
System.getProperties().setProperty("http.proxyPort", "端口号");
URL url2 = new URL(url);
HttpURLConnection conn = (HttpURLConnection)url2.openConnection();
conn.setRequestMethod("GET");
int status = conn.getResponseCode();
System.out.println(status);
代理IP在浏覽器中可以檢視

如果代理伺服器需要使用者登入,還需要設定使用者名和密碼。(如果不設定,傳回狀态碼407,提示需要代理授權)
java.io.IOException: Server returned HTTP response code: 407 for URL: http://www.xinhuanet.com
下面是加上使用者登入的代碼
String url = "http://www.xinhuanet.com";
System.getProperties().put("proxySet", "true");
//這裡設定IP,不要用域名
System.getProperties().setProperty("http.proxyHost", "代理IP");
System.getProperties().setProperty("http.proxyPort", "端口号");
URL url2 = new URL(url);
HttpURLConnection conn = (HttpURLConnection)url2.openConnection();
conn.setRequestMethod("GET");
//設定你的使用者名和密碼 例如 username=admin,password=123456
String authentication = "admin:123456";
//需要用BASE64Encoder進行編碼轉換
String encodedLogin = new BASE64Encoder().encode(authentication.getBytes());
conn.setRequestProperty("Proxy-Authorization", " Basic " + encodedLogin);
int status = conn.getResponseCode();
System.out.println(status);
3、解決Eclipse中無法直接使用Base64Encoder的問題
右鍵項目名稱 ----> Build Path ----> Configure Build Path
選擇 Access rules ----> Edit ----> Add
在Resolution 中選擇 Accessible ,在 Rule Pattern中輸入 ** 。OK儲存即可
上一段整理後的代碼
//使用代理伺服器,添加這段代碼塊 -START-
static{
System.getProperties().put("proxySet", "true");
System.getProperties().setProperty("http.proxyHost", "代理IP");
System.getProperties().setProperty("http.proxyPort", "代理端口号");
}
//使用代理伺服器,添加這段代碼塊 -END-
//擷取Jsoup的Document
public Document getDoc(String strUrl){
Document doc = null;
InputStream in = null;
try {
URL url = new URL(strUrl);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
//使用代理且需要登入,添加這段代碼
/*conn.setRequestProperty("Proxy-Authorization", " Basic " +
new BASE64Encoder().encode("使用者名:密碼".getBytes()));*/
//該項必須配置,很多網站會拒絕非浏覽器的通路,不設定會傳回403,通路被伺服器拒絕
conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)");
conn.setRequestMethod("GET");
conn.setRequestProperty("Content-type", "text/html");
conn.setRequestProperty("Connection", "close");
conn.setUseCaches(false);
conn.setConnectTimeout(5 * 1000);
String encode = getEncode(conn.getHeaderField("Content-Type"));
in = conn.getInputStream();
doc = Jsoup.parse(in,encode,strUrl);
} catch (Exception e) {
e.printStackTrace();
}finally{
if(null != in){
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return doc;
}
//有的HTML頁是UTF-8,有的是GBK,如果頁面指定了編碼格式,直接取來用,沒指定就預設用UTF-8了
/*publicString getEncode(String headerField) {
String encode = "utf-8";
if(null == headerField || "".equals(headerField)){
return encode;
}
headerField = headerField.toLowerCase();
if(headerField.contains("charset=") && !headerField.contains("charset=utf-8")){
if(headerField.contains("charset=gbk")){
encode = "gbk";
}else if(headerField.contains("charset=gb2312")){
encode = "gb2312";
}else if(headerField.contains("charset=iso-8859-1")){
encode = "iso-8859-1";
}
}
return encode;
}*/
//追加 getEncode這樣判斷編碼格式不行,方法已注掉