jsoup解析网页出现转义符问题

艾丽斯顿 发布于 2013/12/06 16:29
阅读 4K+
收藏 3

我要解析这个网页  http://sports.163.com/13/0830/22/97IFSI5I00051CD5.html


然后直接在获得源码后,使用select  只捕获其中一部分  doc.select("textarea[id^=photoList]")

为何出现了这个情况呢、求大牛们帮忙解决啊 @红薯



很奇怪的是,我用转义符全部替换之后,直接打印在控制台,显示正确,然后又用Jsoup.parse()这个方法,结果又成了这样子、大神们,帮帮忙吧@jsoup

加载中
1
黄亿华
黄亿华
html()和outerHtml()的区别只是有没有包含本层而已,最终底层方法是一样的,所以这里确实转义了。

其实也说得通,因为textarea里的内容是“文本”,html里的纯文本内容,如果不进行转义是不安全的。

当然这里你的需求是"保持原文",“转义再反转”其实是无法保持原文的。而且Apache的StringEscapeUtils的转义范围比Jsoup要小,所以其实反转是不完整的。

有个比较hack的方法:

Document doc = Jsoup.connect("http://sports.163.com/13/0830/22/97IFSI5I00051CD5.html").get();
//清空jsoup的转义表,会使jsoup失去转义能力
Entities.EscapeMode.base.getMap().clear();
Elements elements = doc.select("textarea[id^=photoList]");
for(Element e:elements){
    System.out.println(e.html());
}




0
Timco
Timco
这个用正则替换一下噻,很快的。replace()方法
黄亿华
黄亿华
回复 @Timco : textarea就是一个表单元素啊...当然也可以用text(),效果是一样的。我看你这里说的是“直接打印”,System out会隐式调用toString(),html()和outerHtml()系列都会转义。具体可以看TextNode.outerHtmlHead()方法。
Timco
Timco
回复 @黄亿华 : 没有直接用Element#toString(),val()看文档是用于返回表单元素的值。我觉得楼主应该和我一样,用的是Element#html()方法,这个居然也出现了转义?我推测是在服务器端就进行了整个页面的转义吗?
黄亿华
黄亿华
回复 @Timco : 用doc.select("textarea[id^=photoList]").val()。 Element.toString()方法会对输出进行格式化,html实体会被转义,而val()会输出原文。
Timco
Timco
回复 @艾丽斯顿 : 试了一下,确实。。帮你at个大牛 @黄亿华
艾丽斯顿
艾丽斯顿
替换成功了,然后解析的时候,就又变成这样了
下一页
0
Timco
Timco

感觉可能是我没说清楚。。直接上代码吧 = = 麻烦了


Document doc = Jsoup.connect("http://sports.163.com/13/0830/22/97IFSI5I00051CD5.html").get();
Elements elements = doc.select("textarea[id^=photoList]");
for(Element e:elements){
    System.out.println(e.html());
    //System.out.println(e.outerHtml());  这样就和楼主的输出一样了
}

输出为:

<li>
<a href="#p=97I7L4MD00CO0005" hidefocus="true"><img data-id="102437" src="http://img4.cache.netease.com/photo/0005/2013-08-30/s_97I7L4MD00CO0005.jpg" alt="米兰官网:博阿滕转投沙尔克04" /></a>
<h2>米兰官网:博阿滕转投沙尔克04</h2>
<p>意大利当地时间8月30日,AC米兰通过俱乐部官方...


我觉得这里应该没有转义的道理欸,应该是直接输出 html字符串吧  -。- @黄亿华

0
Timco
Timco

找了个曲线救国的方法。。

StringEscapeUtils.unescapeHtml(e.outerHtml());



引入"common-lang"这个包就可以了。。

然后textarea是表单元素,用e.val()就省了上面这个过程

0
Timco
Timco

引用来自“黄亿华”的答案

html()和outerHtml()的区别只是有没有包含本层而已,最终底层方法是一样的,所以这里确实转义了。

其实也说得通,因为textarea里的内容是“文本”,html里的纯文本内容,如果不进行转义是不安全的。

当然这里你的需求是"保持原文",“转义再反转”其实是无法保持原文的。而且Apache的StringEscapeUtils的转义范围比Jsoup要小,所以其实反转是不完整的。

有个比较hack的方法:

Document doc = Jsoup.connect("http://sports.163.com/13/0830/22/97IFSI5I00051CD5.html").get();
//清空jsoup的转义表,会使jsoup失去转义能力
Entities.EscapeMode.base.getMap().clear();
Elements elements = doc.select("textarea[id^=photoList]");
for(Element e:elements){
    System.out.println(e.html());
}




果然可以了  感觉只有像你那样通读源码才能有这么个hack方法啊 -。- 谢了
s
safetys
神一样的存在啊。
艾丽斯顿
艾丽斯顿
给jsoup的作者来个pull request? 这个是干啥用的呢
黄亿华
黄亿华
嗯,不过我觉得会有这样的需求,我看看能不能给作者提个pull request去
0
泡不烂的凉粉
泡不烂的凉粉
为什么中文不搞utf8编码. 
0
Timco
Timco
github上给代码作者提交代码
0
艾丽斯顿
艾丽斯顿
我的问题解决了,感谢各位大神,尤其是@黄亿华 ,非常感谢各位
返回顶部
顶部