爬剖HTML檔
Last updated
Was this helpful?
Last updated
Was this helpful?
HTML檔案的結構大致如下:
首先會有一個檔案類別的宣告<!DOCTYPE html>,用以告訴第三方瀏覽器或應用程式說這是一個HTML5檔案;
再來是成對標籤所組成的巢套結構,下例即有一對<html></html>包著一對<head></head>和一對<body></body>。
另外<!---->包著的內容為註解,瀏覽器或程式遇到該區段的內容會略過不處理。
每一對標籤,我們把它稱為一個Element(HTML元素)。下二圖為兩個元素(elements),一對「標籤(tags)」前後包夾稱為一個「元素」,在Opening tag中除了標籤名外的其他資訊為「屬性(Attribute)」,一個屬性包含屬性名稱(Attribute name)和屬性值(Attribute value),屬性值多為文字,所以需要用雙引號括起來。
例如:以下自由時報新聞關鍵字查詢的結果以及pchome24h購物中心產品查詢的結果。可見ㄍ到<a></a>為一對elements、而網址則以attribute value指給href這個既定名稱的<a>的屬性。
那我們要的資料通常會怎麼放在HTML上呢?
<p> 通常如果是本文多會是用<p></p>,<p>的意義為paragraph;
<h1>如果是要取出新聞或文章標題的話,通常會是<h1>、<h2>等headings(標題);
<li>若回傳的搜尋結果的話,多半會是用<ul></ul>內包著<li></li> 表示,<ul>為unordered list(無序列表)、<li>為list item(列表中的項目)
<table>若是查詢資料結果為網頁「表格」多半用<table></table>包裹,裡面會有<th></th>、<tr></tr>、<td></td>等,分別為table header、table row、與table data。
<div>網頁中巢套的最厲害的是<div></div>為division的縮寫,也就是網頁的區塊,通常被用來區隔頁面中的區塊,是進行排版和視覺化的好幫手。
在一個html檔案中,id是唯一的,而class則可以出現在好幾個地方。因此,若你要的資料外包一個有id的區塊,應該非常高興。例如下面的例子的CSS Selector可縮寫為 #newslistul li
XPath and CSS selector: 一般來說,要獲取HTML文檔中的內容有兩種途徑,一種是CSS Selector,和CSS語法、概念完全相同;另一種是XPath,不是那麼常看見,但卻有支援一些CSS Selector沒支援的功能(例如用text()取出沒有HTML tag僅有純文字的部分)。CSS Selector和XPath是用來定義一個路徑,以選取HTML中的一個或者多個條件相同的元素。例如說,定義一條路徑來選取頁面上所有的標題,或選取所有標題背後的超鏈結,或選取頁面上搜尋結果的圖片路徑、或選取某PTT Web上討論版某篇文章所有回文者的ID。
對著你所要複製資料路徑(或者元素路徑)的元素按右鍵,就可以複製CSS seletor與XPath路徑,自由時報的搜尋結果為例,其在搜尋結果頁面的一則文章其CSS selector與XPath分別為
CSS selector: #newslistul > li:nth-child(1)
XPath: //*[@id="newslistul"]/li[1]
注意看上面的例子會發現他是從#newslistul
這個id開始寫起,因為id在整個HTML內理論上是唯一的,所以前面的路徑都可以省了。而複製的路徑#newslistul > li:nth-child(1)
表示#newsslistul
這個id底下的第一個<li>,可以進一步修改路徑以 表示#newslistul
底下的<li>
我全都要了#newslistul li
。
若以XPath來看的話,複製的路徑://*[@id="newslistul"]/li[1]
//
表示選取所有可能的情形
*
表示任意一個element。因為有id的關係,所以可以忽略它本身是個甚麼物件,所以用//*
代表即可
*[@id="newslistul"]
表示任意一個id為newslistul
的元素
/li[1]
在前述標籤底下的表示第一個<li>
可更改路徑為選取全部的元素,而非只是第一個://*[@id="newslistul"]//li
。//li
表示在前述標籤底下的所有<li>
我都要
下圖可用以說明HTML檔案的巢套(一層包一層)結構(圖片來源)。