urconnection下载网页源码 ----java基础爬虫

关于下载网页源码再来解析,这是一套简单的java爬虫

这里简单说说网页的下载。

  其实用很多方法,比较好用的有httpclient。但是原理都是从URLConnection这里衍生来的。所以这先讲讲URLConnection下载网页源码的方式。

  这个下载其实方法不难,难的是如何寻找到合适的编码。如果编码不对的话,中文容易造成乱码的情况。那么,有什么方法?

方法一:

  从http返回的响应头获取。在使用urlconnection链接后,会有一个响应头返回如连接 :https://www.w3school.com.cn/,这里的响应头没有给出编码集,

 

如果连接:https://i-beta.cnblogs.com,所以这是一种方法,

 

 方法二:

 

  第二种方法是从网页的源码中获取,毕竟编码不同的话不会影响英文显示的。

如:

 

 

 

 所以可以用这两种方式,一定要结合使用,先从http的响应头部获取,如果找到编码的话,那个一定是正确的。至于方法二目前使用状态是正确的。如果两种

方式都不能获取到,则只能使用默认的编码了。

 

代码如下:

  1 package com.xu.download;
  2 
  3 import java.io.BufferedReader;
  4 import java.io.IOException;
  5 import java.io.InputStream;
  6 import java.io.InputStreamReader;
  7 import java.net.MalformedURLException;
  8 import java.net.URL;
  9 import java.net.URLConnection;
 10 import java.util.List;
 11 import java.util.Map;
 12 
 13 import javax.net.ssl.HttpsURLConnection;
 14 
 15 /**
 16  * @author 徐金仁
 17  * 使用urlpconnection下载网页源码, --初级java爬虫
 18  */
 19 public class Download {
 20     //最困难的地方:编码
 21     /*
 22      * 网页都是不同的人制作的,他们的编码不会保持一致。我们如果用错了编码的话,如果网页中含有中文,
 23      * 则会出现乱码
 24      */
 25     
 26     
 27     /**
 28      * 下载网页源码
 29      * @param url 下载的地址
 30      * @return 返回的是网页源码
 31      * @throws Exception 
 32      */
 33     public String download(String url){
 34         StringBuffer htmlSource = new StringBuffer();
 35         URL url_ = null;
 36         InputStream is = null;
 37         
 38         BufferedReader reader = null;
 39         try {
 40             //定位资源
 41             url_ = new URL(url);
 42             //打开链接
 43             URLConnection con = url_.openConnection();
 44             
 45             //获取正确的编码集
 46             String charset = getCharset(url, "utf-8");
 47             
 48             System.out.println("charset = " + charset);
 49             
 50             is = con.getInputStream();
 51             //使用正确的编码来编码流
 52             reader = new BufferedReader(new InputStreamReader(is,charset));
 53             
 54             String line = null;
 55             //读写
 56             while((line = reader.readLine()) != null){
 57                 htmlSource.append("\n");
 58                 htmlSource.append(line);
 59             }
 60         
 61         } catch (IOException e) {
 62             e.printStackTrace();
 63         }finally{
 64             if(is != null){
 65                 try {
 66                     is.close();
 67                 } catch (IOException e) {
 68                     // TODO Auto-generated catch block
 69                     e.printStackTrace();
 70                 }
 71             }
 72             
 73             if(reader != null){
 74                 try {
 75                     reader.close();
 76                 } catch (IOException e) {
 77                     // TODO Auto-generated catch block
 78                     e.printStackTrace();
 79                 }
 80             }
 81         }
 82         return htmlSource.toString();
 83     }
 84     
 85     /**
 86      * 获取正确的编码集
 87      * 要从两个个地方下手
 88      * 1.http链接的头部信息
 89      * 2.html源码中显示表明的编码
 90      * @param url 网页地址
 91      * @param string 默认的编码集
 92      * @return
 93      * @throws IOException 
 94      */
 95     private String getCharset(String url, String defaultCharset) throws IOException {
 96         String charset = null;
 97         
 98         URL url_ = null;
 99         //定位资源
100         url_ = new URL(url);
101         //打开链接
102         URLConnection con = url_.openConnection();
103         //获取http响应回来的头部信息
104         Map<String, List<String>> headerField = con.getHeaderFields();
105         System.out.println(headerField);
106         List<String> line = headerField.get("Content-Type");
107         if(line == null){
108             line = headerField.get("content-type");
109         }
110         
111         if(line != null){
112             for(String st : line){
113                 if(st.contains("charset")){
114                     //说明找到了编码
115                     charset = st.split(";")[1].split("=")[1].trim();
116                     break;
117                 }
118             }
119         }
120         //说明没有找到,要到源码里面取寻找
121         if(charset == null){
122             //获取流
123             InputStream is;
124             is = con.getInputStream();
125             BufferedReader reader = new BufferedReader(new InputStreamReader(is));
126             String line_str = null;
127             String cha = null;
128             //一行行读下去
129             while((line_str = reader.readLine()) != null){
130                 //去掉所有的空格
131                 line_str = line_str.replaceAll(" ", "");
132                 //去掉引号
133                 line_str = line_str.replaceAll("\"", "");
134                 if(line_str.contains("meta")){
135                         if(line_str.contains("charset")){
136                             //将charset开始到最后的双引号为止截取,区间左开右闭
137                             int index = line_str.indexOf("charset");
138                             cha = line_str.substring(index, line_str.indexOf("/", index));
139                             charset = cha.split("=")[1];
140                             System.out.println("c2:" + charset);
141                             break;
142                         }
143                 }
144                 
145             }
146             //说明以上两种方法都没有用
147             if(charset ==null){
148                 //设置为默认的
149                 charset = defaultCharset;
150             }
151         }
152         return charset;
153     }
154     
155     /**
156      * 测试
157      * @param args
158      * @throws Exception
159      */
160     public static void main(String[] args) throws Exception {
161         String htm = new Download().download("https://www.w3school.com.cn/");
162         System.out.println("源码:" + htm);
163     }
164 }

结果如下:

 

 

posted @ 2020-02-24 18:30  陆某人  阅读(208)  评论(0编辑  收藏  举报