本文轉(zhuǎn)載:靜覓 ? [Python3網(wǎng)絡(luò)爬蟲開發(fā)實戰(zhàn)] 2.2-網(wǎng)頁基礎(chǔ)
用瀏覽器訪問網(wǎng)站時,頁面各不相同,你有沒有想過它為何會呈現(xiàn)這個樣子呢?本節(jié)中,我們就來了解一下網(wǎng)頁的基本組成、結(jié)構(gòu)和節(jié)點等內(nèi)容。
1. 網(wǎng)頁的組成
網(wǎng)頁可以分為三大部分——HTML、CSS和JavaScript。如果把網(wǎng)頁比作一個人的話,HTML相當(dāng)于骨架,JavaScript相當(dāng)于肌肉,CSS相當(dāng)于皮膚,三者結(jié)合起來才能形成一個完善的網(wǎng)頁。下面我們分別來介紹一下這三部分的功能。
(1) HTML
HTML是用來描述網(wǎng)頁的一種語言,其全稱叫作Hyper Text Markup Language,即超文本標(biāo)記語言。網(wǎng)頁包括文字、按鈕、圖片和視頻等各種復(fù)雜的元素,其基礎(chǔ)架構(gòu)就是HTML。不同類型的文字通過不同類型的標(biāo)簽來表示,如圖片用img標(biāo)簽表示,視頻用video標(biāo)簽表示,段落用p標(biāo)簽表示,它們之間的布局又常通過布局標(biāo)簽div嵌套組合而成,各種標(biāo)簽通過不同的排列和嵌套才形成了網(wǎng)頁的框架。
在Chrome瀏覽器中打開百度,右擊并選擇“檢查”項(或按F12鍵),打開開發(fā)者模式,這時在Elements選項卡中即可看到網(wǎng)頁的源代碼,如圖2-9所示。

圖2-9 源代碼
這就是HTML,整個網(wǎng)頁就是由各種標(biāo)簽嵌套組合而成的。這些標(biāo)簽定義的節(jié)點元素相互嵌套和組合形成了復(fù)雜的層次關(guān)系,就形成了網(wǎng)頁的架構(gòu)。
(2) CSS
HTML定義了網(wǎng)頁的結(jié)構(gòu),但是只有HTML頁面的布局并不美觀,可能只是簡單的節(jié)點元素的排列,為了讓網(wǎng)頁看起來更好看一些,這里借助了CSS。
CSS,全稱叫作Cascading Style Sheets,即層疊樣式表?!皩盈B”是指當(dāng)在HTML中引用了數(shù)個樣式文件,并且樣式發(fā)生沖突時,瀏覽器能依據(jù)層疊順序處理。“樣式”指網(wǎng)頁中文字大小、顏色、元素間距、排列等格式。
CSS是目前唯一的網(wǎng)頁頁面排版樣式標(biāo)準(zhǔn),有了它的幫助,頁面才會變得更為美觀。
圖2-9的右側(cè)即為CSS,例如:
#head_wrapper.s-ps-islite .s-p-top {
position: absolute;
bottom: 40px;
width: 100%;
height: 181px;
}
就是一個CSS樣式。大括號前面是一個CSS選擇器,此選擇器的意思是首先選中id為head_wrapper且class為s-ps-islite的節(jié)點,然后再選中其內(nèi)部的class為s-p-top的節(jié)點。大括號內(nèi)部寫的就是一條條樣式規(guī)則,例如position指定了這個元素的布局方式為絕對布局,bottom指定元素的下邊距為40像素,width指定了寬度為100%占滿父元素,height則指定了元素的高度。也就是說,我們將位置、寬度、高度等樣式配置統(tǒng)一寫成這樣的形式,然后用大括號括起來,接著在開頭再加上CSS選擇器,這就代表這個樣式對CSS選擇器選中的元素生效,元素就會根據(jù)此樣式來展示了。
在網(wǎng)頁中,一般會統(tǒng)一定義整個網(wǎng)頁的樣式規(guī)則,并寫入CSS文件中(其后綴為css)。在HTML中,只需要用link標(biāo)簽即可引入寫好的CSS文件,這樣整個頁面就會變得美觀、優(yōu)雅。
(3) JavaScript
JavaScript,簡稱JS,是一種腳本語言。HTML和CSS配合使用,提供給用戶的只是一種靜態(tài)信息,缺乏交互性。我們在網(wǎng)頁里可能會看到一些交互和動畫效果,如下載進度條、提示框、輪播圖等,這通常就是JavaScript的功勞。它的出現(xiàn)使得用戶與信息之間不只是一種瀏覽與顯示的關(guān)系,而是實現(xiàn)了一種實時、動態(tài)、交互的頁面功能。
JavaScript通常也是以單獨的文件形式加載的,后綴為js,在HTML中通過script標(biāo)簽即可引入,例如:
<script src="jquery-2.1.0.js"></script>
綜上所述,HTML定義了網(wǎng)頁的內(nèi)容和結(jié)構(gòu),CSS描述了網(wǎng)頁的布局,JavaScript定義了網(wǎng)頁的行為。
2. 網(wǎng)頁的結(jié)構(gòu)
我們首先用例子來感受一下HTML的基本結(jié)構(gòu)。新建一個文本文件,名稱可以自取,后綴為html,內(nèi)容如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>This is a Demo</title>
</head>
<body>
<div id="container">
<div class="wrapper">
<h2 class="title">Hello World</h2>
<p class="text">Hello, this is a paragraph.</p>
</div>
</div>
</body>
</html>
這就是一個最簡單的HTML實例。開頭用DOCTYPE定義了文檔類型,其次最外層是html標(biāo)簽,最后還有對應(yīng)的結(jié)束標(biāo)簽來表示閉合,其內(nèi)部是head標(biāo)簽和body標(biāo)簽,分別代表網(wǎng)頁頭和網(wǎng)頁體,它們也需要結(jié)束標(biāo)簽。head標(biāo)簽內(nèi)定義了一些頁面的配置和引用,如:
<meta charset="UTF-8">
它指定了網(wǎng)頁的編碼為UTF-8。
title標(biāo)簽則定義了網(wǎng)頁的標(biāo)題,會顯示在網(wǎng)頁的選項卡中,不會顯示在正文中。body標(biāo)簽內(nèi)則是在網(wǎng)頁正文中顯示的內(nèi)容。div標(biāo)簽定義了網(wǎng)頁中的區(qū)塊,它的id是container,這是一個非常常用的屬性,且id的內(nèi)容在網(wǎng)頁中是唯一的,我們可以通過它來獲取這個區(qū)塊。然后在此區(qū)塊內(nèi)又有一個div標(biāo)簽,它的class為wrapper,這也是一個非常常用的屬性,經(jīng)常與CSS配合使用來設(shè)定樣式。然后此區(qū)塊內(nèi)部又有一個h2標(biāo)簽,這代表一個二級標(biāo)題。另外,還有一個p標(biāo)簽,這代表一個段落。在這兩者中直接寫入相應(yīng)的內(nèi)容即可在網(wǎng)頁中呈現(xiàn)出來,它們也有各自的class屬性。
將代碼保存后,在瀏覽器中打開該文件,可以看到如圖2-10所示的內(nèi)容。

圖2-10 運行結(jié)果
可以看到,在選項卡上顯示了This is a Demo字樣,這是我們在head中的title里定義的文字。而網(wǎng)頁正文是body標(biāo)簽內(nèi)部定義的各個元素生成的,可以看到這里顯示了二級標(biāo)題和段落。
這個實例便是網(wǎng)頁的一般結(jié)構(gòu)。一個網(wǎng)頁的標(biāo)準(zhǔn)形式是html標(biāo)簽內(nèi)嵌套head和body標(biāo)簽,head內(nèi)定義網(wǎng)頁的配置和引用,body內(nèi)定義網(wǎng)頁的正文。
3. 節(jié)點樹及節(jié)點間的關(guān)系
在HTML中,所有標(biāo)簽定義的內(nèi)容都是節(jié)點,它們構(gòu)成了一個HTML DOM樹。
我們先看下什么是DOM,DOM是W3C(萬維網(wǎng)聯(lián)盟)的標(biāo)準(zhǔn),其英文全稱Document Object Model,即文檔對象模型。它定義了訪問HTML和XML文檔的標(biāo)準(zhǔn):
W3C文檔對象模型(DOM)是中立于平臺和語言的接口,它允許程序和腳本動態(tài)地訪問和更新文檔的內(nèi)容、結(jié)構(gòu)和樣式。
W3C DOM標(biāo)準(zhǔn)被分為3個不同的部分。
- 核心DOM: 針對任何結(jié)構(gòu)化文檔的標(biāo)準(zhǔn)模型。
- XML DOM:針對XML文檔的標(biāo)準(zhǔn)模型。
- HTML DOM:針對HTML文檔的標(biāo)準(zhǔn)模型。
根據(jù)W3C的HTML DOM標(biāo)準(zhǔn),HTML文檔中的所有內(nèi)容都是節(jié)點。
- 整個文檔是一個文檔節(jié)點;
- 每個HTML元素是元素節(jié)點;
- HTML元素內(nèi)的文本是文本節(jié)點;
- 每個HTML屬性是屬性節(jié)點;
- 注釋是注釋節(jié)點。
HTML DOM將HTML文檔視作樹結(jié)構(gòu),這種結(jié)構(gòu)被稱為節(jié)點樹,如圖2-11所示。

圖2-11 節(jié)點樹
通過HTML DOM,樹中的所有節(jié)點均可通過JavaScript訪問,所有HTML節(jié)點元素均可被修改,也可以被創(chuàng)建或刪除。
節(jié)點樹中的節(jié)點彼此擁有層級關(guān)系。我們常用父(parent)、子(child)和兄弟(sibling)等術(shù)語描述這些關(guān)系。父節(jié)點擁有子節(jié)點,同級的子節(jié)點被稱為兄弟節(jié)點。
在節(jié)點樹中,頂端節(jié)點稱為根(root)。除了根節(jié)點之外,每個節(jié)點都有父節(jié)點,同時可擁有任意數(shù)量的子節(jié)點或兄弟節(jié)點。圖2-12展示了節(jié)點樹以及節(jié)點之間的關(guān)系。

圖2-12 節(jié)點樹及節(jié)點間的關(guān)系
本段參考W3SCHOOL,鏈接:http://www.w3school.com.cn/htmldom/dom_nodes.asp。
4. 選擇器
我們知道網(wǎng)頁由一個個節(jié)點組成,CSS選擇器會根據(jù)不同的節(jié)點設(shè)置不同的樣式規(guī)則,那么怎樣來定位節(jié)點呢?
在CSS中,我們使用CSS選擇器來定位節(jié)點。例如,上例中div節(jié)點的id為container,那么就可以表示為#container,其中#開頭代表選擇id,其后緊跟id的名稱。另外,如果我們想選擇class為wrapper的節(jié)點,便可以使用.wrapper,這里以點(.)開頭代表選擇class,其后緊跟class的名稱。另外,還有一種選擇方式,那就是根據(jù)標(biāo)簽名篩選,例如想選擇二級標(biāo)題,直接用h2即可。這是最常用的3種表示,分別是根據(jù)id、class、標(biāo)簽名篩選,請牢記它們的寫法。
另外,CSS選擇器還支持嵌套選擇,各個選擇器之間加上空格分隔開便可以代表嵌套關(guān)系,如#container .wrapper p則代表先選擇id為container的節(jié)點,然后選中其內(nèi)部的class為wrapper的節(jié)點,然后再進一步選中其內(nèi)部的p節(jié)點。另外,如果不加空格,則代表并列關(guān)系,如div#container .wrapper p.text代表先選擇id為container的div節(jié)點,然后選中其內(nèi)部的class為wrapper的節(jié)點,再進一步選中其內(nèi)部的class為text的p節(jié)點。這就是CSS選擇器,其篩選功能還是非常強大的。
另外,CSS選擇器還有一些其他語法規(guī)則,具體如表2-4所示。




另外,還有一種比較常用的選擇器是XPath,這種選擇方式后面會詳細(xì)介紹。
本節(jié)介紹了網(wǎng)頁的基本結(jié)構(gòu)和節(jié)點間的關(guān)系,了解了這些內(nèi)容,我們才有更加清晰的思路去解析和提取網(wǎng)頁內(nèi)容。