Jsoup 提交参数乱码,解决思路,解决过程及解决方案

最近在开发ICP备案查询网,为了保持运行的稳定性,虽然我已经拥有不用验证码的ICP备案查询:https://www.sojson.com/beian/

但是还是不能放弃域名(www.xbeian.com),故开发一套产品出来。下面来一个不成型的界面当封面图吧。

废话不说了,开始这篇的分享内容。

需求介绍

1.从工信部页面(“http://www.beian.miit.gov.cn/icp/publish/query/icpMemoInfo_showPage.action”)获取验证码。

2.填写查询内容。

3.填写验证码,提交查询内容,获取查询结果。

遇到的问题

中文参数问题:

我们现在项目一般都是UTF-8的了,但是这个页面是GBK的。关于编码可以自己看请求头。

有一个头痛的问题就是汉字会编码,就是表单提交编码问题,而  Jsoup  目前自身没有指定编码的方法。。

    页面GBK编码—> URLEncode 编码—>提交到服务器

刘飞” GBK的URLEncode编码后为 “%C1%F5%B7%C9”,如果你直接转码成这样,通过Jsoup.data(key,value)提交后,会变成“%25C1%25F5%25B7%25C9”,没错,他又一次urlencode,并且是UTF-8编码的。

辗转反侧测试了很多次,还是不行。

上代码,这个代码非中文参数,没毛病。

Connection jsoup = Jsoup.connect("http://www.beian.miit.gov.cn/icp/publish/query/icpMemoInfo_searchExecute.action")
        .header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3")
        .header("Pragma", "no-cache")
        .header("Cache-Control", "no-cache")
        .header("Upgrade-Insecure-Requests", "1")
        .header("Connection", "close")
        .header("Host", "www.beian.miit.gov.cn")
        .header("Referer", "http://www.beian.miit.gov.cn/icp/publish/query/icpMemoInfo_showPage.action")
        .header("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:42.0) Gecko/20100101 Firefox/42.0")
        .header("Accept-Encoding", "gzip, deflate")
        .header("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8")
        .header("Cookie", session);
jsoup.data("mainUnitNature","-1");
jsoup.data("certType","-1");
jsoup.data("mainUnitCertNo","");
jsoup.data("verifyCode",vcode);
jsoup.data("condition",type);

switch (type){
    case "0":
        jsoup.data("siteName",java.net.URLEncoder.encode(qtext, "gbk"));
        break;
    case "1":
        jsoup.data("siteDomain",qtext);
        break;
    case "2":
        jsoup.data("siteUrl",qtext);
        break;
    case "3":
        jsoup.data("mainLicense",java.net.URLEncoder.encode(qtext, "gbk"));

        break;
    case "4":
        jsoup.data("siteIp",qtext);
        break;
    case "5"://中文参数提交
        //这里转成GBK,但是URLEncode的编码它是utf-8,所以有问题。
        //直接提交GBK的URLEncode编码结果,它还是再次URLEncode编码,也是utf-8编码。
        jsoup.data("unitName",new String(qtext.getBytes("gbk")));//java.net.URLEncoder.encode(qtext, "gbk")
        break;
}
jsoup.timeout(50000);
Document doc = jsoup.post();

Jsoup解决思路

我们知道  Jsoup  支持解析IO,直接解析  HTML  ,或者  URL  对象都可以。用这些我知道能解决,但是我还是想直接通过  Jsoup  来解决,尝试了很久,网上看了很多资料,看了些许源码,最终还是失败了。

当我们遇到Http请求出现问题了,而又不容易看出问题所在,那么就建议直接用抓包工具,把正常的请求和你模拟的请求进行对比。

对比有几个点:header、text参数、form参数、cookie等等,一般是出在参数、header、cookie问题。本次是参数问题,下面截图对比。

查询资料的时候比较滑稽的是,发现百度里,搜索  Jsoup  乱码,我曾经写的一篇关于  Jsoup  乱码是No 1排名。

Jsoup参数乱码解决方案

不得不借助  Httpclient  等  Http  请求解决。不管采用什么  Http  开源包请求,只要能getInputStream()或者直接拿到Html Dom结构也可以,因为  Jsoup  支持parse IO,也支持parse HTML

我自己有自己的Http 封装的工具。为了大家方便使用,我写了一遍较为原始的Http请求,代码如下,测试好使。

try {
	OutputStream outStream = null;
	OutputStreamWriter  out = null;
	URL realUrl = new URL("http://www.beian.miit.gov.cn/icp/publish/query/icpMemoInfo_searchExecute.action");
	// 打开和URL之间的连接
	HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();
	// 发送POST请求必须设置如下两行
	conn.setDoOutput(true);
	conn.setDoInput(true);
	conn.setRequestMethod("POST");// 提交模式
	conn.addRequestProperty("Connection","close");
	conn.addRequestProperty("Host", "www.beian.miit.gov.cn");
	conn.addRequestProperty("Content-type", "application/x-www-form-urlencoded; charset=gbk");
	conn.addRequestProperty("Referer", "http://www.beian.miit.gov.cn/icp/publish/query/icpMemoInfo_searchExecute.action");
	conn.addRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:42.0) Gecko/20100101 Firefox/42.0");
	conn.addRequestProperty("Cookie", "__jsluid=3f1f3c28f6c3af8b9a7f93418aac4cf1; Hm_lvt_af6f1f256bb28e610b1fc64e6b1a7613=1560086695; Hm_lpvt_af6f1f256bb28e610b1fc64e6b1a7613=1560088421; JSESSIONID=xDlE3rmJFa4RoGaxI_QbVvdJNKbuD-iG_B3Avs_ypkTwQIIoiF-D!-1797433545");
	outStream = conn.getOutputStream();
	out = new OutputStreamWriter(outStream);
        //参数输出
	out.write("certType=-1&condition=5&mainUnitNature=-1&unitName=" + java.net.URLEncoder.encode("刘飞", "gbk") +"&verifyCode=666666");
	// flush输出流的缓冲
	out.flush();

	Document doc = Jsoup.parse(conn.getInputStream(), "GBK", "http://www.beian.miit.gov.cn/icp/publish/query/icpMemoInfo_showPage.action");

	System.out.println(doc.html());
} catch (IOException e) {
	e.printStackTrace();
}

秀一下我封装的Http工具类请求,我比较喜欢链式编程。

String res = Http.create("http://www.beian.miit.gov.cn/icp/publish/query/icpMemoInfo_searchExecute.action")
        .cookies("cookie")
        .charset("gbk")
        .head("Referer","http://www.beian.miit.gov.cn/icp/publish/query/icpMemoInfo_showPage.action")
        .head("User-Agent","Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36")
        .head("Host","www.beian.miit.gov.cn")
        //提交参数
        .bodys("siteName=&siteDomain=&siteUrl=&mainLicense=&siteIp=&condition=5&unitName=%D6%DC%B0%D8%B3%C9&mainUnitNature=-1&certType=-1&mainUnitCertNo=&verifyCode=wgqk3k")
        .post()
        .send()
        .getResponse()
        .getResult();

Document doc = Jsoup.parse(res);

结果是可以参数编码为GBKURLEncode后提交正确。也对比了抓包,一模一样。

最终还是依赖Http组件来解决的,如果  Jsoup  解决了的同学,请下面留言,我来补充。

 

版权所属:SO JSON在线解析

原文地址:https://www.sojson.com/blog/331.html

转载时必须以链接形式注明原始出处及本声明。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
12-12 609

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值