2017-01-25 121 views
1

我正在寫一個帶有Node的網頁抓取工具,並且正在考慮使用像Cheerio或JSDom這樣的模塊來將HTML解析爲DOM中的一組URL。但是,我有一個必要的特定功能。如何通過NodeJS中的值獲取元素的CSS選擇器?

我的目標是建立一個刮刀可颳去網站上的多個類似頁的信息,一些關鍵件。但是,我有一些包含這些信息的示例數據,我想使用它們爲這些頁面動態構建模型,然後使用該模型刮擦剩餘的網站。

爲了澄清,如果有一個網站三個頁面,每個包含一個不同的產品:

第1頁:

<html> 
<body> 
<h1>Product 1</h1> 
<p>Desc</p> 
<small>$2.05</small> 
</body> 
</html> 

第2頁:

<html> 
<body> 
<h1>Product 2</h1> 
<p>Desc</p> 
<small>$8.05</small> 
</body> 
</html> 

第3頁:

<html> 
<body> 
<h1>Product 3</h1> 
<p>Desc</p> 
<small>$5.07</small> 
</body> 
</html> 

薩我已經有了第一個產品的數據(我知道產品名稱,說明和價格)。我想要使​​用第一頁獲取每個元素的選擇器,然後使用這些選擇器從其他頁面中抓取數據。

鑑於DOM中的標籤的內容,我怎麼能得到該元素的CSS選擇器?例如:

<html> 
    <body> 
    <h1>Hello world</h1> 
    </body> 
</html> 

我如何提供Cheerio/JSDom包含「Hello World」的字符串,並將它在該元素所在的DOM返回CSS選擇器?

是否有一個簡單的方法來做到這一點(包括使用另一個框架),或者是唯一的方式,通過整個DOM對象只是循環,並逐個檢查每個元素的值是多少?

+0

將會有多個不同的XPath返回相同的節點列表。你想要哪一個?我假設'// * [text()='Hello world']'不是你想要的? – OrangeDog

+0

你想知道什麼?正如你可以像XPath一樣簡單的// * [。 =「Hello world」]' – skAstro

+0

我想要的是找到包含「hello world」元素的元素/路徑,以便稍後可以使用該路徑提取其他信息。基本上,我使用種子數據自動構建我的scraping模型。 –

回答

0

這是最簡單,最有效的與SAX模型來完成,而是可以應用到DOM遍歷來代替。

var match, path = []; 

parser.on('start', function(tag) { currentPath.push(tag); }); 
parser.on('end', function(tag) { currentPath.pop(); }); 

parser.on('text', function(text) { 
    if (!match && text === 'Hello world') { 
    match = path.join('/'); 
    } 
}); 

如果需要無論如何構建DOM,你可以使用XPath來查找節點(在內部只是循環整個DOM),然後循環了父母。

var path = []; 
var node = document.xpath('//*[.="Hello world"]')[0]; 

do { 
    path.push(node.tag); 
} while (node = node.parent); 

var match = path.reverse().join('/'); 

第二種方法是一個很大的效率不高,特別是如果你有很多不同的節點找到。 SAX方法可以一次覆蓋所有這些方法,但可能會根據解析器的實現而與格式錯誤的輸入進行鬥爭。

對於CSS選擇器,以取代' > ''/'

+0

在你的第一個建議中,解析器對象是什麼?你能提供一個更全面的檢查你的代碼的作用嗎? –

+0

這是一個SAX解析器。推測某種'Stream'可以通過管道響應,或者一個'EventEmitter',你可以讓DOM運行。 – OrangeDog

+0

我只是修改我的問題,而不是問問CSS選擇器。您的SAX解決方案是否仍然適用? –

相關問題