Html Agility Pack - 在表格中讀取div InnerText

c# html-agility-pack web-scraping

我的問題是我無法從表中獲取div InnerText。我已經成功地提取了不同類型的數據,但我不知道如何從表中讀取div。

在下面的圖片中我突出顯示了div,我需要從中獲取InnerText,在這種情況下 - 數字3。

點擊此處查看第一張照片

我正在嘗試使用以下路徑完成此操作:

"//div[@class='kal']//table//tr[2]/td[1]/div[@class='cipars']"

但我得到以下錯誤:

單擊此處查看錯誤消息圖片

假設其餘代碼寫得正確,有人能指出我正確的方向嗎?我一直在努力想出這個,但我無法得到任何結果。

一般承認的答案

所以你的問題是你依賴XPath中的位置。雖然在某些情況下這可能沒問題,但它不在這裡,因為你期望給定tr第一個 td與該類有一個div

查看Chrome中的來源,它表明並非總是這樣。您可以通過比較日曆中的“1”元素到“2”和“3”來看到這一點。您會注意到“1”元素周圍有許多元素,而其他元素則沒有。

您的原始XPath查詢不返回元素,這就是您收到錯誤的原因。如果你給HtmlAgilityPack提供的XPath查詢不會產生DOM元素,它將返回null。

現在,因為你沒有顯示整個代碼,我不知道這個代碼是如何運行的。但是,我猜你正試圖遍歷所有的日曆項目。無論如何,你有多種方法可以做到這一點,但我會告訴你,使用descendant XPath選擇器,你可以一次抓住整個批次:

//div[@class='kal']//table//descendant::div[@class='cipars']

這將返回所有日曆項(即1到30)。

但是,要獲取特定行中的所有項目,您可以將該tr到查詢中:

//div[@class='kal']//table//descendant::div[@class='cipars']

這將返回2到8(第二行日曆項)。

為了定位特定的一個,你必須對網站的源代碼做出假設。看起來每個“cipars” div都有一個帶有類datumstd的祖先....所以從你的問題中得到“3”值:

//div[@class='kal']//table//descendant::div[@class='cipars']

希望這足以至少顯示這個問題。

編輯

雖然您確實有XPath問題,但您還有另一個問題。

該網站創建非常奇怪。日曆以奇怪的方式加載。當我點擊該URL時,日曆是由一些Javascript調用XML Web服務(用PHP編寫)創建的,然後計算用於日曆的完整table

由於這是Javascript(客戶端代碼),HtmlAgilityPack將不會執行它。因此,HtmlAgilityPack甚至沒有“看到”該表。因此對它的查詢返回“未找到”(null)。

解決方法:1)使用一個可以調用腳本的工具。這個,我的意思是加載一個瀏覽器。一個很好的工具用於此,稱為Selenium 。這可能是更好的整體解決方案,因為這意味著實際上將調用站點使用的所有腳本。您仍然可以使用XPath,因此您的查詢不會更改。

第二種方法是將請求發送到該頁面相同的 Web服務。這基本上是為了獲取與頁面相同的 HTML,並將與HtmlAgilityPack一起使用。我們怎麼做?

好吧,您可以使用C#輕鬆地將數據發佈到Web服務。為了便於使用,我偷了這個SO問題的代碼。有了這個,我們可以發送頁面相同的請求,並返回相同的HTML。

所以為了發送一些POST數據,我們生成一個像這樣的方法.....

//div[@class='kal']//table//descendant::div[@class='cipars']

我們可以這樣稱呼它:

//div[@class='kal']//table//descendant::div[@class='cipars']

我怎麼得到這個?我們調用的php文件是頁面的Web服務,POST數據也是。我發現它發送給服務的數據的方式是調試Javascript(使用Chrome的開發者控制台), 您可能會注意到它與URL中的幾乎相同。這似乎是故意的。

responseBody返回的只是 物理HTML table日曆。

我們現在用它做什麼?我們將其加載到HtmlAgilityPack中,因為它能夠接受純HTML。

//div[@class='kal']//table//descendant::div[@class='cipars']

現在,我們堅持原來的XPath:

//div[@class='kal']//table//descendant::div[@class='cipars']

現在,我們打印出有希望成為“3”的內容:

//div[@class='kal']//table//descendant::div[@class='cipars']

我在本地運行它的輸出確實是: 3

但是,雖然這可以解決您遇到的問題,但我假設網站的其餘部分是這樣的。如果是這種情況,您仍然可以使用上面的技術解決它,但是像Selenium這樣的工具就是出於這個原因而創建的。




許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因