日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java的html解析器——Jsoup详解

發(fā)布時間:2023/12/20 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java的html解析器——Jsoup详解 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

入門

1.?解析和遍歷一個html文檔

輸入

2.?解析一個html字符串

3.?解析一個body片斷

4.?根據(jù)一個url加載Document對象

5.?根據(jù)一個文件加載Document對象

數(shù)據(jù)抽取

6.?使用dom方法來遍歷一個Document對象

7.?使用選擇器語法來查找元素

8.?從元素集合抽取屬性、文本和html內(nèi)容

9.?URL處理

10.?程序示例:獲取所有鏈接

數(shù)據(jù)修改

11.?設(shè)置屬性值

12.?設(shè)置元素的html內(nèi)容

13.?設(shè)置元素的文本內(nèi)容

html清理

14.?消除不受信任的html?(來防止xss攻擊)

?


1.解析和遍歷一個HTML文檔

如何解析一個HTML文檔:

String?html?=?"<html><head><title>First?parse</title></head>"

??+?"<body><p>Parsed?HTML?into?a?doc.</p></body></html>";

Document?doc?=?Jsoup.parse(html);

(更詳細(xì)內(nèi)容可查看?解析一個HTML字符串.)

其解析器能夠盡最大可能從你提供的HTML文檔來創(chuàng)見一個干凈的解析結(jié)果,無論HTML的格式是否完整。比如它可以處理:

·?沒有關(guān)閉的標(biāo)簽?(比如:?<p>Lorem?<p>Ipsum?parses?to?<p>Lorem</p>?<p>Ipsum</p>)

·?隱式標(biāo)簽?(比如.?它可以自動將?<td>Table?data</td>包裝成<table><tr><td>?)

·?創(chuàng)建可靠的文檔結(jié)構(gòu)(html標(biāo)簽包含head?和?body,在head只出現(xiàn)恰當(dāng)?shù)脑?#xff09;

一個文檔的對象模型

·?文檔由多個ElementsTextNodes組成?(以及其它輔助nodes:詳細(xì)可查看:nodes?package?tree).

·?其繼承結(jié)構(gòu)如下:Document繼承Element繼承Node.?TextNode繼承?Node.

·?一個Element包含一個子節(jié)點(diǎn)集合,并擁有一個父Element。他們還提供了一個唯一的子元素過濾列表。

參見

·?數(shù)據(jù)抽取:DOM遍歷

·?數(shù)據(jù)抽取:Selector?syntax

?

?

?


2.解析一個HTML字符串

存在問題

來自用戶輸入,一個文件或一個網(wǎng)站的HTML字符串,你可能需要對它進(jìn)行解析并取其內(nèi)容,或校驗其格式是否完整,或想修改它。怎么辦?jsoup能夠幫你輕松解決這些問題

解決方法

使用靜態(tài)Jsoup.parse(String?html)?方法或?Jsoup.parse(String?html,?String?baseUri)示例代碼:

String?html?=?"<html><head><title>First?parse</title></head>"

??+?"<body><p>Parsed?HTML?into?a?doc.</p></body></html>";

Document?doc?=?Jsoup.parse(html);

描述

parse(String?html,?String?baseUri)?這方法能夠?qū)⑤斎氲?span style="font-family:Arial">HTML解析為一個新的文檔?(Document),參數(shù)?baseUri?是用來將相對?URL?轉(zhuǎn)成絕對URL,并指定從哪個網(wǎng)站獲取文檔。如這個方法不適用,你可以使用?parse(String?html)?方法來解析成HTML字符串如上面的示例。.

只要解析的不是空字符串,就能返回一個結(jié)構(gòu)合理的文檔,其中包含(至少)?一個head和一個body元素。

一旦擁有了一個Document,你就可以使用Document中適當(dāng)?shù)姆椒ɑ蛩割?ElementNode中的方法來取得相關(guān)數(shù)據(jù)。

?

?

?

?

?

3.解析一個body片斷

問題

假如你有一個HTML片斷?(比如.?一個?div?包含一對?p?標(biāo)簽;?一個不完整的HTML文檔)?想對它進(jìn)行解析。這個HTML片斷可以是用戶提交的一條評論或在一個CMS頁面中編輯body部分。

辦法

使用Jsoup.parseBodyFragment(String?html)方法.

String?html?=?"<div><p>Lorem?ipsum.</p>";

Document?doc?=?Jsoup.parseBodyFragment(html);

Element?body?=?doc.body();

說明

parseBodyFragment?方法創(chuàng)建一個空殼的文檔,并插入解析過的HTMLbody元素中。假如你使用正常的?Jsoup.parse(String?html)?方法,通常你也可以得到相同的結(jié)果,但是明確將用戶輸入作為?body片段處理,以確保用戶所提供的任何糟糕的HTML都將被解析成body元素。

Document.body()?方法能夠取得文檔body元素的所有子元素,與?doc.getElementsByTag("body")相同。

保證安全Stay?safe

假如你可以讓用戶輸入HTML內(nèi)容,那么要小心避免跨站腳本攻擊。利用基于?Whitelist?的清除器和?clean(String?bodyHtml,?Whitelist?whitelist)方法來清除用戶輸入的惡意內(nèi)容。

?

?

?


4.從一個URL加載一個Document

存在問題

你需要從一個網(wǎng)站獲取和解析一個HTML文檔,并查找其中的相關(guān)數(shù)據(jù)。你可以使用下面解決方法:

解決方法

使用?Jsoup.connect(String?url)方法:

Document?doc?=?Jsoup.connect("http://example.com/").get();

String?title?=?doc.title();

說明?

connect(String?url)?方法創(chuàng)建一個新的?Connection,?和?get()?取得和解析一個HTML文件。如果從該URL獲取HTML時發(fā)生錯誤,便會拋出?IOException,應(yīng)適當(dāng)處理。

Connection?接口還提供一個方法鏈來解決特殊請求,具體如下:

Document?doc?=?Jsoup.connect("http://example.com")

??.data("query",?"Java")

??.userAgent("Mozilla")

??.cookie("auth",?"token")

??.timeout(3000)

??.post();

這個方法只支持Web?URLs?(httphttps?協(xié)議);?假如你需要從一個文件加載,可以使用?parse(File?in,?String?charsetName)?代替。

?

?

?

?

?

5.從一個文件加載一個文檔

問題

在本機(jī)硬盤上有一個HTML文件,需要對它進(jìn)行解析從中抽取數(shù)據(jù)或進(jìn)行修改。

辦法

可以使用靜態(tài)?Jsoup.parse(File?in,?String?charsetName,?String?baseUri)?方法:

File?input?=?new?File("/tmp/input.html");

Document?doc?=?Jsoup.parse(input,?"UTF-8",?"http://example.com/");

說明

parse(File?in,?String?charsetName,?String?baseUri)?這個方法用來加載和解析一個HTML文件。如在加載文件的時候發(fā)生錯誤,將拋出IOException,應(yīng)作適當(dāng)處理。

baseUri?參數(shù)用于解決文件中URLs是相對路徑的問題。如果不需要可以傳入一個空的字符串。

另外還有一個方法parse(File?in,?String?charsetName)?,它使用文件的路徑做為?baseUri。?這個方法適用于如果被解析文件位于網(wǎng)站的本地文件系統(tǒng),且相關(guān)鏈接也指向該文件系統(tǒng)。?

?

?

?


?

?

6.使用DOM方法來遍歷一個文檔

問題

你有一個HTML文檔要從中提取數(shù)據(jù),并了解這個HTML文檔的結(jié)構(gòu)。

方法

HTML解析成一個Document之后,就可以使用類似于DOM的方法進(jìn)行操作。示例代碼:

File?input?=?new?File("/tmp/input.html");

Document?doc?=?Jsoup.parse(input,?"UTF-8",?"http://example.com/");

?

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的方法來查找元素,抽取并處理其中的數(shù)據(jù)。具體如下:

查找元素

·?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)

元素數(shù)據(jù)

·?attr(String?key)獲取屬性attr(String?key,?String?value)設(shè)置屬性

·?attributes()獲取所有屬性

·?id(),?className()?and?classNames()

·?text()獲取文本內(nèi)容text(String?value)?設(shè)置文本內(nèi)容

·?html()獲取元素內(nèi)HTMLhtml(String?value)設(shè)置元素內(nèi)的HTML內(nèi)容

·?outerHtml()獲取元素外HTML內(nèi)容

·?data()獲取數(shù)據(jù)內(nèi)容(例如:scriptstyle標(biāo)簽)

·?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)

?

?

?

?


7.使用選擇器語法來查找元素

問題

你想使用類似于CSSjQuery的語法來查找和操作元素。

方法

可以使用Element.select(String?selector)?和?Elements.select(String?selector)?方法實現(xiàn):

File?input?=?new?File("/tmp/input.html");

Document?doc?=?Jsoup.parse(input,?"UTF-8",?"http://example.com/");

?

Elements?links?=?doc.select("a[href]");?//帶有href屬性的a元素

Elements?pngs?=?doc.select("img[src$=.png]");

??//擴(kuò)展名為.png的圖片

?

Element?masthead?=?doc.select("div.masthead").first();

??//class等于mastheaddiv標(biāo)簽

?

Elements?resultLinks?=?doc.select("h3.r?>?a");?//h3元素之后的a元素

說明

jsoup?elements對象支持類似于CSS?(jquery)的選擇器語法,來實現(xiàn)非常強(qiáng)大和靈活的查找功能。.

這個select?方法在Document,?Element,Elements對象中都可以使用。且是上下文相關(guān)的,因此可實現(xiàn)指定元素的過濾,或者鏈?zhǔn)竭x擇訪問。

Select方法將返回一個Elements集合,并提供一組方法來抽取和處理結(jié)果。

Selector選擇器概述

·?tagname:?通過標(biāo)簽查找元素,比如:a

·?ns|tag:?通過標(biāo)簽在命名空間查找元素,比如:可以用?fb|name?語法來查找?<fb:name>?元素

·?#id:?通過ID查找元素,比如:#logo

·?.class:?通過class名稱查找元素,比如:.masthead

·?[attribute]:?利用屬性查找元素,比如:[href]

·?[^attr]:?利用屬性名前綴來查找元素,比如:可以用[^data-]?來查找?guī)в?span style="font-family:Arial">HTML5?Dataset屬性的元素

·?[attr=value]:?利用屬性值來查找元素,比如:[width=500]

·?[attr^=value],?[attr$=value],?[attr*=value]:?利用匹配屬性值開頭、結(jié)尾或包含屬性值來查找元素,比如:[href*=/path/]

·?[attr~=regex]:?利用屬性值匹配正則表達(dá)式來查找元素,比如:?img[src~=(?i)\.(png|jpe?g)]

·?*:?這個符號將匹配所有元素

Selector選擇器組合使用

·?el#id:?元素+ID,比如:?div#logo

·?el.class:?元素+class,比如:?div.masthead

·?el[attr]:?元素+class,比如:?a[href]

·?任意組合,比如:a[href].highlight

·?ancestor?child:?查找某個元素下子元素,比如:可以用.body?p?查找在"body"元素下的所有?p元素

·?parent?>?child:?查找某個父元素下的直接子元素,比如:可以用div.content?>?p?查找?p?元素,也可以用body?>?*?查找body標(biāo)簽下所有直接子元素

·?siblingA?+?siblingB:?查找在A元素之前第一個同級元素B,比如:div.head?+?div

·?siblingA?~?siblingX:?查找A元素之前的同級X元素,比如:h1?~?p

·?el,?el,?el:多個選擇器組合,查找匹配任一選擇器的唯一元素,例如:div.masthead,?div.logo

偽選擇器selectors

·?:lt(n):?查找哪些元素的同級索引值(它的位置在DOM樹中是相對于它的父節(jié)點(diǎn))小于n,比如:td:lt(3)?表示小于三列的元素?

·?:gt(n):查找哪些元素的同級索引值大于n,比如:?div?p:gt(2)表示哪些div中有包含2個以上的p元素

·?:eq(n):?查找哪些元素的同級索引值與n相等,比如:form?input:eq(1)表示包含一個input標(biāo)簽的Form元素

·?:has(seletor):?查找匹配選擇器包含元素的元素,比如:div:has(p)表示哪些div包含了p元素?

·?:not(selector):?查找與選擇器不匹配的元素,比如:?div:not(.logo)?表示不包含?class=logo?元素的所有?div?列表?

·?:contains(text):?查找包含給定文本的元素,搜索不區(qū)分大不寫,比如:?p:contains(jsoup)

·?:containsOwn(text):?查找直接包含給定文本的元素

·?:matches(regex):?查找哪些元素的文本匹配指定的正則表達(dá)式,比如:div:matches((?i)login)

·?:matchesOwn(regex):?查找自身包含文本匹配指定正則表達(dá)式的元素

·?注意:上述偽選擇器索引是從0開始的,也就是說第一個元素索引值為0,第二個元素index1

可以查看Selector?API參考來了解更詳細(xì)的內(nèi)容

?

?

?

?

?

?

?

8.從元素抽取屬性,文本和HTML

問題

在解析獲得一個Document實例對象,并查找到一些元素之后,你希望取得在這些元素中的數(shù)據(jù)。

方法

·?要取得一個屬性的值,可以使用Node.attr(String?key)?方法?

·?對于一個元素中的文本,可以使用Element.text()方法

·?對于要取得元素或?qū)傩灾械?span style="font-family:Arial">HTML內(nèi)容,可以使用Element.html(),?或?Node.outerHtml()方法

示例:

String?html?=?"<p>An?<a?href='http://example.com/'><b>example</b></a>?link.</p>";

Document?doc?=?Jsoup.parse(html);//解析HTML字符串返回一個Document實現(xiàn)

Element?link?=?doc.select("a").first();//查找第一個a元素

?

String?text?=?doc.body().text();?//?"An?example?link"//取得字符串中的文本

String?linkHref?=?link.attr("href");?//?"http://example.com/"//取得鏈接地址

String?linkText?=?link.text();?//?"example""//取得鏈接地址中的文本

?

String?linkOuterH?=?link.outerHtml();?

????//?"<a?href="http://example.com"><b>example</b></a>"

String?linkInnerH?=?link.html();?//?"<b>example</b>"//取得鏈接內(nèi)的html內(nèi)容

說明

上述方法是元素數(shù)據(jù)訪問的核心辦法。此外還其它一些方法可以使用:

·?Element.id()

·?Element.tagName()

·?Element.className()?and?Element.hasClass(String?className)

這些訪問器方法都有相應(yīng)的setter方法來更改數(shù)據(jù).

參見

·?ElementElements集合類的參考文檔

·?URLs處理

·?使用CSS選擇器語法來查找元素

?

?

?

?

?

?

?

?

9.處理URLs

問題

你有一個包含相對URLs路徑的HTML文檔,需要將這些相對路徑轉(zhuǎn)換成絕對路徑的URLs

方法

1.?在你解析文檔時確保有指定base?URI,然后

2.?使用?abs:?屬性前綴來取得包含base?URI的絕對路徑。代碼如下:?

Document?doc?=?Jsoup.connect("http://www.open-open.com").get();

?

Element?link?=?doc.select("a").first();

String?relHref?=?link.attr("href");?//?==?"/"

String?absHref?=?link.attr("abs:href");?//?"http://www.open-open.com/"

說明

HTML元素中,URLs經(jīng)常寫成相對于文檔位置的相對路徑:?<a?href="/download">...</a>.?當(dāng)你使用?Node.attr(String?key)?方法來取得a元素的href屬性時,它將直接返回在HTML源碼中指定定的值。

假如你需要取得一個絕對路徑,需要在屬性名前加?abs:?前綴。這樣就可以返回包含根路徑的URL地址attr("abs:href")

因此,在解析HTML文檔時,定義base?URI非常重要。

如果你不想使用abs:?前綴,還有一個方法能夠?qū)崿F(xiàn)同樣的功能?Node.absUrl(String?key)

?

?

?

?

?

10.示例程序:?獲取所有鏈接

這個示例程序?qū)⒄故救绾螐囊粋€URL獲得一個頁面。然后提取頁面中的所有鏈接、圖片和其它輔助內(nèi)容。并檢查URLs和文本信息。

運(yùn)行下面程序需要指定一個URLs作為參數(shù)

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;

????}

}

org/jsoup/examples/ListLinks.java

示例輸入結(jié)果

Fetching?http://news.ycombinator.com/...

?

Media:?(38)

?*?img:?<http://ycombinator.com/images/y18.gif>?18x18?()

?*?img:?<http://ycombinator.com/images/s.gif>?10x1?()

?*?img:?<http://ycombinator.com/images/grayarrow.gif>?x?()

?*?img:?<http://ycombinator.com/images/s.gif>?0x10?()

?*?script:?<http://www.co2stats.com/propres.php?s=1138>

?*?img:?<http://ycombinator.com/images/s.gif>?15x1?()

?*?img:?<http://ycombinator.com/images/hnsearch.png>?x?()

?*?img:?<http://ycombinator.com/images/s.gif>?25x1?()

?*?img:?<http://mixpanel.com/site_media/images/mixpanel_partner_logo_borderless.gif>?x?(Analytics?by?Mixpan.)

?

Imports:?(2)

?*?link?<http://ycombinator.com/news.css>?(stylesheet)

?*?link?<http://ycombinator.com/favicon.ico>?(shortcut?icon)

?

Links:?(141)

?*?a:?<http://ycombinator.com>??()

?*?a:?<http://news.ycombinator.com/news>??(Hacker?News)

?*?a:?<http://news.ycombinator.com/newest>??(new)

?*?a:?<http://news.ycombinator.com/newcomments>??(comments)

?*?a:?<http://news.ycombinator.com/leaders>??(leaders)

?*?a:?<http://news.ycombinator.com/jobs>??(jobs)

?*?a:?<http://news.ycombinator.com/submit>??(submit)

?*?a:?<http://news.ycombinator.com/x?fnid=JKhQjfU7gW>??(login)

?*?a:?<http://news.ycombinator.com/vote?for=1094578&dir=up&whence=%6e%65%77%73>??()

?*?a:?<http://www.readwriteweb.com/archives/facebook_gets_faster_debuts_homegrown_php_compiler.php?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+readwriteweb+%28ReadWriteWeb%29&utm_content=Twitter>??(Facebook?speeds?up?PHP)

?*?a:?<http://news.ycombinator.com/user?id=mcxx>??(mcxx)

?*?a:?<http://news.ycombinator.com/item?id=1094578>??(9?comments)

?*?a:?<http://news.ycombinator.com/vote?for=1094649&dir=up&whence=%6e%65%77%73>??()

?*?a:?<http://groups.google.com/group/django-developers/msg/a65fbbc8effcd914>??("Tough.?Django?produces?XHTML.")

?*?a:?<http://news.ycombinator.com/user?id=andybak>??(andybak)

?*?a:?<http://news.ycombinator.com/item?id=1094649>??(3?comments)

?*?a:?<http://news.ycombinator.com/vote?for=1093927&dir=up&whence=%6e%65%77%73>??()

?*?a:?<http://news.ycombinator.com/x?fnid=p2sdPLE7Ce>??(More)

?*?a:?<http://news.ycombinator.com/lists>??(Lists)

?*?a:?<http://news.ycombinator.com/rss>??(RSS)

?*?a:?<http://ycombinator.com/bookmarklet.html>??(Bookmarklet)

?*?a:?<http://ycombinator.com/newsguidelines.html>??(Guidelines)

?*?a:?<http://ycombinator.com/newsfaq.html>??(FAQ)

?*?a:?<http://ycombinator.com/newsnews.html>??(News?News)

?*?a:?<http://news.ycombinator.com/item?id=363>??(Feature?Requests)

?*?a:?<http://ycombinator.com>??(Y?Combinator)

?*?a:?<http://ycombinator.com/w2010.html>??(Apply)

?*?a:?<http://ycombinator.com/lib.html>??(Library)

?*?a:?<http://www.webmynd.com/html/hackernews.html>??()

?*?a:?<http://mixpanel.com/?from=yc>??()

?

?

?

?

?

11.設(shè)置屬性的值

問題

在你解析一個Document之后可能想修改其中的某些屬性值,然后再保存到磁盤或都輸出到前臺頁面。

方法

可以使用屬性設(shè)置方法?Element.attr(String?key,?String?value),?和?Elements.attr(String?key,?String?value).

假如你需要修改一個元素的?class?屬性,可以使用?Element.addClass(String?className)?和?Element.removeClass(String?className)?方法。

Elements?提供了批量操作元素屬性和class的方法,比如:要為div中的每一個a元素都添加一個?rel="nofollow"?可以使用如下方法:

doc.select("div.comments?a").attr("rel",?"nofollow");

說明

Element中的其它方法一樣,attr?方法也是返回當(dāng)?Element?(或在使用選擇器是返回?Elements?集合)。這樣能夠很方便使用方法連用的書寫方式。比如:

doc.select("div.masthead").attr("title",?"jsoup").addClass("round-box");

?

?

?

?

?

??

12.設(shè)置一個元素的HTML內(nèi)容

問題

你需要一個元素中的HTML內(nèi)容

方法

可以使用Element中的HTML設(shè)置方法具體如下:

Element?div?=?doc.select("div").first();?//?<div></div>

div.html("<p>lorem?ipsum</p>");?//?<div><p>lorem?ipsum</p></div>

div.prepend("<p>First</p>");//div前添加html內(nèi)容

div.append("<p>Last</p>");//div之后添加html內(nèi)容

//?添完后的結(jié)果:?<div><p>First</p><p>lorem?ipsum</p><p>Last</p></div>

?

Element?span?=?doc.select("span").first();?//?<span>One</span>

span.wrap("<li><a?href='http://example.com/'></a></li>");

//?添完后的結(jié)果:?<li><a?href="http://example.com"><span>One</span></a></li>

說明

·?Element.html(String?html)?這個方法將先清除元素中的HTML內(nèi)容,然后用傳入的HTML代替。

·?Element.prepend(String?first)?和?Element.append(String?last)?方法用于在分別在元素內(nèi)部HTML的前面和后面添加HTML內(nèi)容

·?Element.wrap(String?around)?對元素包裹一個外部HTML內(nèi)容。

參見

可以查看API參考文檔中?Element.prependElement(String?tag)Element.appendElement(String?tag)?方法來創(chuàng)建新的元素并作為文檔的子元素插入其中。

13.設(shè)置元素的文本內(nèi)容

問題

你需要修改一個HTML文檔中的文本內(nèi)容

方法

可以使用Element的設(shè)置方法::

Element?div?=?doc.select("div").first();?//?<div></div>

div.text("five?>?four");?//?<div>five?>?four</div>

div.prepend("First?");

div.append("?Last");

//?now:?<div>First?five?>?four?Last</div>

說明

文本設(shè)置方法與?HTML?setter?方法一樣:

·?Element.text(String?text)?將清除一個元素中的內(nèi)部HTML內(nèi)容,然后提供的文本進(jìn)行代替

·?Element.prepend(String?first)?和?Element.append(String?last)?將分別在元素的內(nèi)部html前后添加文本節(jié)點(diǎn)。

對于傳入的文本如果含有像?<,?>?等這樣的字符,將以文本處理,而非HTML

?

?

?

?

?

??

14.消除不受信任的HTML?(來防止XSS攻擊)

問題

在做網(wǎng)站的時候,經(jīng)常會提供用戶評論的功能。有些不懷好意的用戶,會搞一些腳本到評論內(nèi)容中,而這些腳本可能會破壞整個頁面的行為,更嚴(yán)重的是獲取一些機(jī)要信息,此時需要清理該HTML,以避免跨站腳本cross-site?scripting攻擊(XSS)。

方法

使用jsoup?HTML?Cleaner?方法進(jìn)行清除,但需要指定一個可配置的?Whitelist

String?unsafe?=?

??"<p><a?href='http://example.com/'?οnclick='stealCookies()'>Link</a></p>";

String?safe?=?Jsoup.clean(unsafe,?Whitelist.basic());

//?now:?<p><a?href="http://example.com/"?rel="nofollow">Link</a></p>

說明

XSS又叫CSS?(Cross?Site?Script)?,跨站腳本攻擊。它指的是惡意攻擊者往Web頁面里插入惡意html代碼,當(dāng)用戶瀏覽該頁之時,嵌入其中Web里面的html代碼會被執(zhí)行,從而達(dá)到惡意攻擊用戶的特殊目的。XSS屬于被動式的攻擊,因為其被動且不好利用,所以許多人常忽略其危害性。所以我們經(jīng)常只讓用戶輸入純文本的內(nèi)容,但這樣用戶體驗就比較差了。

一個更好的解決方法就是使用一個富文本編輯器WYSIWYGCKEditor?和?TinyMCE。這些可以輸出HTML并能夠讓用戶可視化編輯。雖然他們可以在客戶端進(jìn)行校驗,但是這樣還不夠安全,需要在服務(wù)器端進(jìn)行校驗并清除有害的HTML代碼,這樣才能確保輸入到你網(wǎng)站的HTML是安全的。否則,攻擊者能夠繞過客戶端的Javascript驗證,并注入不安全的HMTL直接進(jìn)入您的網(wǎng)站。

jsoupwhitelist清理器能夠在服務(wù)器端對用戶輸入的HTML進(jìn)行過濾,只輸出一些安全的標(biāo)簽和屬性。

jsoup提供了一系列的Whitelist基本配置,能夠滿足大多數(shù)要求;但如有必要,也可以進(jìn)行修改,不過要小心。

這個cleaner非常好用不僅可以避免XSS攻擊,還可以限制用戶可以輸入的標(biāo)簽范圍。

參見

http://download.csdn.net/detail/wisewall/3461216?locationNum=11&fps=1

總結(jié)

以上是生活随笔為你收集整理的java的html解析器——Jsoup详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。