目录
[1. 什么是 HttpClient?](#1. 什么是 HttpClient?)
[2. 基本使用](#2. 基本使用)
[3. 使用 HttpClient 爬取腾讯天气的数据](#3. 使用 HttpClient 爬取腾讯天气的数据)
[4. 爬取拉勾招聘网站的职位信息](#4. 爬取拉勾招聘网站的职位信息)
[5. 总结](#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 依赖配置:
XML
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version> <!-- 请使用最新版本 -->
</dependency>
2.2 发送 HTTP GET 请求
下面是一个简单的使用示例,展示如何通过 HttpClient 发送一个 HTTP GET 请求:
java
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 源码。
可以看到请求的结果为百度源代码
3. 使用 HttpClient 爬取腾讯天气的数据
接下来,展示如何使用 HttpClient 来爬取 JSON 格式的天气数据。我们通过发送 HTTP GET 请求,获取腾讯天气 API 返回的 JSON 数据,并进行解析。
3.1 查询天气的json格式数据
我们构造一个 HTTP GET 请求,访问腾讯的天气 API:
java
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 数据,提取了天气信息,并输出了夜间风向。
3.2 JSON 解析
通过使用 fastjson
库,我们能够方便地解析 JSON 数据。JSONObject
类提供了 get()
、getJSONObject()
和 getJSONArray()
方法,方便我们提取对应的值:
get()
:获取某个键对应的值,返回Object
类型。getJSONObject()
:获取某个键对应的 JSON 对象,返回JSONObject
类型。getJSONArray()
:获取某个键对应的 JSON 数组,返回JSONArray
类型。
整体代码:
java
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();
}
}
}
}
java
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<cityLists.size();i++){
JSONObject jsonObject = cityLists.getJSONObject(i);
if(!jsonObject.getString("city").equals("待确认地区")){
System.out.println("城市:"+jsonObject.getString("city")+" 当前确认:"+jsonObject.getString("currentConfirm"));
}
}
}
}
}
}
4. 爬取拉勾招聘网站的职位信息
除了获取天气数据,我们还可以利用 HttpClient 抓取其他网站的数据。例如,我们可以爬取拉钩招聘网站的职位信息。以下是一个爬取拉钩招聘职位的简单示例:
java
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<Job> 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 数据清洗
爬取到的数据往往需要进行清洗处理,以符合我们需要的格式。例如,在拉钩招聘爬虫中,我们提取了职位名称、经验要求、薪资信息等,并进行清洗和格式化。
java
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 数据,并能在实践中抓取和清洗网页数据。