解决java的http请求库dongliu.requests请求结果中文乱码的问题
前言
在前几天接到一个需求,需要爬取某个网站上的一些数据,并且经过整理后将爬取到的数据写入到数据库内。
这类需求如果不需要考虑太多性能的问题的话,使用 Python
来实现的效率是最高的,但考虑到后续可能需要作为模块整合至springboot
的应用内,所以还是决定使用 java
的库来进行开发。
在这之前了解到并且使用的 java
的 http
库都是 okhttp
、httpclient
、RestTemplate
等,虽然这些库也简化了很多原生求的复杂配置过程,但对于一些需求还是需要自行去封装,操作体验和开发效率上都差了很多。
所以突发奇,在java庞大的生态里面,有无类似 python
的 requests
这类体验更好的 http
请求库? 经过一番搜索后,在 github
上找到了与该库同名的一个 http
库,该模块的作者的灵感也同样来自于 Python 的第三方 库 requests
,描述如下
Requests is a http request lib with fluent api for java, inspired by the python request module. Requests requires JDK 1.8+, the last version support Java7 is 4.18.* . 一个具有流畅java api的http请求库,灵感来自python请求模块。请求需要JDK 1.8+,最后一个支持Java7的版本是4.18.* (中文为机器翻译)
经过一番体验后,该模块确实提供了很多便捷的java api,简化了大量的配置流程。
具体的使用方法,参考该模块的开源仓库:https://github.com/hsiafan/requests
问题描述
请求返回的数据内包含了中文,而 Requests
模块默认使用的是 utf-8
编码来解析响应的数据,代码如下
public class RequestsDemo {
public static void main(String[] args) {
String url = "http://example.com/index.asp";
//请求头
Map<String, Object> headers = new HashMap<>();
headers.put("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36");
//请求信息
Map<String, Object> formData = new HashMap<>();
formData.put("username", "666");
formData.put("passwd", "666");
formData.put("login", "%B5%C7%A1%A1%C2%BC");
Session session = Requests.session();
String respText = session.post(url)
//设置请求头
.headers(headers)
.requestCharset(Charset.forName("gbk"))
//请求表单
.body(formData)
//发送请求
.send().readToText();
System.out.println(respText);
}
}
请求返回的结果如下图
从上图可以看出中文的内容都变成了乱码。
发现了两个与编码相关的api
但通过 charset
进行编码的设置后,请求返回的结果仍然是乱码,无奈只能寻求其他的解决方案。
在后续的反思当中,觉着事情没这么简单,经过大量版本迭代的一个优秀的http库怎么会由如此弱鸡的问题?最后发现是api调用循序的问题导致无法根据指定的编码格式对响应的数据进行解码,详细请看
方案2
的过程描述。
解决方案
方案1
使用 .readToBytes()
以 bytes
形式结果获取响应的数据,然后再将 bytes
转为 gb2312
编码的 String
字符串,最终得到预期编码的结果,代码如下
Session session = Requests.session();
//发送请求
byte[] readToBytes = session.post(url)
//设置请求头
.headers(headers)
//请求表单
.body(formData)
//发送请求
.send().readToBytes();
//将请求结果进行解码
try {
String gb2312 = new String(readToBytes, "gb2312");
System.out.println(gb2312);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
执行结果如下
成功获取解析带有中文的响应结果。
方案2
而在提出 方案1
的解决方案后又想到可能是因为 api
调用顺序的问题,于是翻阅到了一篇文章,发现对于编码的案例是在 .send()
之后调用了 withCharset()
而 .withCharset()
已被官方替换为 .charset()
由于目前网上对于这个开源类库的内容比较少,所以在这之前没有搜索到合适的案例
废话少说,直接上代码。
//发送请求
String respStr = session.post(url)
//设置请求头
.headers(headers)
//请求表单
.body(formData)
//发送请求
.send().charset(Charset.forName("gb2312")).readToText();
System.out.println(respStr);
响应结果如下
官方给出的解释如下
由于之前没有仔细阅读官方的文档,耗进去了不少的时间去去寻找其他的解决办法(机翻的英文有点曲解了意思,奈何纯英文的文档又看不懂)
我的博客即将同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=10stzoecdirmx
- 01.SQLServer性能优化之----强大的文件组----分盘存储
- stackGan实验
- pyTorch基础入门练习
- 昨天遇到的几个常用函数
- 【深入浅出】一篇超棒的机器学习入门文章
- .NET中的异步编程上
- 从python2到python3
- 【干货】如何写代码 -编程内功心法
- .NET中的异步编程下
- 深度学习数学基础一--最小二乘法
- 【LeetCode 344】关关的刷题日记26 Reverse String
- 基于AOE网的关键路径的求解
- 【LeetCode 122】关关刷题日记25-Best Time to Buy and Sell Stock II
- 【干货】python正则表达式应用笔记
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Math - 50. Pow(x, n)
- String - 44. Wildcard Matching
- DFS&BFS - 37. Sudoku Solver
- Array - 36. Valid Sudoku
- Array - 57. Insert Interval
- Binary Search - 378. Kth Smallest Element in a Sorted Matrix
- Array - 59. Spiral Matrix II
- Array - 54. Spiral Matrix
- String - 8. String to Integer (atoi)
- Array - 16. 3Sum Closest
- Array - 15. 3Sum
- Design - 146. LRU Cache
- LinkedList - 142. Linked List Cycle II
- LinkedList - 2. Add Two Numbers
- Array - 56. Merge Intervals