Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
解析HTML文檔,可以使用一些編程語(yǔ)言中的HTML解析庫(kù)或工具。以下是一些常用的方法:
from bs4 import BeautifulSoup
# 讀取HTML文檔
with open('example.html', 'r') as file:
html = file.read()
# 創(chuàng)建BeautifulSoup對(duì)象
soup = BeautifulSoup(html, 'html.parser')
# 使用BeautifulSoup對(duì)象提取數(shù)據(jù)
# 例如,提取所有的鏈接
links = soup.find_all('a')
for link in links:
print(link.get('href'))
// 讀取HTML文檔
var html = document.documentElement.innerHTML;
// 使用DOM解析器提取數(shù)據(jù)
// 例如,提取所有的鏈接
var links = document.getElementsByTagName('a');
for (var i = 0; i < links.length; i++) {
console.log(links[i].getAttribute('href'));
}
無(wú)論你選擇哪種方法,解析HTML文檔的關(guān)鍵是了解HTML的結(jié)構(gòu)和標(biāo)簽,并使用相應(yīng)的解析器或工具來(lái)提取所需的數(shù)據(jù)。
當(dāng)你解析HTML文檔時(shí),你可能會(huì)遇到以下一些常見(jiàn)的任務(wù)和技術(shù):
總的來(lái)說(shuō),解析HTML文檔需要一定的HTML知識(shí)和編程技巧。你需要了解HTML的結(jié)構(gòu)和標(biāo)簽,選擇合適的解析器或工具,使用選擇器來(lái)定位元素,提取所需的數(shù)據(jù),并處理特殊情況。通過(guò)不斷練習(xí)和實(shí)踐,你將能夠更熟練地解析HTML文檔并提取所需的數(shù)據(jù)。
tmlAgilityPack是一個(gè).NET平臺(tái)下的HTML解析庫(kù),它可以將HTML文本轉(zhuǎn)換為DOM文檔對(duì)象,方便我們對(duì)HTML文本進(jìn)行操作和分析。HtmlAgilityPack支持XPath語(yǔ)法,可以通過(guò)XPath表達(dá)式來(lái)獲取DOM節(jié)點(diǎn),同時(shí)還提供了一些方便的API,可以實(shí)現(xiàn)HTML文本的解析、修改、生成等功能。本文將詳細(xì)介紹HtmlAgilityPack的使用及使用方法。
一、HtmlAgilityPack的安裝
HtmlAgilityPack是一個(gè)NuGet包,可以通過(guò)Visual Studio的NuGet包管理器來(lái)安裝。具體步驟如下:
安裝完成后,就可以在項(xiàng)目中使用HtmlAgilityPack了。
二、HtmlAgilityPack的使用
使用HtmlAgilityPack解析HTML文本的第一步是將HTML文本加載到一個(gè)HtmlDocument對(duì)象中??梢酝ㄟ^(guò)以下代碼來(lái)實(shí)現(xiàn):
HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(htmlText);
其中,htmlText是要解析的HTML文本。LoadHtml方法會(huì)將HTML文本解析成一個(gè)DOM文檔對(duì)象,并存儲(chǔ)在doc對(duì)象中。
HtmlAgilityPack提供了一些方法來(lái)獲取DOM節(jié)點(diǎn),例如GetElementById、GetElementsByTagName、SelectSingleNode、SelectNodes等。這些方法都接受一個(gè)XPath表達(dá)式作為參數(shù),用來(lái)指定要獲取的節(jié)點(diǎn)。以下是一些示例代碼:
// 獲取id為"content"的節(jié)點(diǎn)
HtmlNode contentNode = doc.GetElementById("content");
// 獲取所有的a標(biāo)簽
HtmlNodeCollection aNodes = doc.DocumentNode.SelectNodes("//a");
// 獲取第一個(gè)p標(biāo)簽
HtmlNode pNode = doc.DocumentNode.SelectSingleNode("//p");
其中,XPath表達(dá)式的語(yǔ)法與XML的XPath語(yǔ)法相同。在這里不再詳細(xì)介紹。
HtmlAgilityPack提供了一些方法來(lái)修改DOM節(jié)點(diǎn),例如SetAttributeValue、InnerHtml、OuterHtml等。以下是一些示例代碼:
// 修改id為"content"的節(jié)點(diǎn)的class屬性
contentNode.SetAttributeValue("class", "new-class");
// 修改第一個(gè)p標(biāo)簽的內(nèi)容
pNode.InnerHtml = "這是新的內(nèi)容";
// 修改第一個(gè)a標(biāo)簽的href屬性
HtmlNode aNode = aNodes[0];
aNode.SetAttributeValue("href", "http://www.example.com");
HtmlAgilityPack還可以將DOM文檔對(duì)象轉(zhuǎn)換為HTML文本。可以通過(guò)以下代碼來(lái)實(shí)現(xiàn):
string newHtmlText = doc.DocumentNode.OuterHtml;
其中,OuterHtml屬性返回DOM文檔對(duì)象的HTML文本表示。
三、HtmlAgilityPack的功能實(shí)例
下面將通過(guò)一些具體的實(shí)例來(lái)演示HtmlAgilityPack的使用方法。
以下代碼演示了如何獲取頁(yè)面標(biāo)題:
HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(htmlText);
HtmlNode titleNode = doc.DocumentNode.SelectSingleNode("//title");
string title = titleNode.InnerHtml;
其中,htmlText是要解析的HTML文本。首先,將HTML文本加載到一個(gè)HtmlDocument對(duì)象中。然后,通過(guò)XPath表達(dá)式“//title”獲取頁(yè)面標(biāo)題節(jié)點(diǎn)。最后,通過(guò)InnerHtml屬性獲取標(biāo)題的內(nèi)容。
以下代碼演示了如何獲取頁(yè)面中的所有圖片:
HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(htmlText);
HtmlNodeCollection imgNodes = doc.DocumentNode.SelectNodes("//img");
foreach (HtmlNode imgNode in imgNodes)
{
string src = imgNode.GetAttributeValue("src", "");
Console.WriteLine(src);
}
首先,將HTML文本加載到一個(gè)HtmlDocument對(duì)象中。然后,通過(guò)XPath表達(dá)式“//img”獲取所有圖片節(jié)點(diǎn)。最后,遍歷所有圖片節(jié)點(diǎn),獲取每個(gè)節(jié)點(diǎn)的src屬性。
以下代碼演示了如何獲取頁(yè)面中的所有鏈接:
HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(htmlText);
HtmlNodeCollection aNodes = doc.DocumentNode.SelectNodes("//a");
foreach (HtmlNode aNode in aNodes)
{
string href = aNode.GetAttributeValue("href", "");
Console.WriteLine(href);
}
首先,將HTML文本加載到一個(gè)HtmlDocument對(duì)象中。然后,通過(guò)XPath表達(dá)式“//a”獲取所有鏈接節(jié)點(diǎn)。最后,遍歷所有鏈接節(jié)點(diǎn),獲取每個(gè)節(jié)點(diǎn)的href屬性。
以下代碼演示了如何將頁(yè)面中的所有鏈接修改為指定的鏈接:
HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(htmlText);
HtmlNodeCollection aNodes = doc.DocumentNode.SelectNodes("//a");
foreach (HtmlNode aNode in aNodes)
{
aNode.SetAttributeValue("href", "http://www.example.com");
}
string newHtmlText = doc.DocumentNode.OuterHtml;
首先,將HTML文本加載到一個(gè)HtmlDocument對(duì)象中。然后,通過(guò)XPath表達(dá)式“//a”獲取所有鏈接節(jié)點(diǎn)。最后,遍歷所有鏈接節(jié)點(diǎn),將它們的href屬性修改為指定的鏈接。最后,通過(guò)OuterHtml屬性將修改后的DOM文檔對(duì)象轉(zhuǎn)換為HTML文本。
本文介紹了HtmlAgilityPack的使用及使用方法。HtmlAgilityPack是一個(gè)功能強(qiáng)大、易用性高的HTML解析庫(kù),可以方便地對(duì)HTML文本進(jìn)行操作和分析。通過(guò)本文的介紹,讀者可以了解HtmlAgilityPack的基本用法,并可以根據(jù)需要自行擴(kuò)展。
我們先前進(jìn)行網(wǎng)站頁(yè)面內(nèi)容解析的過(guò)程中,通常選擇運(yùn)用正則表達(dá)式來(lái)完成此任務(wù)。然而,正如前面幾篇文章所闡述和分析的那樣,無(wú)論是正則表達(dá)式還是XPath,它們雖各自具備適應(yīng)不同應(yīng)用場(chǎng)景的優(yōu)勢(shì),卻也都存在著各自難以避免的缺陷。例如,正則表達(dá)式具有相對(duì)復(fù)雜的語(yǔ)法結(jié)構(gòu)并且需要大量的編程知識(shí)才能熟練掌握;而XPath雖然使得實(shí)現(xiàn)路徑查找更為簡(jiǎn)潔易懂,但卻需要編寫(xiě)復(fù)雜的節(jié)點(diǎn)路徑編碼。因此,為了充分利用HTML讀取技術(shù)的強(qiáng)大功能,同時(shí)追求更加簡(jiǎn)明直觀(guān)的操作體驗(yàn),本文將向您推薦Beautiful Soup這款強(qiáng)大的三方工具。那么,它是否能夠如其名字那般“美麗”呢?接下來(lái),讓我們共同揭開(kāi)這個(gè)謎團(tuán)!
Beautiful Soup 也是一個(gè) Python 的 XML 和 HTML 的解析庫(kù),其提供了簡(jiǎn)單的,Python 式的函數(shù)來(lái)處理導(dǎo)航,搜索,修改分析樹(shù)等功能(來(lái)自官方介紹)。
Beautiful Soup來(lái)源于愛(ài)麗絲夢(mèng)游仙境
在使用 Beautiful Soup 之前,需要安裝好 lxml(推薦 lxml 解析器) 和其自身的庫(kù)。
pip install beautifulsoup4
pip install lxml
beautiful Soup 在解析過(guò)程中依賴(lài)各種解析器,除了支持 Python 標(biāo)準(zhǔn)的解析器外,還支持其他的三方解析器(如: lxml)。
各種解析器優(yōu)缺點(diǎn)
一般在使用的過(guò)程中,推薦使用 lxml,因?yàn)?lxml 本身也是一個(gè)非常優(yōu)秀的解析庫(kù),也支持 XML 的解析。
假設(shè)有以下內(nèi)容的 html 文檔。
<!DOCTYPE html>
<html lang="en">
<body>
<div>
<ul>
<li class="class-0">
<a href="a.html">
<span>第一個(gè)標(biāo)簽</span>
</a>
</li>
</ul>
</div>
</body>
</html>
from bs4 import BeautifulSoup
# 初始化BeautifulSoup,并指定lxml為解析器
soup = BeautifulSoup(open("index.html"),
"lxml")
# 獲取span標(biāo)簽
print(soup.span)
print(soup.span.string)
# <span>第一個(gè)標(biāo)簽</span>
# 第一個(gè)標(biāo)簽
如上代碼,BeautifulSoup 方法有有兩個(gè)參數(shù), 第一個(gè)參數(shù)接受一個(gè) html 文檔,第二個(gè)參數(shù)指定解釋器類(lèi)型,這樣就初始化了一個(gè)BeautifulSoup 的對(duì)象,后續(xù)就可以使用這個(gè)對(duì)象來(lái)解析和獲取 HTML 中的數(shù)據(jù),如上方獲取 span, 并獲取 span 的內(nèi)容。
獲取 bs 對(duì)象有兩種方式,一種是直接使用文本字符,另一種是讀取文檔:
from bs4 import BeautifulSoup
soup = BeautifulSoup(open("index.html"))
soup = BeautifulSoup("<html>data</html>")
通過(guò)上邊的代碼示例可以看到,在獲取到 bs 對(duì)象后,后續(xù)直接調(diào)用節(jié)點(diǎn)名稱(chēng)就可以獲取到節(jié)點(diǎn)對(duì)象,再調(diào)用 string 屬性就可以獲取到節(jié)點(diǎn)的文本內(nèi)容,相較于使用正則表達(dá)式或者 XPath 效率是非常高的。
html_doc = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html_doc, 'html.parser')
# 獲取title標(biāo)簽
soup.title
# <title>The Dormouse's story</title>
#獲取title標(biāo)簽名字
soup.title.name
# u'title'
#獲取title標(biāo)簽文本內(nèi)容
soup.title.string
# u'The Dormouse's story'
#獲取title父標(biāo)簽
soup.title.parent.name
# u'head'
#獲取p標(biāo)簽
soup.p
# <p class="title"><b>The Dormouse's story</b></p>
#獲取p標(biāo)簽的class屬性
soup.p['class']
# u'title'
# 獲取a標(biāo)簽
soup.a
# <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>
# 查找所有的a標(biāo)簽
soup.find_all('a')
# [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
# <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
# <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
# 查找id為link3的標(biāo)簽
soup.find(id="link3")
# <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>
雖然在 Beautiful Soup 中可以將復(fù)雜的 HTML 文檔轉(zhuǎn)換為樹(shù)形結(jié)構(gòu),但是從大體可歸納為以下 4 個(gè)對(duì)象:
Tag:Tag 對(duì)象用于表示 HTML 和 XML 文檔中的 tag 標(biāo)簽。
soup = BeautifulSoup('<b class="boldest">Extremely bold</b>')
tag = soup.b
type(tag)
# <class 'bs4.element.Tag'>
tag.name
# u'b'
tag['class']
# u'boldest'
如上任何的標(biāo)簽在Beautiful Soup 都表示為一個(gè) Tag 對(duì)象,且從該對(duì)象上獲取到當(dāng)前標(biāo)簽的各種屬性值。
NavigableString :表示 Tag 中被包裹的字符串
tag.string
# u'Extremely bold'
type(tag.string)
# <class 'bs4.element.NavigableString'>
BeautifulSoup :該對(duì)象表示文檔整體的一個(gè)類(lèi),即初始化后獲得的類(lèi),所以獲取到該類(lèi),就獲取到了整個(gè)文檔。需要注意需要和上邊 Tag 類(lèi)做出區(qū)分,BeautifulSoup 類(lèi)是特殊的 Tag 類(lèi)。
Comment :表示文檔中的注釋內(nèi)容,其本質(zhì)也是一個(gè)特殊的NavigableString 對(duì)象,但由于其特殊性,單獨(dú)做封裝處理。
除了上邊的屬性選擇器和方法選擇器外,Beautiful Soup 還提供 CSS 選擇器,這對(duì)于有前端樣式開(kāi)發(fā)經(jīng)驗(yàn)的同學(xué)來(lái)說(shuō)是非常給力的一個(gè)特性。通過(guò) CSS 選擇器也可以輕松的選定各個(gè)節(jié)點(diǎn),但在使用中和上邊的有所不同需要調(diào)用 .selsect() 方法, 如下方代碼:
soup.select("title")
# [<title>The Dormouse's story</title>]
soup.select("p:nth-of-type(3)")
# [<p class="story">...</p>]
有不熟悉css選擇器的小伙伴可以在w3c上學(xué)習(xí),一般基礎(chǔ)的選擇器就可勝任絕大多數(shù)數(shù)據(jù)獲取的任務(wù)。
*請(qǐng)認(rèn)真填寫(xiě)需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。