Java网络爬虫--HttpClient

目录标题

  • 技术介绍
    • 有什么优点?
    • 怎么在项目中引入?
  • 请求URL
    • EntityUtils 类
    • GET请求
    • 带参数的GET请求
    • POST请求
  • 总结

技术介绍

HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、功能丰富的、支持 HTTP 协议的客户端编程工具包。相比于 java.net 包中提供的 URLConnection 与HttpURLConnection,HttpClient 增加了易用性和灵活性。在 Java 网络爬虫实战中,经常使用 HttpClient 向服务器发送请求,获取响应资源。

网络爬虫就是用程序帮助我们访问网络上的资源,我们一直以来都是使用HTTP协议访问互联网的网页,网络爬虫需要编写程序,在这里使用同样的HTTP协议访问网页。 这里我们使用Java的HTTP协议客户端 HttpClient这个技术,来实现抓取网页数据。

有什么优点?

  1. 易用性和灵活性: HttpClient 提供了更简洁、易读的 API,使得发送 HTTP 请求和处理响应变得更加直观和容易。其面向对象的设计和灵活的配置选项使得开发者能够更容易地进行定制和扩展。
  2. 功能丰富: HttpClient 提供了丰富的功能和扩展,包括但不限于请求和响应拦截器、连接池管理、Cookie 管理、身份验证、代理支持等。这些功能大大简化了复杂任务的处理,例如处理会话、保持持久连接等。
  3. 性能优越: HttpClient 的设计注重性能和效率,内部采用了连接池等机制,减少了连接的建立和关闭次数,提高了系统的整体性能。同时,HttpClient 采用了并发处理机制,允许多个请求并行执行,提高了系统的吞吐量。
  4. 协议支持: HttpClient 支持多种协议,不仅仅局限于 HTTP 和 HTTPS,还包括 FTP、HTTP/2 等。这使得 HttpClient 成为一个通用的网络编程工具,适用于各种场景。
  5. 错误处理和异常管理: HttpClient 提供了详细的错误处理和异常管理机制,使得开发者能够更容易地诊断和处理网络请求中可能出现的问题。这对于构建健壮的爬虫系统非常重要。

怎么在项目中引入?

环境准备:会使用Maven新建项目,在pom.xml中导入依赖:

      <!-- HttpClient -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
        </dependency>

请求URL

HttpClient 的重要功能是执行 HTTP 请求方法,获取响应资源。在执行具体的请求方法之前,需要实例化 HttpClient
HttpClient 的重要功能是执行 HTTP 请求方法,获取响应资源。在执行具体的请求方法之前,需要实例化 HttpClient。

基本步骤

  1. 创建 HttpClient 实例

    CloseableHttpClient httpClient4 = HttpClients.createDefault();

  2. 创建请求方法实例

    在网络爬虫中,常用的类是 HttpGet 与 HttpPost。

  3. 执行请求

    基于实例化的 HttpClient,可以调用 execute(HttpUriRequest request)方法执行数据请求,返回 HttpResponse

  4. 获取响应信息

       //获取具体响应信息
        System.out.println("response:" + httpResponse);
        //响应状态
        String status = httpResponse.getStatusLine().toString();
        System.out.println("status:" + status);
        //获取响应状态码
        int StatusCode = httpResponse.getStatusLine().getStatusCode();
        System.out.println("StatusCode:" + StatusCode);
        ProtocolVersion protocolVersion = httpResponse.
                getProtocolVersion(); //协议的版本号
        System.out.println("protocolVersion:" + protocolVersion);
        //是否OK 
        String phrase = httpResponse.getStatusLine().getReasonPhrase();
        System.out.println("phrase:" + phrase);
        Header[] headers = httpResponse.getAllHeaders();
        System.out.println("输出头信息为:");

EntityUtils 类

EntityUtils 类的作用是操作响应实体

//可以设置编码
public static String toString(final HttpEntity entity, final String 
defaultCharset) 
//可以设置编码
public static String toString(final HttpEntity entity, final
Charset defaultCharset) 
//使用默认编码ISO-8859-1 
public static String toString(final HttpEntity entity)

另外,EntityUtils 类还提供了将响应实体转化成字节数组的方法,如下:
针对图片、PDF 和压缩包等文件,可以先将响应实体转化成字节数组,之后,利用缓冲流的方式写入指定文件,

public static byte[] toByteArray(final HttpEntity entity)

GET请求

public class GetTest {
    public static void main(String[] args) throws Exception {
        // 创建HttpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();

        // 声明访问地址
        HttpGet httpGet = new HttpGet("https://www.autohome.com.cn/bestauto/");

        CloseableHttpResponse response = null;
        try {
            // 发起请求
            response = httpClient.execute(httpGet);

            // 判断状态码是否是200
            if (response.getStatusLine().getStatusCode() == 200) {
                // 解析数据
                String content = EntityUtils.toString(response.getEntity(), "UTF-8");
                System.out.println(content.length());
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            // 释放连接
            if (response != null) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                httpClient.close();
            }
        }
    }

}

在这里插入图片描述

使用Apache HttpClient库进行HTTP GET请求的Java程序。下面是代码的详细解释:

  1. 创建HttpClient对象:使用HttpClients.createDefault()方法来创建一个CloseableHttpClient实例,这个实例可以用来发送HTTP请求和处理HTTP响应。
  2. 声明访问地址:通过HttpGet对象,指定要请求的URL地址("https://www.autohome.com.cn/bestauto/")。
  3. 发起请求:使用httpClient.execute(httpGet)来发送HTTP GET请求。这个方法会返回一个CloseableHttpResponse对象来表示服务器的响应。
  4. 判断状态码:通过response.getStatusLine().getStatusCode()获取HTTP响应的状态码,并判断是否等于200,即HTTP OK状态。状态码200表示请求已成功被服务器接收、理解,并接受。
  5. 解析数据:如果状态码为200,则使用EntityUtils.toString(response.getEntity(), "UTF-8")将响应实体转换为字符串。这里指定了字符集为UTF-8,以确保正确处理字符。
  6. 输出内容长度:输出解析后的内容长度,通过content.length()获取。
  7. 异常处理:如果在请求过程中发生异常,异常会被捕获并打印堆栈跟踪。
  8. 释放资源:在finally块中,确保关闭响应和HttpClient实例,以释放系统资源。
  9. 异常处理:如果关闭响应或HttpClient时发生IOException异常,异常同样会被捕获并打印堆栈跟踪。

带参数的GET请求

public static void main(String[] args) throws Exception {
    // 创建HttpClient对象
    CloseableHttpClient httpClient = HttpClients.createDefault();

    // 声明访问地址
    // https://www.baidu.com/s?wd=汽车之家
    URI uri = new URIBuilder("https://www.baidu.com/s").setParameter("wd", "汽车之家").build();

    // 创建HttpGet请求对象
    HttpGet httpGet = new HttpGet(uri);

    CloseableHttpResponse response = null;
    try {
        // 发起请求
        response = httpClient.execute(httpGet);

        // 判断状态码是否是200
        if (response.getStatusLine().getStatusCode() == 200) {
            // 解析数据
            String content = EntityUtils.toString(response.getEntity(), "UTF-8");
            System.out.println(content.length());
        }
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } finally {
        // 释放连接
        if (response != null) {
            try {
                response.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            httpClient.close();
        }
    }
}

在构造HTTP GET请求时使用了URIBuilder来构建请求的URI。主要区别在于如何构造和设置请求的URL,以及如何传递查询参数:

  1. 使用URIBuilder:在这段代码中,URIBuilder类被用来构造带有查询参数的URI。new URIBuilder("https://www.baidu.com/s")创建了一个指向百度搜索的URIBuilder实例,然后通过.setParameter("wd", "汽车之家")方法设置了一个查询参数wd,其值为"汽车之家"。这个参数是用于百度搜索的关键词参数。build()方法用来生成最终的URI对象。
  2. 创建HttpGet对象时使用URI:在创建HttpGet对象时,直接使用uri对象,而不是之前的代码中直接传递URL字符串。这种方式更加灵活,因为可以在不改变基础URL的情况下动态地添加或修改查询参数。
  3. 其他部分相同:除了构建请求的URL部分以外,其他的代码逻辑和处理方式与上一段代码基本一致。都是创建HttpClient对象,发起请求,检查响应状态码,解析响应内容,并在最后释放资源。

POST请求

public static void main(String[] args) throws Exception {
    // 创建HttpClient对象
    CloseableHttpClient httpClient = HttpClients.createDefault();

    // 声明访问地址
    HttpPost httpPost = new HttpPost("https://www.oschina.net");

    // 设置User-Agent属性,解决开源中国限制的问题
    httpPost.setHeader("User-Agent", "");

    CloseableHttpResponse response = null;
    try {
        // 发起请求
        response = httpClient.execute(httpPost);

        // 判断状态码是否是200
        if (response.getStatusLine().getStatusCode() == 200) {
            // 解析数据
            String content = EntityUtils.toString(response.getEntity(), "UTF-8");
            System.out.println(content.length());
        }
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } finally {
        // 释放连接
        if (response != null) {
            try {
                response.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            httpClient.close();
        }
    }
}

在这里插入图片描述

response.getEntity() 是Apache HttpClient库中HttpResponse对象的一个方法,用于获取HTTP响应中的实体部分
服务器可能会根据User-Agent判断请求是否来自真正的用户还是爬虫。例如,一些网站可能会限制爬虫的访问,只允许真正的用户访问。此时,爬虫需要设置一个可以被服务器接受的User-Agent,才能成功获取数据。在实际应用中,应该根据目标服务器的要求设置合适的User-Agent。

总结

HttpClient是Apache Common下的子项目,提供了高效、功能丰富的HTTP客户端编程工具包。相比于java.net中的URLConnection和HttpURLConnection,HttpClient增加了易用性和灵活性。它具有以下优点:易用性和灵活性、功能丰富、性能优越、协议支持、错误处理和异常管理。在使用HttpClient进行网络爬虫时,首先需要创建HttpClient实例,然后执行请求,获取响应信息。
HttpClient提供了详细的错误处理和异常管理机制,方便构建健壮的爬虫系统。在使用HttpClient进行HTTP请求时,可以使用HttpGet和HttpPost方法,并在发起请求之前设置请求方法和参数。还可以使用EntityUtils类来操作响应实体,并将响应实体转化为字节数组或写入指定文件。
在发起GET请求时,可以使用URIBuilder类构建带参数的URI,并使用HttpGet对象发送请求。在发起POST请求时,可以使用HttpPost对象发送请求,并设置User-Agent属性来解决限制问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/305938.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Pycharm中如何配置python环境(conda)

首先在pycharm中点击 "File" > "Settings" 再次点击如下操作&#xff1a; 点击Python Interpreter的最右侧按钮&#xff0c;点击Show All... 找到python文件 最后点击OK

ros gazebo机械臂仿真,手动控制与MoveIt自动控制

本文总结归纳古月居胡春旭ros机械臂教程&#xff0c;给出了一些error的解决方法&#xff0c;补充了通过python运行moveit。十分建议去看github huchunxu源代码的repository。 创建机械臂的xacro模型 首先创建一个工作空间&#xff0c;在工作空间中创建arm_description功能包。…

Qt应用-实现图像截取功能类似QQ上传头像截取功能

本文演示利用Qt实现图像截取功能类似QQ上传头像截取功能。 效果如下,通过移动中间的裁剪区域可以获得一张裁剪后的图片。 目录

MySQL进阶之(二)索引的数据结构

二、索引的数据结构 2.1 关于索引2.1.1 什么是索引&#xff1f;2.1.2 为什么使用索引&#xff1f;2.1.3 索引的优缺点01、优点02、缺点 2.1.4 一个简单的索引设计方案 2.2 InnoDB 中的索引设计2.2.1 迭代①&#xff1a;目录项记录的页2.2.2 迭代②&#xff1a;多个目录项记录的…

程序媛的mac修炼手册-- 终端(terminal)常用命令

「终端&#xff08;terminal&#xff09;」相当于macOS的一个 App &#xff0c;它的特殊之处是&#xff0c;它是管理其它App的App&#xff0c;操作主要通过命令行界面 (CLI) 。 相比于我们日常熟悉的用户界面&#xff08;User Interface&#xff0c;UI&#xff09;&#xff0c…

顺序栈之共享栈实现——C语言

参考书&#xff1a;数据结构教程 第5版 李葆春 P83 #include <stdio.h> #include <string.h> #include <stdlib.h>#define MaxSize 10/*共享栈*/ typedef struct {char data[MaxSize];int top1,top2,len; }DStack;/*初始化*/ void InitStack(DStack *s){s-…

HCIA-Datacom题库(自己整理分类的)_17_简单的命令判断【11道题】

1.华为AR路由器的命令行界面下&#xff0c;save命令的作用是保存当前的系统时间。 解析&#xff1a;Save保存配置 2.VRP界面下&#xff0c;使用命令delete vrpcfg.zp删除文件&#xff0c;必须在回收站中清空&#xff0c;才能彻底删除文件。√ 解析&#xff1a;delete删除到回…

Selenium 学习(0.19)——软件测试之基本路径测试法——拓展案例

1、案例 请使用基本路径法为变量year设计测试用例&#xff0c;year的取值范围是1000<year<2001。代码如下&#xff1a; 2、步骤 先画控制流程图 再转化为控制流图&#xff08;标出节点&#xff09; V(G) 总区域数 4 V(G) E - N 2 (边数 - 节点数 2…

AArch64 Exception Model学习

提示 该博客主要为个人学习&#xff0c;通过阅读官网手册整理而来&#xff08;个人觉得阅读官网的英文文档非常有助于理解各个IP特性&#xff09;。若有不对之处请参考参考文档&#xff0c;以官网文档为准。 1 Privilege and Exception Levels 1.1 为什么要划分权限&#xf…

5分钟使用Hologres实时湖仓加速分析挑战赛来袭

活动简介 5分钟快速使用Hologres实时湖仓能力&#xff0c;加速分析数据湖OSS上Hudi、Delta、Paimon、ORC等格式数据&#xff0c;赢取精美礼品 活动入口&#xff1a;Hologres实时湖仓分析挑战赛-阿里云开发者社区 或点击文末【阅读全文】参与挑战 活动时间 2024年1月4日-202…

爬取国家法律法规数据库法律条文

代码展现&#xff1a; import requests import os filename 法律条文\\ if not os.path.exists(filename):os.mkdir(filename) url https://flk.npc.gov.cn/api/? data {type: flfg,searchType: title;vague,sortTr: f_bbrq_s;desc,gbrqStart: ,gbrqEnd: ,sxrqStart: ,sx…

【C语言】TCP测速程序

一、服务端 下面是一个用 C 语言编写的测试 TCP 传输速度的基本程序示例。 这只是一个简单示例&#xff0c;没有做详细的错误检查和边缘情况处理。在实际应用中&#xff0c;可能需要增加更多的功能和完善的异常处理机制。 TCP 服务器 (server.c): #include <stdio.h> #…

【c++】vector模拟

> 作者简介&#xff1a;დ旧言~&#xff0c;目前大二&#xff0c;现在学习Java&#xff0c;c&#xff0c;c&#xff0c;Python等 > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;能手撕vector模拟 > 毒鸡汤&#xff1a;在等待…

动态规划(分割等和子集)

416. 分割等和子集 题目难易&#xff1a;中等 给定一个只包含正整数的非空数组。是否可以将这个数组分割成两个子集&#xff0c;使得两个子集的元素和相等。 注意: 每个数组中的元素不会超过 100 数组的大小不会超过 200 示例 1: 输入: [1, 5, 11, 5] 输出: true 解释: 数…

STM32入门教程-2023版【3-3】gpio输入

关注 星标公众号 不错过精彩内容 大家好&#xff0c;我是硬核王同学&#xff0c;最近在做免费的嵌入式知识分享&#xff0c;帮助对嵌入式感兴趣的同学学习嵌入式、做项目、找工作! 上两小节我们已经把GPIO的结构和8种输入输出模式都讲完了&#xff0c;到这里还不懂的可以回…

浅析内存一致性:内存屏障

文章目录 概述内存乱序访问Store Buffer和Invalidate QueueStore BufferStore ForwardingStore Buffer与内存屏障 Invalidate QueueInvalidate Queue与内存屏障 内存屏障分类编译器屏障CPU内存屏障 相关参考 概述 内存屏障&#xff0c;是一类同步屏障指令&#xff0c;是CPU或编…

Java中的输入输出处理(一)

文件 文件&#xff1a;文件是放在一起的数据的集合。比如1.TXT。 存储地方&#xff1a;文件一般存储在硬盘&#xff0c;CD里比如D盘 如何访问文件属性&#xff1a;我们可以通过java.io.File类对其处理 File类 常用方法&#xff1a; 方法名称说明boolean exists()判断文件或目…

处理机调度与死锁

目录 进程调度算法先来先服务调度算法FCFS最短作业优先调度算法SJF最高优先级调度算法***HPF***高响应比优先调度算法 ***HRRN***时间片轮转调度算法***RR***多级队列调度算法MFQ 进程调度算法 进程调度算法也称为CPU调度算法 当 CPU 空闲时&#xff0c;操作系统就选择内存中…

一天一个设计模式---工厂方法

概念 工厂模式是一种创建型设计模式&#xff0c;其主要目标是提供一个统一的接口来创建对象&#xff0c;而不必指定其具体类。工厂模式将对象的实例化过程抽象出来&#xff0c;使得客户端代码不需要知道实际创建的具体类&#xff0c;只需通过工厂接口或方法来获取所需的对象。…

uniapp中uview组件库丰富的Table 表格的使用方法

目录 #平台差异说明 #基本使用 #兼容性 #API #Table Props #Td Props #Th Props 表格组件一般用于展示大量结构化数据的场景 #平台差异说明 AppH5微信小程序支付宝小程序百度小程序头条小程序QQ小程序√√√√√√√ #基本使用 本组件标签类似HTML的table表格&#…