天天看點

使用Jsoup根據Url解析HTML

需求:根據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在浏覽器中可以檢視

使用Jsoup根據Url解析HTML

如果代理伺服器需要使用者登入,還需要設定使用者名和密碼。(如果不設定,傳回狀态碼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

使用Jsoup根據Url解析HTML

選擇 Access rules ----> Edit ----> Add

在Resolution 中選擇 Accessible  ,在 Rule Pattern中輸入 **   。OK儲存即可

使用Jsoup根據Url解析HTML

上一段整理後的代碼

//使用代理伺服器,添加這段代碼塊 -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這樣判斷編碼格式不行,方法已注掉