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 国产韩国在线,鲁鲁视频www一区二区,日韩中文字幕一区二区不卡

          整合營(yíng)銷(xiāo)服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          使用CefSharp和Javascript實(shí)現(xiàn)網(wǎng)絡(luò)爬

          使用CefSharp和Javascript實(shí)現(xiàn)網(wǎng)絡(luò)爬蟲(chóng)—DOM操作

          ello,親愛(ài)的小伙伴們,歡迎瀏覽“使用CefSharp和Javascript實(shí)現(xiàn)網(wǎng)絡(luò)爬蟲(chóng)”。

          本篇是第2篇,介紹在實(shí)現(xiàn)爬蟲(chóng)過(guò)程中會(huì)用到的Javascript和C#主要知識(shí)點(diǎn)。在使用CefSharp和Javascript實(shí)現(xiàn)網(wǎng)絡(luò)爬蟲(chóng)過(guò)程中,我使用到的C#和Javascript知識(shí)主要包括三個(gè)方面:一是Javascript的Dom操作;二是CefSharp中Javascript和C#之間的調(diào)用和交互;三是C#委托使用,用于接收到數(shù)據(jù)后的回調(diào)處理。

          網(wǎng)絡(luò)爬蟲(chóng)采用Javascript的DOM操作來(lái)抓取目標(biāo)數(shù)據(jù),并通過(guò)CefSharp提供的Javascript和C#交互方法,把目標(biāo)數(shù)據(jù)傳遞給C#代碼進(jìn)行處理。下面我將分別進(jìn)行記錄,分享給感興趣的小伙伴。

          一、Javascript原生DOM操作

          HTML通過(guò)瀏覽器解析后形成DOM樹(shù),DOM中每個(gè) HTML標(biāo)簽都是一個(gè)節(jié)點(diǎn)元素,包括屬性、方法、子孫節(jié)點(diǎn)。Javascript有一套操作HTML的DOM編程接口,通過(guò)DOM編程接口能夠操作到每個(gè)節(jié)點(diǎn)元素(即HTML標(biāo)簽),支持增、刪、改、查操作。

          1、查找獲取節(jié)點(diǎn)

          查找獲取HTML節(jié)點(diǎn)元素,可能通過(guò)document的get方法,或者使用document 的querySelector()和querySelectorAll()方法實(shí)現(xiàn)。

          方法1:通過(guò)document的get方法

          var elem=document.getElementById(idName) ;//通過(guò)id號(hào)獲取元素,返回一個(gè)元素對(duì)象
          var elem=document.getElementsByClassName(className) ;//通過(guò)class獲取元素,返回元素?cái)?shù)組
          var elem document.getElementsByTagName(tagName);//通過(guò)標(biāo)簽名獲取元素,返回元素?cái)?shù)組

          以上方法可以串聯(lián)使用,例如:

          // 先定位ID為idName的節(jié)點(diǎn),再返回其內(nèi)部所有名稱為tagName的節(jié)點(diǎn):

          var elem=document.getElementById(idName).getElementsByTagName(tagName);

          // 先定位ID為idName的節(jié)點(diǎn),再返回其內(nèi)部所有class包含className的節(jié)點(diǎn):

          var elem=document.getElementById(idName).getElementsByClassName(className);

          方法二:使用document 的querySelector()和querySelectorAll()方法

          var elem=document.querySelector('# idName ');// 通過(guò)querySelector獲取id為idName的節(jié)點(diǎn)
          var elem=document.querySelectorAll('div');// 通過(guò)querySelectorAll獲取所有的div節(jié)點(diǎn)

          2、獲取/設(shè)置元素的屬性值

          通過(guò)document的get方法,或者使用document 的querySelector()和querySelectorAll()方法,得到節(jié)點(diǎn)對(duì)象后,可進(jìn)一步可獲取節(jié)點(diǎn)的屬性值。

          elem.parentNode;//獲取當(dāng)前元素的父節(jié)點(diǎn)
          elem.chlidren;//獲取當(dāng)前元素子節(jié)點(diǎn)
          elem.chilidNodes;//獲取當(dāng)前元素子節(jié)點(diǎn)
          elem.firstChild;//獲取當(dāng)前元素的第1個(gè)子節(jié)點(diǎn)
          elem.lastChild;//獲取當(dāng)前元素的最后1個(gè)子節(jié)點(diǎn)
          elem.innerHTML?? //獲取元素的內(nèi)部文本
          elem.innerText; //獲取當(dāng)前元素的內(nèi)部文本值,只是文本內(nèi)容,不包括html代碼

          此外,通過(guò)getAttribute、setAttribute可以實(shí)現(xiàn)對(duì)屬性值的獲取或設(shè)置。

          elem.getAttribute(attributeName);//傳入屬性名稱,獲取對(duì)應(yīng)屬性的屬性值
          elem.setAttribute(attributeName,attributeValue); //傳入屬性名稱,以及屬性值

          二、jQuery操作HTML的DOM

          對(duì)于支持jQuery的站點(diǎn),可以直接使用jQuery方便地進(jìn)行DOM操作。

          jQuery對(duì)Javascript的DOM操作方法進(jìn)行了封裝,通過(guò)jQuery 選擇器能夠?qū)?HTML 節(jié)點(diǎn)元素或節(jié)點(diǎn)元素組進(jìn)行操作。jQuery 選擇器通過(guò)節(jié)點(diǎn)的 ID、類(lèi)、類(lèi)型、屬性、屬性值等查找/選擇HTML 節(jié)點(diǎn)元素,jQuery 選擇器以$符號(hào)開(kāi)頭。

          1、查找獲取節(jié)點(diǎn)

          (1)元素選擇器

          使用節(jié)點(diǎn)名選取元素,例如在頁(yè)面中選取所有 <div> 元素:$('div')

          (2)#id選擇器

          使用 HTML 元素的 ID屬性選取指定的元素,例如在頁(yè)面中選取id='myid'的 <div id='myid'> 元素:$('#myid')

          (3).class 選擇器

          使用 class 查找元素,例如在頁(yè)面中選取class='myclass'的 <div class='myclass'>元素:$(".myclass")

          2、獲取/設(shè)置元素的屬性值:

          通過(guò)attr() 、html()、val()方法設(shè)置或返回被選元素的屬性值:

          $(selector).attr(attribute); //獲取被選元素的屬性值
          $(selector).attr(attribute,value);//設(shè)置被選元素的屬性和值
          $(selector).html();//獲取或設(shè)置被選元素的內(nèi)容 (innerHTML)
          $(selector).val();//獲取或設(shè)置被選元素的值

          三、DOM操作實(shí)踐

          使用Chrome瀏覽器,打開(kāi)以下網(wǎng)址:

          https://www.toutiao.com/c/user/3601650358695789/#mid=1652236062202883

          (1)按“F12”打開(kāi) “開(kāi)發(fā)者工具”窗口,在“Elements”面板可以看到頁(yè)面的DOM結(jié)構(gòu)。

          (2)點(diǎn)擊左上角"箭頭"圖標(biāo),在頁(yè)面中選擇文章標(biāo)題,在“開(kāi)發(fā)者工具”中可以看到被選中元素高亮顯示。

          (3)在“開(kāi)發(fā)者工具”中“右鍵”點(diǎn)擊高亮顯示內(nèi)容,在彈出菜單中選擇Copy。

          (4)選擇“Copy selector”

          (5)點(diǎn)擊開(kāi)發(fā)者工具的“Console”選項(xiàng),在窗口中進(jìn)行如下輸入:

          a) 輸入"//" ,然后鍵盤(pán)按下"Ctrl"+"V" 粘貼上述操作獲取的HTML元素選擇字符串,或者在輸入行“點(diǎn)擊右鍵”,選擇“粘貼(P)”,粘貼上述操作獲取的HTML元素選擇字符串,字符串為:

          #wrapper > div.left > div:nth-child(2) > div > div:nth-child(3) > div > ul > li > div > div.normal.rbox > div > div.title-box > a

          b) 輸入 var elem=$("XXX"),其中XXX是"Ctrl"+"V" 粘貼的字符串

          c) 輸入 elem回車(chē),即可獲得我們選中的文章標(biāo)題元素

          d) 輸入 elem.href ,即可獲得文章標(biāo)題的URL鏈接地址

          e) 輸入 elem.innerText,即可獲得文章標(biāo)題字符串。

          這樣我們就獲得了文章標(biāo)題和對(duì)應(yīng)的URL地址,后面通過(guò)CefSharp中Javascript和C#之間的調(diào)用和交互方法,可將標(biāo)題和對(duì)應(yīng)的URL地址傳遞給C#進(jìn)行處理存儲(chǔ)、打開(kāi)鏈接獲取文章詳細(xì)內(nèi)容等。本篇介紹了Javascript的DOM操作,后面我將對(duì)C#委托使用、CefSharp中Javascript和C#之間的調(diào)用和交互進(jìn)行介紹,敬請(qǐng)指正。

          象語(yǔ)法樹(shù)(Abstract Syntax Trees),簡(jiǎn)稱AST,如果您正在編寫(xiě)代碼,那么 AST 很可能已經(jīng)參與了您的開(kāi)發(fā)流程。它們?yōu)槟拈_(kāi)發(fā)流程的許多部分提供動(dòng)力。 有些人可能在編譯器的上下文中聽(tīng)說(shuō)過(guò)它們,但它們被用于各種工具中。 即使您不編寫(xiě)通用開(kāi)發(fā)工具,AST 也可能是您工具帶中的有用工具。 在這篇文章中,我們將討論什么是 AST,它們?cè)谀睦锸褂靡约叭绾卫盟鼈儭?/p>

          什么是AST

          抽象語(yǔ)法樹(shù)或 AST 是代碼的樹(shù)型數(shù)據(jù)結(jié)構(gòu)表示。 它們是編譯器工作方式的基本部分。 當(dāng)編譯器轉(zhuǎn)換某些代碼時(shí),基本上有以下步驟:

          1. 詞法分析
          2. 語(yǔ)法分析
          3. 代碼生成

          詞法分析又名標(biāo)記化

          在此步驟中,您編寫(xiě)的代碼將被轉(zhuǎn)換為一組描述代碼不同部分的標(biāo)記。 這與基本語(yǔ)法突出顯示使用的方法基本相同。 這些標(biāo)記令牌不了解事物如何組合在一起,并且僅關(guān)注文件的組件。

          你可以想象這就像你將一個(gè)文本分解成單詞。 您可能能夠區(qū)分標(biāo)點(diǎn)符號(hào)、動(dòng)詞、名詞、數(shù)字等,但在這個(gè)階段,您對(duì)句子的組成部分或句子如何組合沒(méi)有任何更深入的了解。

          語(yǔ)法分析又名解析

          這是我們將標(biāo)記列表轉(zhuǎn)換為抽象語(yǔ)法樹(shù)的步驟。 它將我們的標(biāo)記轉(zhuǎn)換為表示代碼實(shí)際結(jié)構(gòu)的樹(shù)。 以前在標(biāo)記中我們只有一對(duì) (),現(xiàn)在我們知道它是函數(shù)調(diào)用、函數(shù)定義、分組還是其他東西。

          這里的等價(jià)物是將我們的單詞列表轉(zhuǎn)換為表示諸如句子之類(lèi)的數(shù)據(jù)結(jié)構(gòu),某個(gè)名詞在句子中扮演什么角色,或者我們是否在列表中。

          另一個(gè)可以與之比較的例子是 DOM。 上一步只是將 HTML 分解為“標(biāo)簽”和“文本”,而這一步將生成表示為 DOM 樹(shù)的層次結(jié)構(gòu)。

          需要注意的一件事是沒(méi)有“單一”的 AST 格式。 它們可能會(huì)有所不同,這取決于您要轉(zhuǎn)換為 AST 的語(yǔ)言以及您用于解析的工具。 在 JavaScript 中,一個(gè)通用標(biāo)準(zhǔn)是 ESTree,但您會(huì)看到不同的工具可能會(huì)添加不同的屬性。

          一般來(lái)說(shuō),AST 是一種樹(shù)結(jié)構(gòu),其中每個(gè)節(jié)點(diǎn)至少有一個(gè)類(lèi)型來(lái)指定它所代表的內(nèi)容。

          代碼生成

          此步驟本身可以是多個(gè)步驟。 一旦我們有了抽象語(yǔ)法樹(shù),我們就可以操作它,也可以將它“打印”到不同類(lèi)型的代碼中。 使用 AST 操作代碼比直接在代碼上作為文本或標(biāo)記列表執(zhí)行這些操作更安全。

          操縱文本總是很危險(xiǎn)的; 它顯示最少的上下文。 如果您曾經(jīng)嘗試使用字符串替換或正則表達(dá)式來(lái)操作文本,您可能會(huì)注意到很容易出錯(cuò)。而且不容易調(diào)試。

          甚至操縱令牌也不容易。 雖然我們可能知道變量是什么,但如果我們想重命名它,我們將無(wú)法深入了解變量的范圍或可能與之沖突的任何變量。

          AST 提供了有關(guān)代碼結(jié)構(gòu)的足夠信息,我們可以更有信心地對(duì)其進(jìn)行修改。 例如,我們可以確定變量的聲明位置,并確切地知道由于樹(shù)結(jié)構(gòu)而影響程序的哪個(gè)部分。

          一旦我們操縱了樹(shù),我們就可以打印樹(shù)以輸出任何預(yù)期的代碼輸出。 例如,如果我們要構(gòu)建一個(gè)像 TypeScript 編譯器這樣的編譯器,我們會(huì)輸出 JavaScript,而另一個(gè)編譯器可能會(huì)輸出機(jī)器代碼。

          同樣,使用 AST 更容易實(shí)現(xiàn)這一點(diǎn),因?yàn)橄嗤Y(jié)構(gòu)的不同輸出可能具有不同的格式。 使用更線性的輸入(如文本或標(biāo)記列表)生成輸出會(huì)相當(dāng)困難。

          如何處理 AST?

          理論涵蓋了哪些實(shí)際生活中的 AST 用例? 我們討論了編譯器,但我們并不是整天都在構(gòu)建編譯器。

          AST 的用例很廣泛,通常可以分為三個(gè)總體操作:讀取、修改和打印。 它們是一種添加劑,這意味著如果您正在打印 AST,那么您以前也閱讀過(guò) AST 并對(duì)其進(jìn)行修改的可能性很高。 但我們將介紹每個(gè)主要關(guān)注一個(gè)用例的示例。

          讀取/遍歷 AST

          從技術(shù)上講,使用 AST 的第一步是解析文本以創(chuàng)建 AST,但在大多數(shù)情況下,提供解析步驟的庫(kù)也提供了一種遍歷 AST 的方法。遍歷 AST 意味著訪問(wèn)樹(shù)的不同節(jié)點(diǎn)以獲取細(xì)節(jié)或執(zhí)行操作。

          最常見(jiàn)的用例之一是 linting。 例如,ESLint 使用 espree 生成 AST,如果您想編寫(xiě)任何自定義規(guī)則,您將根據(jù)不同的 AST 節(jié)點(diǎn)編寫(xiě)這些規(guī)則。 ESLint 文檔有大量關(guān)于如何構(gòu)建自定義規(guī)則、插件和格式化程序的文檔。

          修改/轉(zhuǎn)換 AST

          如前所述,與將代碼修改為標(biāo)記或原始字符串相比,擁有 AST 使修改所述樹(shù)更容易、更安全。您可能想要使用 AST 修改某些代碼的原因有很多種。

          例如,Babel 修改 AST 以向下編譯新功能或?qū)?JSX 轉(zhuǎn)換為函數(shù)調(diào)用。例如,當(dāng)您編譯 React 或 Preact 代碼時(shí)會(huì)發(fā)生這種情況。

          另一個(gè)用例是捆綁代碼。在模塊的世界中,捆綁代碼通常比將文件附加在一起要復(fù)雜得多。更好地了解各個(gè)文件的結(jié)構(gòu)可以更輕松地合并這些文件并在必要時(shí)調(diào)整導(dǎo)入和函數(shù)調(diào)用。如果您查看 webpack、parcel 或 rollup 等工具的代碼庫(kù),您會(huì)發(fā)現(xiàn)它們都使用 AST 作為其捆綁工作流程的一部分。

          打印 AST

          在大多數(shù)情況下,打印和修改 AST 是齊頭并進(jìn)的,因?yàn)槟仨気敵鰟倓傂薷牡?AST。 但是,雖然像 recast 這樣的一些庫(kù)明確專(zhuān)注于以與原始代碼樣式相同的代碼樣式打印 AST,但也有各種用例,您希望以不同的方式顯式打印您的 AST。

          例如,Prettier 使用 AST 根據(jù)您的配置重新格式化您的代碼,而無(wú)需更改代碼的內(nèi)容/含義。 他們這樣做的方式是將您的代碼轉(zhuǎn)換為完全與格式無(wú)關(guān)的 AST,然后根據(jù)您的規(guī)則重寫(xiě)它。

          其他常見(jiàn)的用例是用不同的目標(biāo)語(yǔ)言打印代碼或構(gòu)建自己的縮小工具。

          您可以使用幾種不同的工具來(lái)打印 AST,例如 escodegen 或 astring。 您還可以根據(jù)您的用例構(gòu)建自己的格式化程序,或者為 Prettier 構(gòu)建一個(gè)插件。

          最后:

          雖然 AST 可能是大多數(shù)開(kāi)發(fā)人員每天都不會(huì)使用的東西,但我相信了解它對(duì)今后的工作會(huì)有幫助。感謝閱讀。

          瀏覽器訪問(wèn)網(wǎng)站時(shí),頁(yè)面各不相同,你有沒(méi)有想過(guò)它為何會(huì)呈現(xiàn)這個(gè)樣子呢?本節(jié)中,我們就來(lái)了解一下網(wǎng)頁(yè)的基本組成、結(jié)構(gòu)和節(jié)點(diǎn)等內(nèi)容。

          網(wǎng)頁(yè)的組成

          網(wǎng)頁(yè)可以分為三大部分——HTML、CSS和JavaScript。如果把網(wǎng)頁(yè)比作一個(gè)人的話,HTML相當(dāng)于骨架,JavaScript相當(dāng)于肌肉,CSS相當(dāng)于皮膚,三者結(jié)合起來(lái)才能形成一個(gè)完善的網(wǎng)頁(yè)。下面我們分別來(lái)介紹一下這三部分的功能。

          1. HTML

          HTML是用來(lái)描述網(wǎng)頁(yè)的一種語(yǔ)言,其全稱叫作Hyper Text Markup Language,即超文本標(biāo)記語(yǔ)言。網(wǎng)頁(yè)包括文字、按鈕、圖片和視頻等各種復(fù)雜的元素,其基礎(chǔ)架構(gòu)就是HTML。不同類(lèi)型的文字通過(guò)不同類(lèi)型的標(biāo)簽來(lái)表示,如圖片用img標(biāo)簽表示,視頻用video標(biāo)簽表示,段落用p標(biāo)簽表示,它們之間的布局又常通過(guò)布局標(biāo)簽div嵌套組合而成,各種標(biāo)簽通過(guò)不同的排列和嵌套才形成了網(wǎng)頁(yè)的框架。

          在Chrome瀏覽器中打開(kāi)百度,右擊并選擇“檢查”項(xiàng)(或按F12鍵),打開(kāi)開(kāi)發(fā)者模式,這時(shí)在Elements選項(xiàng)卡中即可看到網(wǎng)頁(yè)的源代碼,如圖2-9所示。

          圖2-9 源代碼

          這就是HTML,整個(gè)網(wǎng)頁(yè)就是由各種標(biāo)簽嵌套組合而成的。這些標(biāo)簽定義的節(jié)點(diǎn)元素相互嵌套和組合形成了復(fù)雜的層次關(guān)系,就形成了網(wǎng)頁(yè)的架構(gòu)。

          2.CSS

          HTML定義了網(wǎng)頁(yè)的結(jié)構(gòu),但是只有HTML頁(yè)面的布局并不美觀,可能只是簡(jiǎn)單的節(jié)點(diǎn)元素的排列,為了讓網(wǎng)頁(yè)看起來(lái)更好看一些,這里借助了CSS。

          CSS,全稱叫作Cascading Style Sheets,即層疊樣式表。“層疊”是指當(dāng)在HTML中引用了數(shù)個(gè)樣式文件,并且樣式發(fā)生沖突時(shí),瀏覽器能依據(jù)層疊順序處理。“樣式”指網(wǎng)頁(yè)中文字大小、顏色、元素間距、排列等格式。

          CSS是目前唯一的網(wǎng)頁(yè)頁(yè)面排版樣式標(biāo)準(zhǔn),有了它的幫助,頁(yè)面才會(huì)變得更為美觀。

          圖2-9的右側(cè)即為CSS

          就是一個(gè)CSS樣式。大括號(hào)前面是一個(gè)CSS選擇器,此選擇器的意思是首先選中id為head_wrapper且class為s-ps-islite的節(jié)點(diǎn),然后再選中其內(nèi)部的class為s-p-top的節(jié)點(diǎn)。大括號(hào)內(nèi)部寫(xiě)的就是一條條樣式規(guī)則,例如position指定了這個(gè)元素的布局方式為絕對(duì)布局,bottom指定元素的下邊距為40像素,width指定了寬度為100%占滿父元素,height則指定了元素的高度。也就是說(shuō),我們將位置、寬度、高度等樣式配置統(tǒng)一寫(xiě)成這樣的形式,然后用大括號(hào)括起來(lái),接著在開(kāi)頭再加上CSS選擇器,這就代表這個(gè)樣式對(duì)CSS選擇器選中的元素生效,元素就會(huì)根據(jù)此樣式來(lái)展示了。

          在網(wǎng)頁(yè)中,一般會(huì)統(tǒng)一定義整個(gè)網(wǎng)頁(yè)的樣式規(guī)則,并寫(xiě)入CSS文件中(其后綴為css)。在HTML中,只需要用link標(biāo)簽即可引入寫(xiě)好的CSS文件,這樣整個(gè)頁(yè)面就會(huì)變得美觀、優(yōu)雅。

          3. JavaScript

          JavaScript,簡(jiǎn)稱JS,是一種腳本語(yǔ)言。HTML和CSS配合使用,提供給用戶的只是一種靜態(tài)信息,缺乏交互性。我們?cè)诰W(wǎng)頁(yè)里可能會(huì)看到一些交互和動(dòng)畫(huà)效果,如下載進(jìn)度條、提示框、輪播圖等,這通常就是JavaScript的功勞。它的出現(xiàn)使得用戶與信息之間不只是一種瀏覽與顯示的關(guān)系,而是實(shí)現(xiàn)了一種實(shí)時(shí)、動(dòng)態(tài)、交互的頁(yè)面功能。

          JavaScript通常也是以單獨(dú)的文件形式加載的,后綴為js,在HTML中通過(guò)script標(biāo)簽即可引入,例如:

          <script src="jquery-2.1.0.js"></script>

          綜上所述,HTML定義了網(wǎng)頁(yè)的內(nèi)容和結(jié)構(gòu),CSS描述了網(wǎng)頁(yè)的布局,JavaScript定義了網(wǎng)頁(yè)的行為。

          網(wǎng)頁(yè)的結(jié)構(gòu)

          我們首先用例子來(lái)感受一下HTML的基本結(jié)構(gòu)。新建一個(gè)文本文件,名稱可以自取,后綴為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>

          這就是一個(gè)最簡(jiǎn)單的HTML實(shí)例。開(kāi)頭用DOCTYPE定義了文檔類(lèi)型,其次最外層是html標(biāo)簽,最后還有對(duì)應(yīng)的結(jié)束標(biāo)簽來(lái)表示閉合,其內(nèi)部是head標(biāo)簽和body標(biāo)簽,分別代表網(wǎng)頁(yè)頭和網(wǎng)頁(yè)體,它們也需要結(jié)束標(biāo)簽。head標(biāo)簽內(nèi)定義了一些頁(yè)面的配置和引用,如:

          <meta charset="UTF-8">

          它指定了網(wǎng)頁(yè)的編碼為UTF-8。

          title標(biāo)簽則定義了網(wǎng)頁(yè)的標(biāo)題,會(huì)顯示在網(wǎng)頁(yè)的選項(xiàng)卡中,不會(huì)顯示在正文中。body標(biāo)簽內(nèi)則是在網(wǎng)頁(yè)正文中顯示的內(nèi)容。div標(biāo)簽定義了網(wǎng)頁(yè)中的區(qū)塊,它的id是container,這是一個(gè)非常常用的屬性,且id的內(nèi)容在網(wǎng)頁(yè)中是唯一的,我們可以通過(guò)它來(lái)獲取這個(gè)區(qū)塊。然后在此區(qū)塊內(nèi)又有一個(gè)div標(biāo)簽,它的class為wrapper,這也是一個(gè)非常常用的屬性,經(jīng)常與CSS配合使用來(lái)設(shè)定樣式。然后此區(qū)塊內(nèi)部又有一個(gè)h2標(biāo)簽,這代表一個(gè)二級(jí)標(biāo)題。另外,還有一個(gè)p標(biāo)簽,這代表一個(gè)段落。在這兩者中直接寫(xiě)入相應(yīng)的內(nèi)容即可在網(wǎng)頁(yè)中呈現(xiàn)出來(lái),它們也有各自的class屬性。

          將代碼保存后,在瀏覽器中打開(kāi)該文件,可以看到如圖2-10所示的內(nèi)容。

          圖2-10 運(yùn)行結(jié)果

          可以看到,在選項(xiàng)卡上顯示了This is a Demo字樣,這是我們?cè)趆ead中的title里定義的文字。而網(wǎng)頁(yè)正文是body標(biāo)簽內(nèi)部定義的各個(gè)元素生成的,可以看到這里顯示了二級(jí)標(biāo)題和段落。

          這個(gè)實(shí)例便是網(wǎng)頁(yè)的一般結(jié)構(gòu)。一個(gè)網(wǎng)頁(yè)的標(biāo)準(zhǔn)形式是html標(biāo)簽內(nèi)嵌套head和body標(biāo)簽,head內(nèi)定義網(wǎng)頁(yè)的配置和引用,body內(nèi)定義網(wǎng)頁(yè)的正文。

          節(jié)點(diǎn)樹(shù)及節(jié)點(diǎn)間的關(guān)系

          在HTML中,所有標(biāo)簽定義的內(nèi)容都是節(jié)點(diǎn),它們構(gòu)成了一個(gè)HTML DOM樹(shù)。

          我們先看下什么是DOM,DOM是W3C(萬(wàn)維網(wǎng)聯(lián)盟)的標(biāo)準(zhǔn),其英文全稱Document Object Model,即文檔對(duì)象模型。它定義了訪問(wèn)HTML和XML文檔的標(biāo)準(zhǔn):

          W3C文檔對(duì)象模型(DOM)是中立于平臺(tái)和語(yǔ)言的接口,它允許程序和腳本動(dòng)態(tài)地訪問(wèn)和更新文檔的內(nèi)容、結(jié)構(gòu)和樣式。

          W3C DOM標(biāo)準(zhǔn)被分為3個(gè)不同的部分。

          l 核心DOM: 針對(duì)任何結(jié)構(gòu)化文檔的標(biāo)準(zhǔn)模型。

          l XML DOM:針對(duì)XML文檔的標(biāo)準(zhǔn)模型。

          l HTML DOM:針對(duì)HTML文檔的標(biāo)準(zhǔn)模型。

          根據(jù)W3C的HTML DOM標(biāo)準(zhǔn),HTML文檔中的所有內(nèi)容都是節(jié)點(diǎn)。

          l 整個(gè)文檔是一個(gè)文檔節(jié)點(diǎn);

          l 每個(gè)HTML元素是元素節(jié)點(diǎn);

          l HTML元素內(nèi)的文本是文本節(jié)點(diǎn);

          l 每個(gè)HTML屬性是屬性節(jié)點(diǎn);

          注釋是注釋節(jié)點(diǎn)。

          HTML DOM將HTML文檔視作樹(shù)結(jié)構(gòu),這種結(jié)構(gòu)被稱為節(jié)點(diǎn)樹(shù),如圖2-11所示。

          圖2-11 節(jié)點(diǎn)樹(shù)

          通過(guò)HTML DOM,樹(shù)中的所有節(jié)點(diǎn)均可通過(guò)JavaScript訪問(wèn),所有HTML節(jié)點(diǎn)元素均可被修改,也可以被創(chuàng)建或刪除。

          節(jié)點(diǎn)樹(shù)中的節(jié)點(diǎn)彼此擁有層級(jí)關(guān)系。我們常用父(parent)、子(child)和兄弟(sibling)等術(shù)語(yǔ)描述這些關(guān)系。父節(jié)點(diǎn)擁有子節(jié)點(diǎn),同級(jí)的子節(jié)點(diǎn)被稱為兄弟節(jié)點(diǎn)。

          在節(jié)點(diǎn)樹(shù)中,頂端節(jié)點(diǎn)稱為根(root)。除了根節(jié)點(diǎn)之外,每個(gè)節(jié)點(diǎn)都有父節(jié)點(diǎn),同時(shí)可擁有任意數(shù)量的子節(jié)點(diǎn)或兄弟節(jié)點(diǎn)。圖2-12展示了節(jié)點(diǎn)樹(shù)以及節(jié)點(diǎn)之間的關(guān)系。

          圖2-12 節(jié)點(diǎn)樹(shù)及節(jié)點(diǎn)間的關(guān)系

          本段參考W3SCHOOL,鏈接:http://www.w3school.com.cn/htmldom/dom_nodes.asp。

          選擇器

          我們知道網(wǎng)頁(yè)由一個(gè)個(gè)節(jié)點(diǎn)組成,CSS選擇器會(huì)根據(jù)不同的節(jié)點(diǎn)設(shè)置不同的樣式規(guī)則,那么怎樣來(lái)定位節(jié)點(diǎn)呢?

          在CSS中,我們使用CSS選擇器來(lái)定位節(jié)點(diǎn)。例如,上例中div節(jié)點(diǎn)的id為container,那么就可以表示為#container,其中#開(kāi)頭代表選擇id,其后緊跟id的名稱。另外,如果我們想選擇class為wrapper的節(jié)點(diǎn),便可以使用.wrapper,這里以點(diǎn)(.)開(kāi)頭代表選擇class,其后緊跟class的名稱。另外,還有一種選擇方式,那就是根據(jù)標(biāo)簽名篩選,例如想選擇二級(jí)標(biāo)題,直接用h2即可。這是最常用的3種表示,分別是根據(jù)id、class、標(biāo)簽名篩選,請(qǐng)牢記它們的寫(xiě)法。

          另外,CSS選擇器還支持嵌套選擇,各個(gè)選擇器之間加上空格分隔開(kāi)便可以代表嵌套關(guān)系,如#container .wrapper p則代表先選擇id為container的節(jié)點(diǎn),然后選中其內(nèi)部的class為wrapper的節(jié)點(diǎn),然后再進(jìn)一步選中其內(nèi)部的p節(jié)點(diǎn)。另外,如果不加空格,則代表并列關(guān)系,如div#container .wrapper p.text代表先選擇id為container的div節(jié)點(diǎn),然后選中其內(nèi)部的class為wrapper的節(jié)點(diǎn),再進(jìn)一步選中其內(nèi)部的class為text的p節(jié)點(diǎn)。這就是CSS選擇器,其篩選功能還是非常強(qiáng)大的。

          另外,CSS選擇器還有一些其他語(yǔ)法規(guī)則,具體如表2-4所示。

          表2-4 CSS選擇器的其他語(yǔ)法規(guī)則

          另外,還有一種比較常用的選擇器是XPath,這種選擇方式后面會(huì)詳細(xì)介紹。

          本節(jié)介紹了網(wǎng)頁(yè)的基本結(jié)構(gòu)和節(jié)點(diǎn)間的關(guān)系,了解了這些內(nèi)容,我們才有更加清晰的思路去解析和提取網(wǎng)頁(yè)內(nèi)容。


          主站蜘蛛池模板: 亚洲AV无码一区二区三区国产| 国产成人AV一区二区三区无码| 天堂Aⅴ无码一区二区三区| 日韩精品无码一区二区三区 | 91一区二区在线观看精品| 日本免费一区尤物| 精品欧洲AV无码一区二区男男| 亚洲一区二区三区影院 | 在线精品日韩一区二区三区| 99精品一区二区三区| 精品国产日产一区二区三区| 综合久久一区二区三区 | 国产高清一区二区三区四区| 在线观看视频一区二区| 无码国产精品一区二区免费式直播 | 在线播放国产一区二区三区| 久久国产免费一区| 国产麻豆精品一区二区三区v视界| 亚洲高清成人一区二区三区| 国产伦精品一区二区| 日韩一区二区三区视频久久| 国产三级一区二区三区| 国产福利一区二区| 国模大胆一区二区三区| 国产成人精品亚洲一区| 亚洲av成人一区二区三区在线观看| 无码人妻精品一区二区蜜桃AV| 一区二区三区在线免费观看视频 | 色偷偷久久一区二区三区| 国产激情无码一区二区app| 国产成人AV一区二区三区无码| 色窝窝无码一区二区三区成人网站| 亚洲一区二区三区无码国产| 中文乱码字幕高清一区二区| 国产乱人伦精品一区二区在线观看| 国产成人高清亚洲一区91| 国产精品被窝福利一区| 一区二区三区日韩| 日本精品高清一区二区2021| 色系一区二区三区四区五区| 国产成人精品久久一区二区三区av|