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

有关httpclient:

HttpClient相比传统JDK自带的URLConnection,增加了易用性和灵活性,它不仅使客户端发送Http请求变得容易,而且也方便开发人员测试接口(基于Http协议的),提高了开发的效率,也方便提高代码的健壮性。因此熟练掌握HttpClient是很重要的必修内容,掌握HttpClient后,相信对于Http协议的了解会更加深入。

org.apache.commons.httpclient.HttpClient与org.apache.http.client.HttpClient的区别

Commons的HttpClient项目现在是生命的尽头,不再被开发,  已被Apache HttpComponents项目HttpClient和HttpCore  模组取代,提供更好的性能和更大的灵活性。

一、简介
HttpClient是Apache Jakarta Common下的子项目,用来提供高效的、最新的、功能丰富的支持HTTP协议的客户端编程工具包,并且它支持HTTP协议最新的版本和建议。HttpClient已经应用在很多的项目中,比如Apache Jakarta上很著名的另外两个开源项目Cactus和HTMLUnit都使用了HttpClient。

那么这里就简单写写如何获取网页源码:

maven依赖:

    <!-- httpclient的依赖 -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.2</version>
        </dependency>

这里最大的问题就是编码的问题,如果编码不是合适的话,就会出现中文乱码情况。

一般是通过两种方式来获取编码,一种是从响应头获取,一种是从网页源码的meta中获取。

这两种方法要结合使用。一般步骤是先从响应头获取,如果响应头没有,就要到网页源码meta中获取,如果还没有,就要设置默认编码。

我的代码如下:

package httpclient.download;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

/**
 * httpclient来下载网页源码。
 *
 * @author 徐金仁
 *
 *关于网页下载最大的问题是编码的问题
 *
 */
public class Download {

    public String getHtmlSource(String url){
        String htmlSource = null;
        String finallyCharset = null;
        //使用httpclient下载
        //创建一个httpclient的引擎
        CloseableHttpClient httpClient = HttpClients.createDefault();
        //创建一个httpGet对象,用于发送get请求,如果要发post请求,就创建一个post对象
        HttpGet get = new HttpGet(url);
        try {

            //发送get请求,获取一个响应
            CloseableHttpResponse response= httpClient.execute(get);

            //获取这次响应的实体,接下来所有的操作都是基于此实体完成,
            HttpEntity entity = response.getEntity();

            //方法还是两个,先从header里面来查看,如果没有,再从meta里面查看

            //这个方法主要是从header里面来获取,如果没有,会返回一个null
            finallyCharset = EntityUtils.getContentCharSet(entity);
            System.out.println("编码如下:");
            System.out.println("charset1 = " + finallyCharset);
            byte[] byteArray = null;

            if(finallyCharset == null){
                     //如果header里面没有,则要从meta里面来获取,为了节约网络资源,网页只读取一次,
                    /*
                     * 那么,就有几个关系 :url->字符流->子节流->字符串
                     * 这里可以用子节数组来作为中间的过渡,从字节数组这里获取到编码,再通过正确的编码变为字符串
                     */
                     byteArray = convertInputStreamToByteArray(entity.getContent());
                     if(byteArray == null){
                            throw new Exception("字节数组为空");
                        }
                        //接下来要从字节数组中获取到meta里面的chatset
                        finallyCharset = getCharsetFromMeta(byteArray);
                        System.out.println("charset2 = " + finallyCharset);
                        if(finallyCharset == null){
                            //如果没有找到
                            finallyCharset = "UTF-8"; //则等于默认的
                            System.out.println("charset3 = " + finallyCharset);
                        }
                        //如果找到了就更好
                    }
            System.out.println("charset = " + finallyCharset);
                htmlSource = new String(byteArray, finallyCharset);
        }catch (IOException e) {
            e.printStackTrace();

    } catch (Exception e) {
            e.printStackTrace();
        }
        return htmlSource;
}

        /**
         * 将一个输入流转化为一个字节数组
         * @param content
         * @param defaultCharset
         * @return
         * @throws IOException
         */
        public  byte[] convertInputStreamToByteArray(InputStream content) throws IOException {
            //输入流转化为一个字节数组
            byte[] by = new byte[4096];
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            int l = -1;
            while((l = content.read(by)) > 0){
                bos.write(by, 0, l);
            }
            byte[] s = bos.toByteArray();
            return s;
        }

        /**
         * 从字节数组中获取到meta里面的charset的值
         * @param byteArray
         * @return
         * @throws IOException
         */
        public  String getCharsetFromMeta(byte[] byteArray) throws IOException {
            //将字节数组转化为bufferedReader,从中一行行的读取来,再判断
            String htmlSource = new String(byteArray);
            StringReader in = new StringReader(htmlSource);
            BufferedReader reader = new BufferedReader(in);
            String line = null;
            while((line = reader.readLine()) != null){
                line = line.toLowerCase();
                if(line.contains("<meta")){
                    //通过正则表达式来获取网页中的编码
                    String regex = "\"text/html;[\\s]*?charset=([\\S]*?)\"";
                    Pattern pattern = Pattern.compile(regex);
                    if(pattern != null){
                        Matcher matcher = pattern.matcher(htmlSource);
                        if(matcher != null){
                            if(matcher.find()){
                                return  matcher.group(1);
                            }
                        }
                    }
                }else{
                    continue;
                }
            }
            return null;
        }
        //测试:
        public static void main(String[] args) {
            String htmlsource = new Download().getHtmlSource("http://news.youth.cn/gn/");
            System.out.println("源码:");
            System.out.println(htmlsource);
        }
}

结果:

收藏的相关博客:

  https://blog.csdn.net/justry_deng/article/details/81042379

  https://blog.csdn.net/w372426096/article/details/82713315

原文地址:https://www.cnblogs.com/1998xujinren/p/12360758.html

时间: 2024-10-09 14:19:27

httpclient下载网页源码---java基础爬虫的相关文章

Java的URL来下载网页源码

import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.Reader; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; @SuppressWarn

bootstrap后台框架源码 java图片爬虫 自定义表单

获取[下载地址]   [免费支持更新]三大数据库 mysql  oracle  sqlsever   更专业.更强悍.适合不同用户群体[新录针对本系统的视频教程,手把手教开发一个模块,快速掌握本系统] A 集成代码生成器 [正反双向(单表.主表.明细表.树形表,开发利器)+快速构建表单; freemaker模版技术 ,0个代码不用写,生成完整的一个模块,带页面.建表sql脚本,处理类,service等完整模块B 集成阿里巴巴数据库连接池druid;  数据库连接池  阿里巴巴的 druid.Dr

Java全新高大尚HTML5 bootstrap后台框架源码 java图片爬虫

获取[下载地址]   QQ: 313596790   [免费支持更新]三大数据库 mysql  oracle  sqlsever   更专业.更强悍.适合不同用户群体[新录针对本系统的视频教程,手把手教开发一个模块,快速掌握本系统]A 集成代码生成器(开发利器);                                         技术:313596790   增删改查的处理类,service层,mybatis的xml,SQL( mysql   和oracle)脚本,   jsp页面

整合mybatis框架源码 java图片爬虫

获取[下载地址]   [免费支持更新]三大数据库 mysql  oracle  sqlsever   更专业.更强悍.适合不同用户群体[新录针对本系统的视频教程,手把手教开发一个模块,快速掌握本系统] A 集成代码生成器 [正反双向(单表.主表.明细表.树形表,开发利器)+快速构建表单; freemaker模版技术 ,0个代码不用写,生成完整的一个模块,带页面.建表sql脚本,处理类,service等完整模块B 集成阿里巴巴数据库连接池druid;  数据库连接池  阿里巴巴的 druid.Dr

bootstrap后台框架源码 java图片爬虫

获取[下载地址]   [免费支持更新]三大数据库 mysql  oracle  sqlsever   更专业.更强悍.适合不同用户群体[新录针对本系统的视频教程,手把手教开发一个模块,快速掌握本系统] A 集成代码生成器 [正反双向(单表.主表.明细表.树形表,开发利器)+快速构建表单; freemaker模版技术 ,0个代码不用写,生成完整的一个模块,带页面.建表sql脚本,处理类,service等完整模块B 集成阿里巴巴数据库连接池druid;  数据库连接池  阿里巴巴的 druid.Dr

Java全新高大尚HTML5 bootstrap后台框架源码 java图片爬虫 自定义表单

获取[下载地址]   QQ: 313596790   [免费支持更新]三大数据库 mysql  oracle  sqlsever   更专业.更强悍.适合不同用户群体[新录针对本系统的视频教程,手把手教开发一个模块,快速掌握本系统]A 集成代码生成器(开发利器);                                         技术:313596790   增删改查的处理类,service层,mybatis的xml,SQL( mysql   和oracle)脚本,   jsp页面

后台框架源码 java图片爬虫 自定义表单

获取[下载地址]     [免费支持更新]三大数据库 mysql  oracle  sqlsever   更专业.更强悍.适合不同用户群体[新录针对本系统的视频教程,手把手教开发一个模块,快速掌握本系统] A 集成代码生成器 [正反双向(单表.主表.明细表.树形表,开发利器)+快速构建表单; freemaker模版技术 ,0个代码不用写,生成完整的一个模块,带页面.建表sql脚本,处理类,service等完整模块B 集成阿里巴巴数据库连接池druid;  数据库连接池  阿里巴巴的 druid.

python下载网页源码 写入文本

import urllib.request,io,os,sysreq=urllib.request.Request("http://echophp.sinaapp.com/uncategorized/194.html")f=urllib.request.urlopen(req)s=f.read()s=s.decode('utf-8','ignore')mdir=sys.path[0]+'/'file=open(mdir+'html.txt','a',1,'gbk')file.write

java中用jsoup抓取网页源码,并批量下载图片

一.导入jsoup的核心jar包jsoup-xxx.jar jar包下载地址:jsoup-1.8.2.jar 中文API地址:http://www.open-open.com/jsoup/parsing-a-document.htm 二.java中用jsoup抓取网页源码,并批量下载图片 package com.dgh.test; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; i