场景介绍
之前写的Jsoup爬虫中有个日期格式解码,一直以来都不知道是在哪里加密的,近期更新了爬虫程序,顺便发现了很多网站用字体加密的反爬虫套路,这种方式利用修改默认字体文件中的对应关系实现加密,传统方式很难破解。
奇怪的字体
在一些加密的数字和文字上,发现了一个奇怪的class属性1
<text class="tyc-num lh24">8348-39-88</text>
这个属性在css中就是使用一个字体:1
2
3.tyc-num {
font-family: "tyc-num" ;
}
在开发者工具NetWork-Font下找到了该字体:tyc-num.woff
Preview中看到的数字明显是乱序的,也就是说正常的数字显示已经混乱了,上面的8348-39-88
在页面中显示为2012-05-22
tyc-num.woff字体文件
下载了tyc-num.woff文件后,可以使用字体编辑工具打开,这里我用的是FontCreator
。打开后发现不光是数字混乱了,有370个左右的中文字也做了混淆,例如搜索可
对应看到的是从
,查看原网页中的可
在页面中显示的果然是从
。
解决方法
- 目前暂时对数字做了解码,只要把字体中的数字对应关系替换回来就行了。
- 中文字符太多暂时没有好的办法。但是从一些未替换的字中也能大概猜出语义了。
- 有的网站会定期更换加密字体,这样也会破解失败!
新的数字解码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34/**
* 新的数字解码
*/
private static String decode2(String date) {
char[] charArray = date.toCharArray();
for (int i = 0; i < charArray.length; i++) {
switch (charArray[i]) {
case '8':
charArray[i] = '0';
break;
case '6':
charArray[i] = '2';
break;
case '2':
charArray[i] = '3';
break;
case '0':
charArray[i] = '4';
break;
case '9':
charArray[i] = '6';
break;
case '3':
charArray[i] = '8';
break;
case '4':
charArray[i] = '9';
break;
default:
break;
}
}
return new String(charArray);
}更新爬虫程序
这次更新是因为原来的网站添加了一些反爬虫机制,例如IP和访问次数这些,使用阿布云后仍无法成功,所以先更换了别的网站:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37public static AccountBookInfo getInfo(String bookName) {
AccountBookInfo result = new AccountBookInfo();
String encodeName;
try {
encodeName = URLEncoder.encode(bookName, "utf-8");
} catch (UnsupportedEncodingException e) {
return null;
}
Document doc = JsoupUtils.getUrlDocument("https://www.tianyancha.com/search?key=" + encodeName);
if (doc == null) {
return null;
}
// 获取详情页地址(列表的第一个公司)
Elements rows = doc.select(".result-list a");
if (rows.size() == 0) {
return null;
}
Element row = rows.get(0);
Document infoDoc = JsoupUtils.getUrlDocument(row.attr("href"));
if (infoDoc == null) {
return null;
}
result.accountBookName = infoDoc.select("h1[class=name]").text();
result.legalPerson = infoDoc.select(".legal-representative a").text();
result.registeredCapital = infoDoc.select("td:containsOwn(实缴资本)").next().text();
result.establishDate = decode2(infoDoc.select("td:containsOwn(核准日期)").next().text());
result.registeredNo = infoDoc.select("td:containsOwn(工商注册号)").next().text();
result.organizationCode = infoDoc.select("td:containsOwn(组织机构代码)").next().text();
result.socialCreditCode = infoDoc.select("td:containsOwn(统一社会信用代码)").next().text();
result.businessStatus = infoDoc.select("div:containsOwn(公司状态)").next().text();
result.companyType = infoDoc.select("td:containsOwn(公司类型)").next().text();
result.businessScope = infoDoc.select("td:containsOwn(经营范围)").next().text();
result.address = infoDoc.select("td:containsOwn(注册地址)").next().text();
result.businessPeriod = infoDoc.select("td:containsOwn(营业期限)").next().text();
return result;
}传送门:
Java爬虫获取企业工商信息
Jsoup选择器语法