1. 程式人生 > 實用技巧 >一個文字都用實體編碼的奇葩網站

一個文字都用實體編碼的奇葩網站

看到一個奇葩的網站,頁面上的文字都是使用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月份,於整理存稿時釋出。