在实际项目的开发中常常遇到需要抓取网页信息的问题,利用Jsoup这款HTML解析器,可直接解析某个URL 地址、HTML 文本内容。由于它提供了一套非常省力的API,可通过DOM,CSS 以及类似于jQuery 的操作方法来取出和操作数据,方便实现快捷抓取。
本文以百度音乐分类中的经典老歌为例,其网址为http://mp3.baidu.com/m?f=ms&tn=baidump3&rf=taste&ct=134217728&lf=&rn=&word=%E7%BB%8F%E5%85%B8%E8%80%81%E6%AD%8C&lm=-1&ie=utf-8&pf=tags#1
为了能够抓取出经典老歌中的所有歌曲名和歌手名信息,首先建议查看网页源码,找到歌曲名和歌手名信息的存放方式,可以看到如图
在保存的html源代码中可以找到,歌曲信息存放在脚本中,以data命名的Map来存放,要实现成功抓取出这些信息,建议先创建一个键名类,从data中的歌曲元素分析中可以看出主要涉及“t”,“s”,“i”,“a”,“l”,“r”,“rt”这六大键名,而我所需要的是键“t”和“s”,若你在开发中需要专辑名,只要选取“a”就行,这样可以创建一个键名类,例如
public class Person {
private String t;//歌曲名键名
private String s;//歌手名键名
private String i;
private String a;//专辑名键名
private String l;
private String r;
private String rt;
public Person() {
// TODO Auto-generated constructor stub
}
public String getT() {
return t;
}
public void setT(String t) {
this.t = t;
}
public String getS() {
return s;
}
public void setS(String s) {
this.s = s;
}
public String getI() {
return i;
}
public void setI(String i) {
this.i = i;
}
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
public String getL() {
return l;
}
public void setL(String l) {
this.l = l;
}
public String getR() {
return r;
}
public void setR(String r) {
this.r = r;
}
public String getRt() {
return rt;
}
public void setRt(String rt) {
this.rt = rt;
}
}
接下来利用Jsoup工具对网页进行抓取,由于歌曲信息位于脚本中,可以建一个类BaiduListTest实现对给定的url地址进行抓取,必须导的包有
gson-1.3.jar; jsoup-1.5.2.jar; jxl.jar;
public class BaiduListTest {
/**
*获取url的JS脚本
* @param url
* @return JsString
* @throws IOException
*/
private static String getWebJavascript(String url) throws IOException {
Document doc = Jsoup.parse(new URL(url).openStream(), "gbk", url);
Elements scriptElements = doc.select("script");
return scriptElements.html();
}
/**
*获取脚本中的变量
* @param jsString
* @return JsVal
* @throws ScriptException
*/
public static String getJavascriptVal(String jsString)
throws ScriptException {
Object obj = null;
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");
String script = jsString;
engine.eval(script);
obj = engine.get("obj");
System.out.println("obj = " + obj.toString());
return obj.toString();
}
// 清除脚本格式
private static String filterScipt(String jsStr) {
String htmlStr = jsStr.replaceAll("\\<script.*?>", "");
htmlStr = htmlStr.replaceAll("\\</script.*?>", "");
System.out.println(htmlStr);
return htmlStr;
}
/**
*字符串操作截取歌曲信息
* @param args
* @throws IOException
*/
private static String filterGetData(String jsStr) {
// TODO Auto-generated method stub
jsStr = jsStr.substring(jsStr.indexOf("[{"), jsStr.indexOf("}];") + 2);
return jsStr;
}
之后在main()方法中利用gson分析截取下来的歌曲信息字符串,并把信息保存至键名类Person中, 测试读取Person中的歌曲信息即可。
public static void main(String[] args) throws ScriptException, IOException {
String url = "http://mp3.baidu.com/m?f=ms&tn=baidump3&rf=taste&ct=134217728&lf=&rn=&word=%E5%BD%B1%E8%A7%86%E9%87%91%E6%9B%B2&lm=-1&ie=utf-8&pf=tags#1";
String jsStr = getWebJavascript(url);
String jsonStr = filterGetData(jsStr);
//System.out.println(jsStr);
Gson gson = new Gson();
List<Person> ps = gson.fromJson(jsonStr, new TypeToken<List<Person>>() {
}.getType());
for (int i = 0; i < ps.size(); i++) {
Person p = ps.get(i);
System.out.println(p.getT()+"||"+p.getS());
}
转载请注明 来自http://blog.youkuaiyun.com/pzhnist_java/article/details/