2013-04-05 36 views
5

đây là lần đầu tiên tôi cố gắng lấy giá trị phần tử bằng HAP. Tôi nhận được một lỗi đối tượng null khi tôi cố gắng sử dụng InnerText.Gói Agility HTML - sử dụng XPath để nhận một nút đơn - Tham chiếu đối tượng không được đặt thành một thể hiện của đối tượng

URL tôi đang cạo là: - http://www.mypivots.com/dailynotes/symbol/659/-1/e-mini-sp500-june-2013 Tôi đang cố gắng lấy giá trị cho mức cao hiện tại từ Bảng tóm tắt thay đổi ngày.

Mã của tôi ở dưới cùng. Thứ nhất, tôi chỉ muốn biết nếu tôi đang đi về điều này đúng cách? Nếu vậy, thì đơn giản là giá trị XPath của tôi không chính xác?

giá trị XPath thu được bằng cách sử dụng một tiện ích mà tôi tìm thấy được gọi là trình trợ giúp htmlagility. Phiên bản firebug của XPath bên dưới, cũng cho cùng một lỗi: - /html/body/div [3]/div/table/tbody/tr [3]/td/table/tbody/tr [5]/td [ 3]

mã của tôi: -

WebClient myPivotsWC = new WebClient(); 
string nodeValue; 
string htmlCode = myPivotsWC.DownloadString("http://www.mypivots.com/dailynotes/symbol/659/-1/e-mini-sp500-june-2013"); 
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument(); 
doc.LoadHtml(htmlCode); 
HtmlNode node = doc.DocumentNode.SelectSingleNode("/html[1]/body[1]/div[3]/div[1]/table[1]/tbody[1]/tr[3]/td[1]/table[1]/tbody[1]/tr[5]/td[3]"); 
nodeValue=(node.InnerText); 

Cảm ơn, Will.

Trả lời

22

Bạn không thể dựa vào một công cụ developper như FireBug hoặc Chrome, v.v ... để xác định XPATH cho các nút bạn đang sử dụng, vì XPATH được cung cấp bởi các công cụ tương ứng với bộ nhớ HTML DOM trong khi Gói Agility Html chỉ biết về HTML thô được gửi lại bởi máy chủ.

Những gì bạn cần làm là xem trực quan những gì được gửi lại (hoặc chỉ cần thực hiện nguồn xem). Bạn sẽ thấy không có phần tử TBODY nào. Vì vậy, bạn muốn tìm bất kỳ điều gì phân biệt đối xử và sử dụng ví dụ XPATH axes. Ngoài ra, XPATH của bạn, ngay cả khi nó hoạt động, sẽ không có khả năng chống lại những thay đổi trong tài liệu, vì vậy bạn cần phải tìm một cái gì đó "ổn định" hơn cho việc cạo để có nhiều tương lai hơn.

Đây là một mã mà dường như làm việc:

HtmlNode node = doc.DocumentNode.SelectSingleNode("//td[@class='dnTableCell']//a[text()='High']/../../td[3]"); 

Đây là những gì nó làm:

  • tìm một yếu tố TD với một thuộc tính CLASS thiết lập để 'dnTableCell'. // token có nghĩa là tìm kiếm đệ quy trong phân cấp XML.
  • tìm phần tử A chứa văn bản (văn bản bên trong) bằng 'Cao'.
  • điều hướng hai cha mẹ lên (chúng tôi sẽ nhận được vào yếu tố TR gần nhất)
  • chọn phần tử TD thứ 3 từ đó
+0

Cảm ơn đống, hoạt động. Tôi sẽ nghiên cứu giải thích của bạn về XPath, tôi nghĩ rằng tôi sẽ có thể làm được điều này mà không thực sự học cách sử dụng XPath, nhưng rõ ràng tôi sẽ phải làm như vậy. – dontpanic

+0

@dontpanic: Tìm hiểu 'xpath', đặt câu hỏi về cách tinh chỉnh các truy vấn' xpath' của bạn, có rất nhiều câu hỏi & câu trả lời 'xpath' trên SO. – MattH

+0

@Simon: Vì vậy, tôi đang gặp vấn đề tương tự và tôi đã thử theo đề xuất của bạn và vẫn không có may mắn. Bạn có thể hiển thị ví dụ từ bất kỳ giá trị nào từ bảng bên dưới trong http://weather.deltixlab.com/ Tôi có văn bản sau: 'string day1 = doc.DocumentNode.SelectNodes (" // * [@ class = 'table-block'] /../../../ tr [1]/td [1] ") [0] .InnerText;' – goodfella

2

như Simon Mourier explaind, bạn lấy mã HTML thô được gửi bởi máy chủ . Phần tử bạn cần chưa được hiển thị nhưng bạn không thể truy xuất phần tử đó vì nó không tồn tại trong DOM. một công việc đơn giản xung quanh vấn đề này là sử dụng một trình kết xuất web để xây dựng DOM, hơn là bạn có thể lấy HTML và loại bỏ nó. Tôi sử dụng WatiN như sau:

WatiN.Core.Settings.MakeNewInstanceVisible = false; 
WatiN.Core.Settings.AutoMoveMousePointerToTopLeft = false; 
IE ie = new IE(); 
ie.GoTo(urlLink); 
ie.WaitForComplete(); 
string html = ie.Html; 
ie.close(); 
+0

Cảm ơn bạn, vì vậy về cơ bản tôi cần phải hiển thị trang hoàn toàn để lấy DOM bị thiếu. Bây giờ những gì lo lắng cho tôi là sự chậm trễ này sẽ gây ra. – goodfella

Các vấn đề liên quan