看到一个奇葩的网站,页面上的文字都是使用html实体编码了的(很久之前看的,现在改版了,只有固定部分是html实体编码了):
view-source:http://www.gzthfy.gov.cn/pa2/wel_bgt2.seam?zxbh=20140110180053&cid=9057
解码如下:
package cc11001100.misc.crawler.misc.tianhefayuan;
/**
* 这个网站,全站都是这种见鬼的编码
* <p>
* http://www.gzthfy.gov.cn
* <p>
* 参考资料:
* 1. https://www.jianshu.com/p/6dcefb2a59b2
* <p>
* 可以直接当做html来解析,但还是自己写一个解析
* <p>
* 使用Apache Commons工具包下的工具类就可以直接解码
* StringEscapeUtils.unescapeHtml4
*
* @author CC11001100
*/
public class TianhefayuanCrawler {
private static String convertToReadable(String rawContent) {
// 直接调库实现
// return StringEscapeUtils.unescapeHtml4(rawContent);
// 不能满足于做一个碉堡侠,还是自己实现一下
StringBuilder sb = new StringBuilder();
boolean isInHtmlEncode = false;
int lastHtmlEncodeBeginIndex = -1;
for (int i = 0; i < rawContent.length(); i++) {
if (isInHtmlEncode) {
if (rawContent.charAt(i) != ';') {
// 仍然在实体编码中,直接略过下一个
continue;
} else {
// 一个实体编码已经结束了,解析出它
isInHtmlEncode = false;
// 略过html实体前面的"&#"部分
String encodeNumStr = rawContent.substring(lastHtmlEncodeBeginIndex + 2, i);
int radix = 10;
if (encodeNumStr.charAt(0) == 'x' || encodeNumStr.charAt(0) == 'X') {
radix = 16;
encodeNumStr = encodeNumStr.substring(1);
} else if (encodeNumStr.startsWith("0")) {
radix = 8;
encodeNumStr = encodeNumStr.substring(1);
}
sb.append((char) Integer.parseInt(encodeNumStr, radix));
}
} else if (nextIsHtmlEncode(rawContent, i)) {
isInHtmlEncode = true;
lastHtmlEncodeBeginIndex = i;
} else {
sb.append(rawContent.charAt(i));
}
}
return sb.toString();
}
private static boolean nextIsHtmlEncode(String s, int index) {
return s.length() > index + 1 && (s.charAt(index) == '&' && s.charAt(index + 1) == '#');
}
public static void main(String[] args) {
String rawContent = "广州市天河区人民法院";
System.out.println(convertToReadable(rawContent)); // 广州市天河区人民法院
}
}请注意爬虫文章具有时效性,本文写于2019年7月份,于整理存稿时发布。