目录
1. 什么是 HttpClient?
2. 基本使用
3. 使用 HttpClient 爬取腾讯天气的数据
4. 爬取拉勾招聘网站的职位信息
5. 总结
Apache HttpClient 是 Apache 提供的一个用于处理 HTTP 请求和响应的工具类库。它提供了一种便捷、功能强大的方式来发送 HTTP 请求,并解析 HTTP 响应。HttpClient 适用于多种网络请求场景,能够帮助我们高效地与 Web 服务进行交互。
HttpClient 是在 JDK 的基础类库基础上进行封装和增强的一个 HTTP 请求工具库。它提供了更强大、更灵活的功能,比如支持连接池、认证机制、重定向、请求重试等,帮助我们提高开发效率和代码质量。
HttpClient 的核心功能包括:
首先,你需要在项目中引入 HttpClient 的 Maven 依赖。以下是 Apache HttpClient 的 Maven 依赖配置:
org.apache.httpcomponents
httpclient
4.5.13
下面是一个简单的使用示例,展示如何通过 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 源码。
可以看到请求的结果为百度源代码
接下来,展示如何使用 HttpClient 来爬取 JSON 格式的天气数据。我们通过发送 HTTP GET 请求,获取腾讯天气 API 返回的 JSON 数据,并进行解析。
我们构造一个 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 数据,提取了天气信息,并输出了夜间风向。
通过使用 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
除了获取天气数据,我们还可以利用 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);
}
}
}
爬取到的数据往往需要进行清洗处理,以符合我们需要的格式。例如,在拉钩招聘爬虫中,我们提取了职位名称、经验要求、薪资信息等,并进行清洗和格式化。
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);
}
HttpClient 是一个强大的工具,适用于多种网络请求场景,特别是爬虫和数据抓取。通过它,我们可以轻松发送 HTTP 请求,解析返回的 JSON 或 HTML 数据,并提取出有用的信息。对于复杂的网络请求场景,HttpClient 还提供了丰富的功能,如连接池、认证、请求重试等,帮助我们提高效率和性能。
通过本文的介绍,你已经掌握了如何使用 HttpClient 发送 HTTP 请求,如何解析 JSON 数据,并能在实践中抓取和清洗网页数据。