Jsoup参见百度http://baike.baidu.com/view/4066913.htm
官方网站:http://jsoup.org/
Jsoup解析HTML文件基本步骤:
获取Connection对象
通过Connection获取文档Document对象
根据需要解析文档
例子1:
import java.io.IOException; import org.jsoup.Connection; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.select.Elements; public class Demo1 { private static final String URL = "http://aiilive.blog.51cto.com/"; public static void main(String[] args) throws IOException { /** * 通过URL获取连接 */ Connection conn = Jsoup.connect(URL); /** * 通过连接获取文档对象 */ Document doc = conn.get(); /** * 获取所有的超链接 */ Elements elements=doc.getElementsByTag("ul"); for(int i=0, j=elements.size();i<j;i++){ System.out.println(elements.get(i).html()); } } }
例子2:来自org.jsoup.examples.ListLink.java
package org.jsoup.examples; import org.jsoup.Jsoup; import org.jsoup.helper.Validate; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; import java.io.IOException; /** * Example program to list links from a URL. */ public class ListLinks { public static void main(String[] args) throws IOException { Validate.isTrue(args.length == 1, "usage: supply url to fetch"); String url = args[0]; print("Fetching %s...", url); Document doc = Jsoup.connect(url).get(); Elements links = doc.select("a[href]"); Elements media = doc.select("[src]"); Elements imports = doc.select("link[href]"); print("\nMedia: (%d)", media.size()); for (Element src : media) { if (src.tagName().equals("img")) print(" * %s: <%s> %sx%s (%s)", src.tagName(), src.attr("abs:src"), src.attr("width"), src.attr("height"), trim(src.attr("alt"), 20)); else print(" * %s: <%s>", src.tagName(), src.attr("abs:src")); } print("\nImports: (%d)", imports.size()); for (Element link : imports) { print(" * %s <%s> (%s)", link.tagName(),link.attr("abs:href"), link.attr("rel")); } print("\nLinks: (%d)", links.size()); for (Element link : links) { print(" * a: <%s> (%s)", link.attr("abs:href"), trim(link.text(), 35)); } } private static void print(String msg, Object... args) { System.out.println(String.format(msg, args)); } private static String trim(String s, int width) { if (s.length() > width) return s.substring(0, width-1) + "."; else return s; } }
在解析51CTO博客中的友情链接的想法:
选择一个博客主页地址,如:http://aiilive.blog.51cto.com
通过<1>中的地址,获取到相对应的友情链接;
将友情链接作为<1>中的地址继续获取;
解析的前提是对博客页面进行分析,下面是通过FireFox的程序员开发工具分析图:
友情链接在<div class="friendLink box">...</div>里面。
Jsoup的优秀之处之一提供了类似CSS的选择器的方法,可以去特定标签进行选择过滤。
友情链接的部分如下图:
做法一:
筛选出div class;
算选出属性class的值为fiendLink box
获取<a>...</a>的HTML代码
处理<3>字符串
代码1:获取<li>中的HTML代码
/** * 获取BlogMain中的超链接 */ Element e = null; Elements elements = doc.select("div[class]"); for (int i = 0; i < elements.size(); i++) { e = elements.get(i); if (e.attr("class").equals("friendLink box")) { break; } } printElements(e.children().tagName("li"));
/** * 获取Elements中每一个Elment的HTML代码 * @param es */ private static void printElements(Elements es) { for (int i = 0, j = es.size(); i < j; i++) { Element e = es.get(i); String str = e.html(); getUrl(str); } }
代码2:处理<3>中的字符串
/** * <a href="http://21cnbao.blog.51cto.com" title="宋宝华的博客" target="_blank">宋宝华的博客</a> * @param str */ private static void getUrl(String str) { String[] strs = str.split("\""); for (String string : strs) { if (string.indexOf("http") != -1) { System.out.println(string); } } }
做法二:
做一个微小的改动:上述代码1中的printElements(Elements es){...}进行改动。
如下:
private static final String ATTRIBUTE_VALUE_ABS = "abs:href"; //方法改写 private static void getUrlExt(Elements es) { for (Element element : es) { String href = element.attr(ATTRIBUTE_VALUE_ABS); //筛选51CTO博客 if (filter51ctoBlog(href)) { linkSetTemp.add(href); } } }
filter51ctoBlog(href)
做51CTO博客筛选,是保证URL个格式符和51CTO博客主页格式。
完整的深度可调节的博客友情链接遍历:
代码:
import java.io.IOException; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; public class Demo4 { //遍历最小深度 private static final int LEVEL_MIN = 1; //遍历最大深度 private static final int LEVEL_MAX = 4; //程序入口URL private static final String IN_URL = "http://aiilive.blog.51cto.com/"; //友情链接标记 // private static final String TAGNAME = "li"; //DIV CLASS筛选条件 private static final String SELECT_DIV = "div[class]"; private static final String ATTRIBUTE = "class"; //友情链接CLASS的值 private static final String ATTRIBUTE_VALUE = "friendLink box"; //超链接筛选Query private static final String ATTRIBUTE_VALUE_ABS = "abs:href"; private static final String SELECT_TAG = "a[href]"; //存放遍历的友情链接 private static Set<String> linkSet = new HashSet<String>(); private static Set<String> linkSetTemp = null; static { linkSet.add(IN_URL); } /** * 第一种:获取友情链接的URL * * @param es */ @SuppressWarnings("unused") private static void getUrl(Elements es) { for (int i = 0, j = es.size(); i < j; i++) { Element e = es.get(i); String str = e.html(); String[] strs = str.split("\""); for (String strs ) { if (href.indexOf("http") != -1) { if (filter51ctoBlog(href)) { linkSetTemp.add(href); } } } } } /** * 过滤非51CTO博客主页的URL * @param str * @return */ private static boolean filter51ctoBlog(String str) { return str.endsWith("blog.51cto.com"); } /** * 第二种:获取友情链接的URL * * @param es */ private static void getUrlExt(Elements es) { for (Element element : es) { String href = element.attr(ATTRIBUTE_VALUE_ABS); if (filter51ctoBlog(href)) { linkSetTemp.add(href); } } } /** * 添加友情链接 * * @param url * @throws IOException */ private static void addFriendLink(String url) throws IOException { Document doc = Jsoup.connect(url).get(); Element e = null; Elements elements = doc.select(SELECT_DIV); for (int i = 0; i < elements.size(); i++) { e = elements.get(i); if (e.attr(ATTRIBUTE).equals(ATTRIBUTE_VALUE)) { break; } } // 获取FRIEND_BOX的孩子结点,筛选出li标签 // getUrl(e.children().tagName(TAGNAME)); Elements es = e.children().select(SELECT_TAG); getUrlExt(es); } /** * 添加友情链接 * * @param set * @throws IOException */ private static void addFriendLink(Set<String> set) throws IOException { for (Iterator<String> iter = set.iterator(); iter.hasNext();) { addFriendLink(iter.next()); } } /** * 打印集合信息 * * @param set */ private static void printSet(Set<String> set) { for (Iterator<String> iter = set.iterator(); iter.hasNext();) { System.out.println(iter.next()); } } public static void main(String[] args) throws IOException { linkSet.add(IN_URL); for (int i = LEVEL_MIN; i <= LEVEL_MAX; i++) { linkSetTemp = new HashSet<String>(); addFriendLink(linkSet); linkSet.addAll(linkSetTemp); linkSetTemp = null; } System.out.println(linkSet.size()); printSet(linkSet); } }
解析HTML要对文件进行分析,找出共同特征。比如:不同博客的主页的排版方式不同,那么通过布局去解析会出问题,在获取HTML文件中某一部分的内容,应该从标签的Id,class入手。这次解遇到这样的问题,是因为博客布局的不同,所以要提取相同解决,特定处理不同。
本文出自 “野马红尘” 博客,谢绝转载!