最初代码只写了2天,没想到写测试写了将近两周。。
今天也终于是算写完,在github上发布了1.0版本,链接:
https://github.com/std4453/StdURL/releases/tag/v1.0
欢迎各位下载写issue发pull。
大致功能就是实现了一遍URL标准上描述的过程,其中又以URL parser为中心。
用法很简单:
import org.stdurl.*;
import org.stdurl.parser.*;
public static void main(String[] args) {
URL url = BasieURLParser.parse("http://www.baidu.com");
if (url == null || url.isFailure()) {
System.out.println("Parser returned FAILURE");
return;
}
System.out.println(url.getHost()); // www.baidu.com
System.out.println(url.getHref()); // http://www.baidu.com
}
这个库的真正用处在于,完美模拟浏览器处理超链接的行为,在做网络爬虫之类的工具的时候,可以这样使用BasicURLParser
:
URL baseURL = BasicURLParser.parse("http://www.example.com");
String input = "a/1.html";
URL parsed = BasicURLParser.parse(input, baseURL);
System.out.println(parsed.getHref());
输出将会是:
这里input的赋值一般就是<a href="XXX">ABC</a>
中的XXX,baseURL这里调用的参数就可以是所解析的html页面的URL。
当然如果href属性的值不是相对链接也完全没有问题:
URL baseURL = BasicURLParser.parse("http://www.example.com");
String input = "http://www.baidu.com";
URL parsed = BasicURLParser.parse(input, baseURL);
System.out.println(parsed.getHref());
输出是:
这个库还能处理做爬虫的时候经常会碰到的一个问题:字符集。
按照标准,URL除了query都强制为utf8编码,而query的编码应该是按照页面的字符集来的。很多常见的库(比如我上次吐槽过的Jsoup)在这种情况下就会出问题,比如把应该是gb2312下百分号编码的query字符串解析成为utf8,结果再次访问的时候服务器就解析不出来。
这些问题,用StrURL就可以完美解决,示例代码:
String baseURL = "www.sfls.cn"
Document doc = Jsoup.connect(baseURL); // 其编码是gb2312
Charset charset = doc.charset();
String input = "你好.html?新年快乐";
URL base = BasicURLParser.parse(baseURL);
URL parsed = BasicURLParser.parse(input, base, charset);
System.out.println(parsed.getHref());
输出是:
http://www.sfls.cn/%E4%BD%A0%E5%A5%BD.html?%D0%C2%C4%EA%BF%EC%C0%D6
再交给网络库去访问就没有问题了(如果直接把带中文的链接交给HttpClient会报错)。
注意这里“你好”的编码是utf8,而“新年快乐”的编码是gb2312。
另一个玩法是去除url后面的fragment端,也就是#
之后的内容,方法很简单:
URL url = BasicURLParser.parse("http://www.example.com/index.html?query#fragment");
System.out.println(url.serialize(true));
输出是:
这样就行了。