jsoup用法.docx_第1页
jsoup用法.docx_第2页
jsoup用法.docx_第3页
jsoup用法.docx_第4页
jsoup用法.docx_第5页
已阅读5页,还剩41页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Jsoup解析HTML实例及文档方法详解 这篇文章主要介绍了Jsoup如何解析一个HTML文档、从文件加载文档、从URL加载Document等方法,对Jsoup常用方法做了详细讲解,最近提供了一个示例供大家参考 使用DOM方法来遍历一个文档 从元素抽取属性,文本和HTML 获取所有链接解析和遍历一个HTML文档如何解析一个HTML文档:复制代码代码如下:String html = First parse + Parsed HTML into a doc.;Document doc = Jsoup.parse(html);其解析器能够尽最大可能从你提供的HTML文档来创见一个干净的解析结果,无论HTML的格式是否完整。比如它可以处理:1、没有关闭的标签 (比如: Lorem Ipsum parses to Lorem Ipsum)2、隐式标签 (比如. 它可以自动将 Table data包装成?)3、创建可靠的文档结构(html标签包含head 和 body,在head只出现恰当的元素)一个文档的对象模型1、文档由多个Elements和TextNodes组成 (以及其它辅助nodes).2、其继承结构如下:Document继承Element继承Node. TextNode继承 Node.3、一个Element包含一个子节点集合,并拥有一个父Element。他们还提供了一个唯一的子元素过滤列表。从一个URL加载一个Document存在问题你需要从一个网站获取和解析一个HTML文档,并查找其中的相关数据。你可以使用下面解决方法:解决方法使用 Jsoup.connect(String url)方法:复制代码代码如下:Document doc = Jsoup.connect(/).get();String title = doc.title();说明connect(String url) 方法创建一个新的 Connection, 和 get() 取得和解析一个HTML文件。如果从该URL获取HTML时发生错误,便会抛出 IOException,应适当处理。Connection 接口还提供一个方法链来解决特殊请求,具体如下:复制代码代码如下:Document doc = Jsoup.connect() .data(query, Java) .userAgent(Mozilla) .cookie(auth, token) .timeout(3000) .post();这个方法只支持Web URLs (http和https 协议); 假如你需要从一个文件加载,可以使用parse(File in, String charsetName) 代替。从一个文件加载一个文档问题在本机硬盘上有一个HTML文件,需要对它进行解析从中抽取数据或进行修改。办法可以使用静态 Jsoup.parse(File in, String charsetName, String baseUri) 方法:复制代码代码如下:File input = new File(/tmp/input.html);Document doc = Jsoup.parse(input, UTF-8, /);说明parse(File in, String charsetName, String baseUri) 这个方法用来加载和解析一个HTML文件。如在加载文件的时候发生错误,将抛出IOException,应作适当处理。baseUri 参数用于解决文件中URLs是相对路径的问题。如果不需要可以传入一个空的字符串。另外还有一个方法parse(File in, String charsetName) ,它使用文件的路径做为 baseUri。 这个方法适用于如果被解析文件位于网站的本地文件系统,且相关链接也指向该文件系统。使用DOM方法来遍历一个文档问题你有一个HTML文档要从中提取数据,并了解这个HTML文档的结构。方法将HTML解析成一个Document之后,就可以使用类似于DOM的方法进行操作。示例代码:复制代码代码如下:File input = new File(/tmp/input.html);Document doc = Jsoup.parse(input, UTF-8, /); Element content = doc.getElementById(content);Elements links = content.getElementsByTag(a);for (Element link : links) String linkHref = link.attr(href); String linkText = link.text();说明Elements这个对象提供了一系列类似于DOM的方法来查找元素,抽取并处理其中的数据。具体如下:查找元素getElementById(String id)getElementsByTag(String tag)getElementsByClass(String className)getElementsByAttribute(String key) (and related methods)Element siblings: siblingElements(), firstElementSibling(), lastElementSibling();nextElementSibling(), previousElementSibling()Graph: parent(), children(), child(int index)元素数据attr(String key)获取属性attr(String key, String value)设置属性attributes()获取所有属性id(), className() and classNames()text()获取文本内容text(String value) 设置文本内容html()获取元素内HTMLhtml(String value)设置元素内的HTML内容outerHtml()获取元素外HTML内容data()获取数据内容(例如:script和style标签)tag() and tagName()操作HTML和文本append(String html), prepend(String html)appendText(String text), prependText(String text)appendElement(String tagName), prependElement(String tagName)html(String value)使用选择器语法来查找元素问题你想使用类似于CSS或jQuery的语法来查找和操作元素。方法可以使用Element.select(String selector) 和 Elements.select(String selector) 方法实现:复制代码代码如下:File input = new File(/tmp/input.html);Document doc = Jsoup.parse(input, UTF-8, ./); Elements links = doc.select(ahref); /带有href属性的a元素Elements pngs = doc.select(imgsrc$=.png); /扩展名为.png的图片Element masthead = doc.select(div.masthead).first(); /class等于masthead的div标签Elements resultLinks = doc.select(h3.r a); /在h3元素之后的a元素说明jsoup elements对象支持类似于CSS (或jquery)的选择器语法,来实现非常强大和灵活的查找功能。.这个select 方法在Document, Element,或Elements对象中都可以使用。且是上下文相关的,因此可实现指定元素的过滤,或者链式选择访问。Select方法将返回一个Elements集合,并提供一组方法来抽取和处理结果。Selector选择器概述tagname: 通过标签查找元素,比如:ans|tag: 通过标签在命名空间查找元素,比如:可以用 fb|name 语法来查找 元素#id: 通过ID查找元素,比如:#logo.class: 通过class名称查找元素,比如:.mastheadattribute: 利用属性查找元素,比如:hrefattr: 利用属性名前缀来查找元素,比如:可以用data- 来查找带有HTML5 Dataset属性的元素attr=value: 利用属性值来查找元素,比如:width=500attr=value, attr$=value, attr*=value: 利用匹配属性值开头、结尾或包含属性值来查找元素,比如:href*=/path/attr=regex: 利用属性值匹配正则表达式来查找元素,比如: imgsrc=(?i).(png|jpe?g)*: 这个符号将匹配所有元素Selector选择器组合使用el#id: 元素+ID,比如: div#logoel.class: 元素+class,比如: div.mastheadelattr: 元素+class,比如: ahref任意组合,比如:ahref.highlightancestor child: 查找某个元素下子元素,比如:可以用.body p 查找在body元素下的所有p元素parent child: 查找某个父元素下的直接子元素,比如:可以用div.content p 查找 p 元素,也可以用body * 查找body标签下所有直接子元素siblingA + siblingB: 查找在A元素之前第一个同级元素B,比如:div.head + divsiblingA siblingX: 查找A元素之前的同级X元素,比如:h1 pel, el, el:多个选择器组合,查找匹配任一选择器的唯一元素,例如:div.masthead, div.logo伪选择器selectors:lt(n): 查找哪些元素的同级索引值(它的位置在DOM树中是相对于它的父节点)小于n,比如:td:lt(3) 表示小于三列的元素:gt(n):查找哪些元素的同级索引值大于n,比如: div p:gt(2)表示哪些div中有包含2个以上的p元素:eq(n): 查找哪些元素的同级索引值与n相等,比如:form input:eq(1)表示包含一个input标签的Form元素:has(seletor): 查找匹配选择器包含元素的元素,比如:div:has(p)表示哪些div包含了p元素:not(selector): 查找与选择器不匹配的元素,比如: div:not(.logo) 表示不包含 class=logo 元素的所有 div 列表:contains(text): 查找包含给定文本的元素,搜索不区分大不写,比如: p:contains(jsoup):containsOwn(text): 查找直接包含给定文本的元素:matches(regex): 查找哪些元素的文本匹配指定的正则表达式,比如:div:matches(?i)login):matchesOwn(regex): 查找自身包含文本匹配指定正则表达式的元素注意:上述伪选择器索引是从0开始的,也就是说第一个元素索引值为0,第二个元素index为1等可以查看Selector API参考来了解更详细的内容从元素抽取属性,文本和HTML问题在解析获得一个Document实例对象,并查找到一些元素之后,你希望取得在这些元素中的数据。方法要取得一个属性的值,可以使用Node.attr(String key) 方法对于一个元素中的文本,可以使用Element.text()方法对于要取得元素或属性中的HTML内容,可以使用Element.html(), 或 Node.outerHtml()方法示例:复制代码代码如下:String html = An link.;Document doc = Jsoup.parse(html);/解析HTML字符串返回一个Document实现Element link = doc.select(a).first();/查找第一个a元素 String text = doc.body().text(); / An link/取得字符串中的文本String linkHref = link.attr(href); / /取得链接地址String linkText = link.text(); / /取得链接地址中的文本String linkOuterH = link.outerHtml(); / String linkInnerH = link.html(); / /取得链接内的html内容说明上述方法是元素数据访问的核心办法。此外还其它一些方法可以使用:Element.id()Element.tagName()Element.className() and Element.hasClass(String className)这些访问器方法都有相应的setter方法来更改数据.示例程序: 获取所有链接这个示例程序将展示如何从一个URL获得一个页面。然后提取页面中的所有链接、图片和其它辅助内容。并检查URLs和文本信息。运行下面程序需要指定一个URLs作为参数复制代码代码如下:package s; 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;/* 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 = args0; print(Fetching %s., url); Document doc = Jsoup.connect(url).get(); Elements links = doc.select(ahref); Elements media = doc.select(src); Elements imports = doc.select(linkhref); print(nMedia: (%d), media.size(); for (Element src : media) if (src.tagName().equals(img) print( * %s: %sx%s (%s), src.tagName(), src.attr(abs:src), src.attr(width), src.attr(height), trim(src.attr(alt), 20); else print( * %s: , src.tagName(), src.attr(abs:src); print(nImports: (%d), imports.size(); for (Element link : imports) print( * %s (%s), link.tagName(),link.attr(abs:href), link.attr(rel); print(nLinks: (%d), links.size(); for (Element link : links) print( * a: (%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; org/jsoup/s/ListLinks.javajava使用Jsoup组件生成word文档的方法先利用jsoup将得到的html代码“标准化”(Jsoup.parse(String html))方法,然后利用FileWiter将此html内容写到本地的template.doc文件中,此时如果文章中包含图片的话,template.doc就会依赖你的本地图片文件路径,如果你将图片更改一个名称或者将路径更改,再打开这个template.doc,图片就会显示不出来(出现一个叉叉)。为了解决此问题,利用jsoup组件循环遍历html文档的内容,将img元素替换成$image_自增值的标识,取出img元素中的src属性,再以键值对的方式存储起来,例如:复制代码代码如下:Map imgMap = new HashMap();imgMap.put(1,”D:lucene.png”);此时你的html内容会变成如下格式:(举个示例)复制代码代码如下: 测试消息1 $image_1 测试消息2 $image_2 测试消息3保存到本地文件以后,利用MSOfficeGeneratorUtils类(工具类详见下面,基于开源组件Jacob)打开你保存的这个template.doc,调用replaceText2Image,将上面代码的图片标识替换为图片,这样就消除了本地图片路径的问题。 然后再调用copy方法,复制整篇文档,关闭template.doc文件,新建一个doc文件(createDocument),调用 paste方法粘贴你刚复制的template.doc里的内容,保存。基本上就ok了。关于copy整个word文档的内容,也会出现一个隐式问题。就是当复制的内容太多时,关闭word程序的时候,会谈出一个对话框,问你是否将复制的数据应用于其它的程序。对于这个问题解决方法很简单,你可以在调用 quit(退出word程序方法)之前,新建一篇文档,输入一行字,然后调用 copy方法,对于复制的数据比较少时,关闭word程序时,它不会提示你的。见如下代码/复制一个内容比较少的*.doc文档,防止在关闭word程序时提示有大量的copy内容在内存中,是否应用于其它程序对话框,复制代码代码如下:msOfficeUtils.createNewDocument();msOfficeUtils.insertText(测试消息);msOfficeUtils.copy();msOfficeUtils.close();msOfficeUtils.quit();Jacob在sourceforge上的链接Jsoup官网MsOfficeGeneratorUtilspackage com.topstar.test;import java.io.File;import java.io.IOException;import java.util.List;import com.jacob.activeX.ActiveXComponent;import .ComThread;import .Dispatch;import .Variant;/* 利用JACOB对Microsoft Office Word 进行相关操作* author xiaowu* category topstar* version 1.0* since 2011-12-5*/public class MSOfficeGeneratorUtils /* * Microsoft Office Word 程序对象 */private ActiveXComponent word = null;/* * Word 活动文档对象 */private Dispatch document = null;/* * 所有 Word 文档对象 */private Dispatch documents = null;/* * selection 代表当前活动文档窗口中的所选内容。如果文档中没有选中任何内容,则此对象代表插入点(即光标所在位置)。 * 每个文档窗口中只能存在一个selection对象,并且在整个应用程序中,只能存在一个活动的selection对象 */private Dispatch selection = null;/* * range 对象代表文档中的一个连续的区域。每个range对象由一个起始字符位置与结束字符位置定义。 * range 对象独立于所选内容。你可以定义和处理一个范围而无需改变所选内容。还可以在文档中定义多个范围。但每个文档中只能有一个所选内容 */private Dispatch range = null;/* * PageSetup 对象包含文档所有页面的设置属性(如纸张大小,左边距,下边距) */private Dispatch pageSetup = null;/* * 文档中的所有表格对象 */private Dispatch tables = null;/* 单个表格对象 */private Dispatch table = null;/* 表格所有行对象 */private Dispatch rows = null;/* 表格所有列对象 */private Dispatch cols = null;/* 表格指定行对象 */private Dispatch row = null;/* 表格指定列对象 */private Dispatch col = null;/* 表格中指定的单元格 */private Dispatch cell = null;/* 字体 */private Dispatch font = null;/* 对齐方式 */private Dispatch alignment = null;/* * 构造方法 * * param visible * 设置在生成word文档时,程序是否可见 */public MSOfficeGeneratorUtils(boolean visible) if (this.word = null) / 初始化Microsoft Office Word 实例 this.word = new ActiveXComponent(Word.Application); this.word.setProperty(Visible, new Variant(visible); / 禁用宏 this.word.setProperty(AutomationSecurity, new Variant(3); if (this.documents = null) this.documents = word.getProperty(Documents).toDispatch();/* * 设置页面方向与页边距 * * param orientation * 页面方向 * * 0 横向 * 1 纵向 * * param leftMargin * 左边距 * param rightMargin * 右边距 * param topMargin * 上边距 * param buttomMargin * 下边距 */public void setPageSetup(int orientation, int leftMargin, int rightMargin, int topMargin, int buttomMargin) if (this.pageSetup = null) this.getPageSetup(); Dispatch.put(pageSetup, Orientation, orientation); Dispatch.put(pageSetup, LeftMargin, leftMargin); Dispatch.put(pageSetup, RightMargin, rightMargin); Dispatch.put(pageSetup, TopMargin, topMargin); Dispatch.put(pageSetup, BottomMargin, buttomMargin);/* * 打开word文档 * * param docPath * word文档路径 * return 打开的文档对象 */public Dispatch openDocument(String docPath) this.document = Dispatch.call(documents, Open, docPath).toDispatch(); this.getSelection(); this.getRange(); this.getAlignment(); this.getFont(); this.getPageSetup(); return this.document;/* * 创建一篇新文档 * * return 文档对象 */public Dispatch createNewDocument() this.document = Dispatch.call(documents, Add).toDispatch(); this.getSelection(); this.getRange(); this.getPageSetup(); this.getAlignment(); this.getFont(); return this.document;/* * 获取选定的内容或插入点 * * return selection */public Dispatch getSelection() this.selection = word.getProperty(Selection).toDispatch(); return this.selection;/* * 获取当前文档中可以修改的部分,前提是必须存在选中内容 * * return range */public Dispatch getRange() this.range = Dispatch.get(this.selection, Range).toDispatch(); return this.range;/* * 获得当前文档的页面属性 */public Dispatch getPageSetup() if (this.document = null) return this.pageSetup; this.pageSetup = Dispatch.get(this.document, PageSetup).toDispatch(); return this.pageSetup;/* * 把选中内容或插入点向上移动 * * param count * 移动的距离 */public void moveUp(int count) for (int i = 0; i count; i+) Dispatch.call(this.selection, MoveUp);/* * 把选中内容或插入点向下移动 * * param count * 移动的距离 */public void moveDown(int count) for (int i = 0; i count; i+) Dispatch.call(this.selection, MoveDown);/* * 把选中内容或插入点向左移动 * * param count * 移动的距离 */public void moveLeft(int count) for (int i = 0; i count; i+) Dispatch.call(this.selection, MoveLeft);/* * 把选中内容或插入点向右移动 * * param count * 移动的距离 */public void moveRight(int count) for (int i = 0; i count; i+) Dispatch.call(this.selection, MoveRight);/* * 执行硬换行(回车键) * * param count * 换行数 */public void enterDown(int count) for (int i = 0; i Dispatch.put(find, Text, toFindText); / 向前查找 Dispatch.put(find, Forward, True); / 设置格式 Dispatch.put(find, Format, True); / 大小写匹配 Dispatch.put(find, MatchCase, True); / 全字匹配 Dispatch.put(find, MatchWholeWord, True); / 查找并选中 return Dispatch.call(find, Execute).getBoolean();/* * 替换选定的内容 * * param newText * 要替换的内容 */public void replace(String newText) / 设置替换文本 Dispatch.put(this.selection, Text, newText);/* * 全局替换 * * param oldText * 要替换的内容 * param replaceObj * 被替换的内容 */public void replaceAll(String oldText, Object replaceObj) / 将插入点移到文件开头 moveStart(); / 表格替换方式 String newText = (String) replaceObj; / 图片替换方式 if (oldText.indexOf(image) != -1 | newText.lastIndexOf(.bmp) != -1 | newText.lastIndexOf(.jpg) != -1 | newText.lastIndexOf(.gif) != -1) while (find(oldText) insertImage(newText); Dispatch.call(this.selection, MoveRight); / 文本方式 else while (find(oldText) replace(newText); Dispatch.call(this.selection, MoveRight); /* * 将指定的内容替换成图片 * param replaceText 指定的内容 * param imgPath 图片路径 */public void replaceText2Image(String replaceText,String imgPath) moveStart(); while(find(replaceText) insertImage(imgPath); moveEnd(); enterDown(1); /* * 向当前插入点替换图片 * * param imagePath * 图片的路径 */public void insertImage(String imagePath) Dispatch.call(Dispatch.get(selection, InLineShapes).toDispatch(), AddPicture, imagePath);/* * 合并单元格 * * param tableIndex * 表格下标,从1开始 * param fstCellRowIdx * 开始行 * param fstCellColIdx * 开始列 * param secCellRowIdx * 结束行 * param secCellColIdx * 结束列 */public void mergeCell(int tableIndex, int fstCellRowIdx, int fstCellColIdx, int secCellRowIdx, int secCellColIdx) getTable(tableIndex); Dispatch fstCell = Dispatch.call(table, Cell, new Variant(fstCellRowIdx), new Variant(fstCellColIdx) .toDispatch(); Dispatch secCell = Dispatch.call(table, Cell, new Variant(secCellRowIdx), new Variant(secCellColIdx) .toDispat

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论