다음 HTML 코드에서
<div class="item">
<div class="thumb">
<a href="http://www.mp3crank.com/wolf-eyes/lower-demos-121866" rel="bookmark" lang="en" title="Wolf Eyes - Lower Demos album downloads">
<img width="100" height="100" alt="Mp3 downloads Wolf Eyes - Lower Demos" title="Free mp3 downloads Wolf Eyes - Lower Demos" src="http://www.mp3crank.com/cover-album/Wolf-Eyes-–-Lower-Demos.jpg" /></a>
</div>
<div class="release">
<h3>Wolf Eyes</h3>
<h4>
<a href="http://www.mp3crank.com/wolf-eyes/lower-demos-121866" title="Wolf Eyes - Lower Demos">Lower Demos</a>
</h4>
<script src="/ads/button.js"></script>
</div>
<div class="release-year">
<p>Year</p>
<span>2013</span>
</div>
<div class="genre">
<p>Genre</p>
<a href="http://www.mp3crank.com/genre/rock" rel="tag">Rock</a>
<a href="http://www.mp3crank.com/genre/pop" rel="tag">Pop</a>
</div>
</div>
다른 방법으로 구문을 분석하는 방법을 알고 있지만 HTMLAgilityPack
라이브러리를 사용하여이 Info를 검색하고 싶습니다.
Title : Wolf Eyes - Lower Demos Cover : http://www.mp3crank.com/cover-album/Wolf-Eyes-–-Lower-Demos.jpg Year : 2013 Genres: Rock, Pop URL : http://www.mp3crank.com/wolf-eyes/lower-demos-121866
다음은이 html 줄입니다.
Title : title="Wolf Eyes - Lower Demos"
Cover : src="http://www.mp3crank.com/cover-album/Wolf-Eyes-–-Lower-Demos.jpg"
Year : <span>2013</span>
Genre1: <a href="http://www.mp3crank.com/genre/rock" rel="tag">Rock</a>
Genre2: <a href="http://www.mp3crank.com/genre/pop" rel="tag">Pop</a>
URL : href="http://www.mp3crank.com/wolf-eyes/lower-demos-121866"
이것은 내가 뭘 하려는지,하지만 난 항상 하나의 노드를 선택하려고 할 때 예외를 object reference not set
가져, 미안하지만, 난 아주 초보자 HTML이 질문의 단계를 따라 노력했습니다 HtmlAgilityPack 기본 방법 제목과 링크를 얻으려면?
Public Class Form1
Private htmldoc As HtmlAgilityPack.HtmlDocument = New HtmlAgilityPack.HtmlDocument
Private htmlnodes As HtmlAgilityPack.HtmlNodeCollection = Nothing
Private Title As String = String.Empty
Private Cover As String = String.Empty
Private Genres As String() = {String.Empty}
Private Year As Integer = -0
Private URL as String = String.Empty
Private Sub Test() Handles MyBase.Shown
' Load the html document.
htmldoc.LoadHtml(IO.File.ReadAllText("C:\source.html"))
' Select the (10 items) nodes.
htmlnodes = htmldoc.DocumentNode.SelectNodes("//div[@class='item']")
' Loop trough the nodes.
For Each node As HtmlAgilityPack.HtmlNode In htmlnodes
Title = node.SelectSingleNode("//div[@class='release']").Attributes("title").Value
Cover = node.SelectSingleNode("//div[@class='thumb']").Attributes("src").Value
Year = CInt(node.SelectSingleNode("//div[@class='release-year']").Attributes("span").Value)
Genres = ¿select multiple nodes?
URL = node.SelectSingleNode("//div[@class='release']").Attributes("href").Value
Next
End Sub
End Class
당신이 발견 한 아이 노드의 속성에 접근하려고 시도한 당신의 실수.
node.SelectSingleNode("//div[@class='release']")
를 호출하면 올바른 div를 반환하지만 .Attributes
호출하면 내부 HTML 요소가 아닌 div
태그의 속성 만 반환됩니다.
하위 노드 (예 : //div[@class='release']/a
를 선택하는 XPATH 쿼리를 작성할 수 있습니다. XPATH에 대한 자세한 내용은 http://www.w3schools.com/xpath/xpath_syntax.asp 를 참조 하십시오 . XML에 대한 예제이지만, 대부분의 원칙은 HTML 문서에 적용되어야합니다.
또 다른 방법은 발견 한 노드에서 추가 XPATH 호출을 사용하는 것입니다. 이 방법을 사용하여 코드를 수정했습니다.
' Load the html document.
htmldoc.LoadHtml(IO.File.ReadAllText("C:\source.html"))
' Select the (10 items) nodes.
htmlnodes = htmldoc.DocumentNode.SelectNodes("//div[@class='item']")
' Loop through the nodes.
For Each node As HtmlAgilityPack.HtmlNode In htmlnodes
Dim releaseNode = node.SelectSingleNode(".//div[@class='release']")
'Assumes we find the node and it has a a-tag
Title = releaseNode.SelectSingleNode(".//a").Attributes("title").Value
URL = releaseNode.SelectSingleNode(".//a").Attributes("href").Value
Dim thumbNode = node.SelectSingleNode(".//div[@class='thumb']")
Cover = thumbNode.SelectSingleNode(".//img").Attributes("src").Value
Dim releaseYearNode = node.SelectSingleNode(".//div[@class='release-year']")
Year = CInt(releaseYearNode.SelectSingleNode(".//span").InnerText)
Dim genreNode = node.SelectSingleNode(".//div[@class='genre']")
Dim genreLinks = genreNode.SelectNodes(".//a")
Genres = (From n In genreLinks Select n.InnerText).ToArray()
Console.WriteLine("Title : {0}", Title)
Console.WriteLine("Cover : {0}", Cover)
Console.WriteLine("Year : {0}", Year)
Console.WriteLine("Genres: {0}", String.Join(",", Genres))
Console.WriteLine("URL : {0}", URL)
Next
이 코드에서는 문서가 올바르게 구성되었고 각 노드 / 요소 / 특성이 존재하고 올바른 것으로 가정합니다. 예를 들어 If someNode Is Nothing Then ....
과 같이 많은 오류 검사를 추가 할 수 있습니다 If someNode Is Nothing Then ....
편집 : 각 .SelectSingleNode 앞에 ".//"접두사를 사용하도록 약간 위의 코드를 수정했습니다 - 이것은 여러 "항목"노드가있는 경우 작동합니다. 그렇지 않으면 현재 문서가 아닌 첫 번째 일치 항목 을 선택합니다 마디.
짧은 XPATH 솔루션을 원한다면,이 접근 방식을 사용하는 코드는 다음과 같습니다.
' Load the html document.
htmldoc.LoadHtml(IO.File.ReadAllText("C:\source.html"))
' Select the (10 items) nodes.
htmlnodes = htmldoc.DocumentNode.SelectNodes("//div[@class='item']")
' Loop through the nodes.
For Each node As HtmlAgilityPack.HtmlNode In htmlnodes
Title = node.SelectSingleNode(".//div[@class='release']/h4/a[@title]").Attributes("title").Value
URL = node.SelectSingleNode(".//div[@class='release']/h4/a[@href]").Attributes("href").Value
Cover = node.SelectSingleNode(".//div[@class='thumb']/a/img[@src]").Attributes("src").Value
Year = CInt(node.SelectSingleNode(".//div[@class='release-year']/span").InnerText)
Dim genreLinks = node.SelectNodes(".//div[@class='genre']/a")
Genres = (From n In genreLinks Select n.InnerText).ToArray()
Console.WriteLine("Title : {0}", Title)
Console.WriteLine("Cover : {0}", Cover)
Console.WriteLine("Year : {0}", Year)
Console.WriteLine("Genres: {0}", String.Join(",", Genres))
Console.WriteLine("URL : {0}", URL)
Console.WriteLine()
Next
당신은 해결책에서 그다지 멀지 않았습니다. 두 가지 중요한 메모 :
//
은 재귀 호출입니다. 성능에 약간의 영향을 미칠 수 있으며 원하지 않는 노드를 선택할 수도 있으므로 계층 구조가 복잡하거나 복잡하거나 전체 경로를 지정하지 않으려는 경우에만 사용하는 것이 좋습니다. GetAttributeValue
라는 XmlNode
에는 유용한 도우미 메서드가 있습니다 (기본값을 지정해야 함). 다음은 작동하는 것으로 보이는 샘플입니다.
' select the base/parent DIV (here we use a discriminant CLASS attribute)
' all select calls below will use this DIV element as a starting point
Dim node As HtmlNode = htmldoc.DocumentNode.SelectNodes("//div[@class='item']")
' get to the A tag which is a child or grand child (//) of a 'release' DIV
Console.WriteLine(("Title :" & node.SelectSingleNode("div[@class='release']//a").GetAttributeValue("title", CStr(Nothing))))
' get to the IMG tag which is a child or grand child (//) of a 'thumb' DIV
Console.WriteLine(("Cover :" & node.SelectSingleNode("div[@class='thumb']//img").GetAttributeValue("src", CStr(Nothing))))
' get to the SPAN tag which is a child or grand child (//) of a 'release-year' DIV
Console.WriteLine(("Year :" & node.SelectSingleNode("div[@class='release-year']//span").InnerText))
' get all A elements which are child or grand child(//) of a 'genre' DIV
Dim nodes As HtmlNodeCollection = node.SelectNodes("div[@class='genre']//a")
Dim i As Integer
For i = 0 To nodes.Count - 1
Console.WriteLine(String.Concat(New Object() { "Genre", (i + 1), ":", nodes.Item(i).InnerText }))
Next i
' get to the A tag which is a child or grand child (//) of a 'release' DIV
Console.WriteLine(("Url :" & node.SelectSingleNode("div[@class='release']//a").GetAttributeValue("href", CStr(Nothing))))