Jsoup调用时URL参数%26被转为%2526的原因排查
问题:Jsoup请求中URL参数的%26被二次编码为%2526导致请求失败
你使用以下Jsoup代码发起HTTP请求:
Document doc = null; doc = Jsoup.connect(url). ignoreContentType(true). timeout(maxTimeout + (tryCount * maxTimeout)). userAgent("Mozilla"). get();
传入的原始URL为:https://www.valueresearchonline.com/stocks/who-owns-what?q=Ratnamani+Metals+%26+Tubes
调试时发现Document的location值变为:https://www.valueresearchonline.com/stocks/who-owns-what?q=Ratnamani+Metals+%2526+Tubes
疑问:为何参数中的%26会被转为%2526?这导致请求无法返回正确数据。
原因分析
Jsoup的connect()方法会自动对传入的URL进行URL编码处理。你的原始URL中%26已经是&的URL编码结果(&对应%26),当Jsoup再次编码时,%字符会被编码为%25,因此%26就变成了%2526,造成二次编码,导致服务器无法正确解析查询参数。
解决办法
方案一:使用data()方法单独添加参数(推荐)
避免手动拼接URL参数,改用Jsoup的data()方法直接传入原始参数值,Jsoup会自动完成正确的URL编码,彻底避免二次编码问题:
Document doc = Jsoup.connect("https://www.valueresearchonline.com/stocks/who-owns-what") .ignoreContentType(true) .timeout(maxTimeout + (tryCount * maxTimeout)) .userAgent("Mozilla") .data("q", "Ratnamani Metals & Tubes") // 直接传入带&的原始字符串 .get();
方案二:传入未编码的原始URL
如果坚持手动拼接URL,直接使用包含&的原始参数字符串,让Jsoup完成一次正确编码:
String url = "https://www.valueresearchonline.com/stocks/who-owns-what?q=Ratnamani Metals & Tubes"; // 或者用空格的编码形式%20,效果一致 // String url = "https://www.valueresearchonline.com/stocks/who-owns-what?q=Ratnamani%20Metals%20%26%20Tubes"; Document doc = Jsoup.connect(url) .ignoreContentType(true) .timeout(maxTimeout + (tryCount * maxTimeout)) .userAgent("Mozilla") .get();
方案三:手动解码已编码URL后传入
如果必须使用已编码的URL作为输入,先手动解码再传给Jsoup,让它重新进行正确编码:
import java.net.URLDecoder; import java.nio.charset.StandardCharsets; String encodedUrl = "https://www.valueresearchonline.com/stocks/who-owns-what?q=Ratnamani+Metals+%26+Tubes"; // 解码已编码的URL String decodedUrl = URLDecoder.decode(encodedUrl, StandardCharsets.UTF_8); Document doc = Jsoup.connect(decodedUrl) .ignoreContentType(true) .timeout(maxTimeout + (tryCount * maxTimeout)) .userAgent("Mozilla") .get();
内容的提问来源于stack exchange,提问作者vikramvi
相关产品推荐
相关产品推荐

