解析与使用 Apache HttpClient 进行网络请求和数据抓取

目录

1. 什么是 HttpClient?

2. 基本使用

3. 使用 HttpClient 爬取腾讯天气的数据

4. 爬取拉勾招聘网站的职位信息

5. 总结


前言

        Apache HttpClient 是 Apache 提供的一个用于处理 HTTP 请求和响应的工具类库。它提供了一种便捷、功能强大的方式来发送 HTTP 请求,并解析 HTTP 响应。HttpClient 适用于多种网络请求场景,能够帮助我们高效地与 Web 服务进行交互。

1. 什么是 HttpClient?

        HttpClient 是在 JDK 的基础类库基础上进行封装和增强的一个 HTTP 请求工具库。它提供了更强大、更灵活的功能,比如支持连接池、认证机制、重定向、请求重试等,帮助我们提高开发效率和代码质量。

HttpClient 的核心功能包括:

  • 连接池管理:提高性能,减少资源消耗,复用 TCP 连接。
  • 自动化处理 HTTP 头、请求和响应数据
  • 支持多种认证方式,如 Basic 认证、Digest 认证等。
  • 重定向处理:自动处理 HTTP 重定向。
  • 支持 Cookie 管理
  • 支持并发请求

2. 基本使用

2.1 引入依赖

首先,你需要在项目中引入 HttpClient 的 Maven 依赖。以下是 Apache HttpClient 的 Maven 依赖配置:


    org.apache.httpcomponents
    httpclient
    4.5.13 

2.2 发送 HTTP GET 请求

下面是一个简单的使用示例,展示如何通过 HttpClient 发送一个 HTTP GET 请求:

import org.apache.http.HttpResponse;
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;
import java.io.IOException;

public class HttpClientExample {
    public static void main(String[] args) throws IOException {
        // 创建一个 HttpClient 实例
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            // 创建一个 HttpGet 请求对象
            HttpGet request = new HttpGet("https://www.baidu.com/");
            
            // 执行请求并获取响应
            HttpResponse response = httpClient.execute(request);
            
            // 如果请求成功,返回 200 状态码
            if (response.getStatusLine().getStatusCode() == 200) {
                // 将响应实体转换为字符串
                String responseBody = EntityUtils.toString(response.getEntity(), "UTF-8");
                // 输出响应内容
                System.out.println(responseBody);
            }
        }
    }
}

在上面的代码中,我们使用 HttpClients.createDefault() 创建了一个默认的 HttpClient 实例,然后通过 HttpGet 对象发送了一个请求,并打印了百度主页的 HTML 源码。

解析与使用 Apache HttpClient 进行网络请求和数据抓取_第1张图片

可以看到请求的结果为百度源代码 

3. 使用 HttpClient 爬取腾讯天气的数据

接下来,展示如何使用 HttpClient 来爬取 JSON 格式的天气数据。我们通过发送 HTTP GET 请求,获取腾讯天气 API 返回的 JSON 数据,并进行解析。

3.1 查询天气的json格式数据

解析与使用 Apache HttpClient 进行网络请求和数据抓取_第2张图片

 

我们构造一个 HTTP GET 请求,访问腾讯的天气 API:

import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.util.EntityUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

public class WeatherDemo {
    public static void main(String[] args) {
        // 创建 HttpClient 实例
        CloseableHttpClient httpClient = HttpClients.createDefault();
        try {
            // 设置请求 URL,查询河北省保定市的天气信息
            HttpGet httpGet = new HttpGet("https://wis.qq.com/weather/common?source=pc&weather_type=observe|forecast_1h|forecast_24h&province=%E6%B2%B3%E5%8C%97%E7%9C%81&city=%E4%BF%9D%E5%AE%9A%E5%B8%82&county=");
            
            // 设置请求头
            httpGet.setHeader("Accept", "*/*");
            httpGet.setHeader("User-Agent", "Mozilla/5.0");
            
            // 执行请求,获取响应
            CloseableHttpResponse response = httpClient.execute(httpGet);
            
            // 获取响应的字符串内容
            String responseBody = EntityUtils.toString(response.getEntity(), "UTF-8");
            
            // 解析 JSON 数据
            String jsonString = responseBody.substring(42, responseBody.length() - 1);
            JSONObject json = JSON.parseObject(jsonString);
            JSONObject data = json.getJSONObject("data");
            JSONObject forecast = data.getJSONObject("forecast_24h");
            JSONObject day0 = forecast.getJSONObject("0");

            // 输出天气信息
            System.out.println("夜间风向: " + day0.get("night_wind_direction"));
            
            // 关闭响应对象
            response.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                // 关闭 HttpClient
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

在这个示例中,我们通过解析返回的 JSON 数据,提取了天气信息,并输出了夜间风向。

解析与使用 Apache HttpClient 进行网络请求和数据抓取_第3张图片 

3.2 JSON 解析

通过使用 fastjson 库,我们能够方便地解析 JSON 数据。JSONObject 类提供了 get()getJSONObject()getJSONArray() 方法,方便我们提取对应的值:

  • get():获取某个键对应的值,返回 Object 类型。
  • getJSONObject():获取某个键对应的 JSON 对象,返回 JSONObject 类型。
  • getJSONArray():获取某个键对应的 JSON 数组,返回 JSONArray 类型。

整体代码:

 


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
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.client.methods.CloseableHttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.util.StringUtils;

import java.io.IOException;

public class XXDemo {
    public static void main(String[] args) {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        try {
            HttpGet httpGet = new HttpGet("https://wis.qq.com/weather/common?source=pc&weather_type=observe%7Cforecast_1h%7Cforecast_24h%7Cindex%7Calarm%7Climit%7Ctips%7Crise&province=%E6%B2%B3%E5%8C%97%E7%9C%81&city=%E4%BF%9D%E5%AE%9A%E5%B8%82&county=&callback=jQuery111307985983701500603_1730452291491&_=1730452291493");
            // 设置请求头
            httpGet.setHeader("Accept", "*/*");
            httpGet.setHeader("Accept-Encoding",  "gzip, deflate, br, zstd");
            httpGet.setHeader("Accept-Language", "zh-CN,zh;q=0.9");
            httpGet.setHeader("Cache-Control", "max-age=0");
            httpGet.setHeader("Connection", "keep-alive");
            httpGet.setHeader("Cookie", "pgv_pvid=7587513344; RK=viMJj838H2; ptcz=410fc81f9ad1719db0b83d1ae0b767a81c43f89b4d79b4f22f0f04bf476c4e44; qq_domain_video_guid_verify=50ba34f244950f77; _qimei_uuid42=17c02140117100fd9f4a0a8f7ddb1d4eb0eef0fe2b; _qimei_q36=; _qimei_h38=2db835139f4a0a8f7ddb1d4e02000003017c02; tvfe_boss_uuid=9dd0f4ca6252467b; _qimei_fingerprint=a8fdf4f9656a2285f66b7f0bb5dbefc2; fqm_pvqid=bfdb0333-6586-490e-9451-7e4628f24f32; pgv_info=ssid=s390182559; pac_uid=0_sBk6e1R1P4Zpc");
            httpGet.setHeader("Host", "wis.qq.com");
            httpGet.setHeader("Upgrade-Insecure-Requests", "1");
            httpGet.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36");
            // 执行请求
            CloseableHttpResponse response = httpClient.execute(httpGet);
            // 获取响应实体
            String responseBody = EntityUtils.toString(response.getEntity(),"UTF-8");

            //获取中间json数据
            String subStringA = responseBody.substring(0,42);
            String str = responseBody.replace(subStringA,"");
            String newStr = str.substring(0, str.length()-1);


            //JSON解析----》JSONObject:处理json对象,根据可以值获取value值
            JSONObject json =  JSON.parseObject(newStr); //将字符串转换成json数组
            JSONObject data =  json.getJSONObject("data");
            JSONObject forecast_24h =  data.getJSONObject("forecast_24h");
            JSONObject data0 =  forecast_24h.getJSONObject("0");
            System.out.println(data0.get("night_wind_direction"));

            // 关闭响应对象
            response.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
public class HttpClient {
    public static void main(String[] args) throws IOException {
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpGet request = new HttpGet("https://cdn.mdeer.com/data/yqstaticdata.js");
            CloseableHttpResponse response = httpClient.execute(request);  //发送请求,获取响应
            if (response.getStatusLine().getStatusCode() == 200) {
                String responseBody = EntityUtils.toString(response.getEntity(),"utf-8");

                //获取中间json数据
                String subStringA = responseBody.substring(0, 19);
                String str = responseBody.replace(subStringA, "");
                String newStr = str.substring(0, str.length() - 1);
                //System.out.println(newStr);

                JSONObject json = JSON.parseObject(newStr); //将字符串转换成json数据
                JSONArray cityLists = json.getJSONArray("cityLists");
                for (int i = 0;i

 

4. 爬取拉勾招聘网站的职位信息

除了获取天气数据,我们还可以利用 HttpClient 抓取其他网站的数据。例如,我们可以爬取拉钩招聘网站的职位信息。以下是一个爬取拉钩招聘职位的简单示例:

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class ParseUtils {
    public static final String url = "https://www.lagou.com/wn/zhaopin?kd=Java&city=%E5%8C%97%E4%BA%AC";

    private static List jobs = new ArrayList<>();

    public static void main(String[] args) throws IOException {
        // 使用 Jsoup 连接拉钩招聘网站
        Document scriptHtml = Jsoup.connect(url)
                .header("User-Agent", "Mozilla/5.0")
                .timeout(50000)
                .get();
        
        // 获取职位列表
        Elements list = scriptHtml.getElementsByClass("item__10RTO");
        for (Element element : list) {
            String jobName = element.getElementById("openWinPostion").text();
            String experience = element.getElementsByClass("p-bom__JlNur").text();
            String salary = element.getElementsByClass("money__3Lkgq").text();
            String company = element.getElementsByClass("company-name__2-SjF").text();

            // 将职位信息添加到列表中
            Job job = new Job(jobName, experience, salary, company);
            jobs.add(job);
        }

        // 输出所有职位信息
        for (Job job : jobs) {
            System.out.println(job);
        }
    }
}

4.1 数据清洗

爬取到的数据往往需要进行清洗处理,以符合我们需要的格式。例如,在拉钩招聘爬虫中,我们提取了职位名称、经验要求、薪资信息等,并进行清洗和格式化。

public static void cleanData(Job job) {
    // 薪资清洗
    String salary = job.getSalary().substring(0, job.getSalary().indexOf("-"));
    job.setSalary(salary);

    // 清洗经验要求
    String experience = job.getExperience().substring(job.getExperience().indexOf("经验"), job.getExperience().indexOf(" "));
    job.setExperience(experience);

    jobs.add(job);
}

5. 总结

        HttpClient 是一个强大的工具,适用于多种网络请求场景,特别是爬虫和数据抓取。通过它,我们可以轻松发送 HTTP 请求,解析返回的 JSON 或 HTML 数据,并提取出有用的信息。对于复杂的网络请求场景,HttpClient 还提供了丰富的功能,如连接池、认证、请求重试等,帮助我们提高效率和性能。

        通过本文的介绍,你已经掌握了如何使用 HttpClient 发送 HTTP 请求,如何解析 JSON 数据,并能在实践中抓取和清洗网页数据。

你可能感兴趣的:(apache,网络)