http parser 基本用法

手动解析HTML是一件很崩溃的事情,sun的swing里也有解析HTML的东东,不过已经是古董了,实在不好拿出来丢Java的人了。

今天要用的是Apache的一个开源项目,html parser。

它的强大不用多说,且看它提供的几个sample吧。

首先去htmlparser.sourceforge.net上去下载,在解压开之后目录里有几个目录,分别存放着src,jars,javadoc之类的,其中bin里有好几个xxx.cmd,用命令行运行那几个脚本,参数就加某个网页的地址就行了。

主意不要拿javaeye的网页做测试哦,不行的,因为sample里的HTTP客户端是用的sun的URLConnection,请求javaeye的话响应的内容是一个空文档,这只是URLConnection的众多bug之一,建议大家不要用哦,如果你只是测试的话那到无所谓咯。

其中stringextractor.cmd是解析出网页内的纯文本内容的,linkextractor.cmd是解析网页里的连接的,非常有用哦。

 

接下来就要开始编程了,如何使用这个好工具捏?貌似官方并米有详细的文档说明,就这几个sample就已经大致说清楚如何用了。我们找到这几个cmd文件,打开找到其中调用的是那个类,因为它的sample并没有单独拿出来,得要我们自己去它的source里去找。我的建议是在Eclipse的工程里添加那个jar文件,然后把jar文件设置src,这样代码看起来爽一些啦。

小研究一下那几个sample是如何实现的,然后想想你自己的需求,借题发挥吧,这是java程序员的强项了。

上面提到了那几个脚本的参数是网页地址,它的代码里也是在构建Parser对象的时候用的也是url字符串作为参数的,其实如果你想用URLConnection之外的其他Http客户端组件来代替html parser的内置请求方式,也不用担心,因为Parser对象同样提供了html内容作为参数的构建方式:Parser p = Parser.createParser(String html, String charser);

 

下面是我在项目中用的两个小method,模仿了sample里的代码

/**
* 用来抽取html里的连接地址,并转换了相对地址为绝对地址
*/

private void extractLinks(URL pageURL, Parser parser) {
		Map<String, String> links = new HashMap<String, String>();
		try {
			NodeFilter filter = new NodeClassFilter(LinkTag.class);
			NodeList list = parser.extractAllNodesThatMatch(filter);
			for (int i = 0; i < list.size(); i++) {
				LinkTag n = (LinkTag) list.elementAt(i);
				String link = n.getLink();
				if (!n.isHTTPLink()) {
					continue;
				}
				if (link.startsWith("http://")) {
					try {
						link = new URL(link).toString();
						links.put(HashUtil.md5(link), link);
					} catch (MalformedURLException e) {
						continue;
					}
				} else {
					try {
						link = new URL(pageURL, link).toString();
						links.put(HashUtil.md5(link), link);
					} catch (MalformedURLException e) {
						continue;
					}
				}
			}
		} catch (ParserException e) {
			// TODO 处理异常
			e.printStackTrace();
		} catch (RuntimeException e) {
			// TODO 处理异常
			e.printStackTrace();
		}
		doc.setDocs(createDoc(links));
	}
 
/**
* 抽取html里的文本内容,里面使用了一个自定义的节点访问器,TextExtractVisitor,下面一段有定义
*/


private Map<String, Object> extractText(Parser parser) {
		try {
			TextExtractVistor textExtractor = new TextExtractVistor();
			parser.visitAllNodesWith(textExtractor);
			doc.getText().setText(textExtractor.getText());
			doc.getText().setDigest(textExtractor.getDigest());
			doc.getText().setKeywords(textExtractor.getKeywords());
			doc.getText().setTitle(textExtractor.getTitle());
			return textExtractor.getHashedTextTags();
		} catch (ParserException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
 
/**
* 用来抽取html里文本等相关内容的节点访问器
*/


public class TextExtractVistor extends NodeVisitor {

	StringBuilder textBuf = new StringBuilder(4096);
	private boolean mIsScript;
	private boolean mIsStyle;
	private boolean mIsPre;
	protected int mCollapseState;
	private final String NEWLINE = System.getProperty("line.separator");
	private final int NEWLINE_SIZE = NEWLINE.length();
	private boolean mIsMeta;
	private boolean mIsH;
	private boolean isStrong;
	private StringBuilder digest = new StringBuilder(512);
	private StringBuilder keywords = new StringBuilder(100);
	private boolean isTtitle;
	private String title;
	private Map<String, Object> textTags = new HashMap<String, Object>();

	protected void carriageReturn() {
		int length;

		length = textBuf.length();
		if ((0 != length)
				&& ((NEWLINE_SIZE <= length) && (!textBuf.substring(
						length - NEWLINE_SIZE, length).equals(NEWLINE))))
			textBuf.append(NEWLINE);
		mCollapseState = 0;
	}

	public void visitStringNode(Text string) {
		if (!mIsScript && !mIsStyle) {
			String text = string.getText();
			textTags.put(HashUtil.md5(text), null);
			if (!mIsPre) {
				text = Translate.decode(text);
				text = text.replace('\u00a0', ' ');
				collapse(textBuf, text);
			} else {
				textBuf.append(text);
				
				if(mIsMeta){
					keywords.append(text);
				}else if(mIsH || isStrong){
					digest.append(text);
				}else if(isTtitle){
					title = text;
				}
			}
		}
	}


	public void visitTag(Tag tag) {
		String name = tag.getTagName();
		if (name.equalsIgnoreCase("PRE"))
			mIsPre = true;
		else if (name.equalsIgnoreCase("SCRIPT"))
			mIsScript = true;
		else if (name.equalsIgnoreCase("STYLE"))
			mIsStyle = true;
		else if (name.equalsIgnoreCase("META"))
			mIsMeta = true;
		else if (name.startsWith("[H|h]"))
			mIsH = true;
		else if (name.equalsIgnoreCase("STRONG"))
			isStrong = true;
		else if (name.equalsIgnoreCase("TITLE"))
			isTtitle = true;
		if (tag.breaksFlow())
			carriageReturn();
	}

	public void visitEndTag(Tag tag) {
		String name;

		name = tag.getTagName();
		if (name.equalsIgnoreCase("PRE"))
			mIsPre = false;
		else if (name.equalsIgnoreCase("SCRIPT"))
			mIsScript = false;
		else if (name.equalsIgnoreCase("STYLE"))
			mIsStyle = false;
		else if (name.equalsIgnoreCase("META"))
			mIsMeta = false;
		else if (name.startsWith("[H|h]"))
			mIsH = false;
		else if (name.equalsIgnoreCase("STRONG"))
			isStrong = false;
		else if (name.equalsIgnoreCase("TITLE"))
			isTtitle = false;
	}

	public String getText() {
		return textBuf.toString();
	}
	
	public String getDigest(){
		return digest.toString();
	}
	
	public String getKeywords(){
		return keywords.toString();
	}
	
	public String getTitle(){
		return title;
	}
	
	public Map<String, Object> getHashedTextTags(){
		return textTags;
	}
	
	protected void collapse(StringBuilder buffer, String string) {
		int chars;
		char character;

		chars = string.length();
		if (0 != chars) {
			for (int i = 0; i < chars; i++) {
				character = string.charAt(i);
				switch (character) {
				// see HTML specification section 9.1 White space
				// http://www.w3.org/TR/html4/struct/text.html#h-9.1
				case '\u0020':
				case '\u0009':
				case '\u000C':
				case '\u200B':
				case '\r':
				case '\n':
					if (0 != mCollapseState)
						mCollapseState = 1;
					break;
				default:
					if (1 == mCollapseState)
						buffer.append(' ');
					mCollapseState = 2;
					buffer.append(character);
				}
			}
		}
	}
}
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Elf parser是一种用于解析与操作ELF文件的工具。ELF文件是一种用于存储可执行文件、目标文件和共享库的标准文件格式。 使用Elf parser,我们可以对ELF文件进行各种操作,如提取符号表、段表、程序头等重要信息。下面是使用Elf parser的一般步骤: 1. 引入Elf parser库:首先,需要在代码中引入Elf parser库,以便能够使用其中的函数和类。 2. 打开ELF文件:使用Elf parser提供的函数,可以打开待解析的ELF文件。 3. 解析ELF头:通过调用解析ELF头(ELF Header)的函数,可以获得ELF文件的一些基本信息,如文件类型、目标体系结构、段表偏移量等。 4. 解析段表:通过调用解析段表(Section Header Table)的函数,可以获取ELF文件中的各个段的信息。段表中包含了代码段、数据段等重要的程序信息。 5. 解析程序头:通过调用解析程序头(Program Header Table)的函数,可以获取ELF文件中各个程序头的信息。程序头中包含了程序加载时需要的详细信息,如内存映射地址、段大小等。 6. 解析符号表:通过调用解析符号表(Symbol Table)的函数,可以获取ELF文件中的符号信息。符号表中存储了函数、变量等符号的名称和地址。 7. 其他操作:除了上述基本操作外,还可以进行其他操作,如查找特定符号的地址、修改ELF文件中的某些信息等。 使用Elf parser可以方便地对ELF文件进行解析与操作,进而帮助我们进行代码调试、代码分析等工作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值