Problem beim Parsen von HTML mit Powershell und Xpath

html html-agility-pack html-parsing powershell xpath

Frage

Dies ist eine Follow-up-Frage zu einer, die ich letzte Woche hier gepostet habe . Ich habe das ursprüngliche Problem hinter mir gelassen, aber jetzt stoße ich auf ein etwas anderes Problem.

Ich bin jetzt in der Lage, das Attribut eines Artikels zu bekommen, an dem ich interessiert bin, wenn die HTML-Tags nicht mit der GetAttributeValue-Methode verschachtelt sind, hier ist es die Daten-PID, aber ich habe jetzt Probleme beim Erfassen des Attributs eines Elements In verschachtelten Tags ist dies in meinem Code-Snippet das Datum. Ich verwende Xpath und das HtmlAgility-Paket, um den HTML-Code hier zu analysieren, aber im Beispiel unten wird das gleiche Datum immer wieder zurückgegeben.

So sieht das $ item- Objekt aus:

Attributes           : {class, data-pid}
ChildNodes           : {#text, a, #text, span...}
Closed               : True
ClosingAttributes    : {}
FirstChild           : HtmlAgilityPack.HtmlTextNode
HasAttributes        : True
HasChildNodes        : True
HasClosingAttributes : False
Id                   : 
InnerHtml            :  <a href="/mod/4175126893.html" class="i"><span class="price">$20</span></a> <span class="star"></span> <span class="pl"> <span class="date">Nov 
                       30</span>  <a href="/mod/4175126893.html">Unlock Any GSM Cell Phone Today!</a> </span> <span class="l2"> <span class="price">$20</span>  <span 
                       class="pnr"> <small> (Des Moines)</small> <span class="px"> <span class="p"> </span></span> </span>  <a class="gc" href="/mod/" 
                       data-cat="mod">cell phones - by dealer</a> </span> 
InnerText            :  $20   Nov 30  Unlock Any GSM Cell Phone Today!   $20    (Des Moines)      cell phones - by dealer  
LastChild            : HtmlAgilityPack.HtmlTextNode
Line                 : 305
LinePosition         : 5408
Name                 : p
NextSibling          : HtmlAgilityPack.HtmlTextNode
NodeType             : Element
OriginalName         : p
OuterHtml            : <p class="row" data-pid="4175126893"> <a href="/mod/4175126893.html" class="i"><span class="price">$20</span></a> <span class="star"></span> 
                       <span class="pl"> <span class="date">Nov 30</span>  <a href="/mod/4175126893.html">Unlock Any GSM Cell Phone Today!</a> </span> <span class="l2"> 
                       <span class="price">$20</span>  <span class="pnr"> <small> (Des Moines)</small> <span class="px"> <span class="p"> </span></span> </span>  <a 
                       class="gc" href="/mod/" data-cat="mod">cell phones - by dealer</a> </span> </p>
OwnerDocument        : HtmlAgilityPack.HtmlDocument
ParentNode           : HtmlAgilityPack.HtmlNode
PreviousSibling      : HtmlAgilityPack.HtmlTextNode
StreamPosition       : 18733
XPath                : /html[1]/body[1]/article[1]/section[1]/div[1]/div[2]/p[11]

Attributes           : {class, data-pid}
ChildNodes           : {#text, a, #text, span...}
Closed               : True
ClosingAttributes    : {}

Ich möchte Daten aus dem äußeren HTML- Wert herausziehen .

OuterHtml            : <p class="row" data-latitude="41.5937565437255" data-longitude="-93.6437636649079" data-pid="4184719674"> <a href="/mod/4184719674.html" class="i"></a> 
               <span class="star"></span> <span class="pl"> <span class="date">Nov 27</span>  <a href="/mod/4184719674.html">iPhone and other Cell Phone Unlocks</a> 
               </span> <span class="l2">   <span class="pnr"> <small> (Des Moines)</small> <span class="px"> <span class="p"> <a href="#" class="maptag" 
               data-pid="4184719674">map</a></span></span> </span>  <a class="gc" href="/mod/" data-cat="mod">cell phones - by dealer</a> </span> </p>

Ich kann die Daten pid kein Problem greifen. So sieht der aktuelle Code aus:

ForEach ($item in $results) {

    # This is working
    $ID = $item.GetAttributeValue("data-pid", "")

    # This is looping over the same item
    $Date = $item.SelectSingleNode("//span[@class='date']").InnerText
}

Ich möchte Attribute aus den verschiedenen Tags, die im outerhtml-Objekt enthalten sind, mithilfe meiner xpath-Anweisungen abrufen, aber ich kann nicht herausfinden, wie das geht. Ist das der beste Weg, um das Problem zu lösen oder sollte ich nur ein paar Regex verwenden, um den gewünschten Wert zu erhalten?

Lassen Sie mich wissen, welche weiteren Details ich veröffentlichen muss.

Akzeptierte Antwort

Ich habe das HTML Agility Pack nicht verwendet, aber AFAICS integrierte Tools sollten trotzdem ausreichen:

$url = 'http://www.example.com/path/to/some.html'

$html = (Invoke-Webrequest $url).ParsedHTML

$html.getElementsByTagName('p') | ? { $_.className -eq 'row' } | % {
  $ID   = $_.getAttributeNode('data-pid').value
  $Date = $_.getElementsByTagName('span') | ? { $_.className -eq 'date' } |
          % { $_.innerText }

  # do stuff with $ID and $Date
  "{0}: {1}" -f $ID, $Date
}

Beachten Sie, dass Invoke-Webrequest PowerShell v3 erfordert. Verwenden Sie das Internet Explorer-COM-Objekt, wenn Sie auf PowerShell v2 beschränkt sind:

$ie = New-Object -COM InternetExplorer.Application
$ie.Navigate($url)
while ($ie.ReadyState -ne 4) { sleep 100 }
$html = $ie.Document

Wenn Ihre HTML-Datei eine lokale Datei ist, ersetzen Sie die Invoke-Webrequest Zeile durch Invoke-Webrequest :

$htmlfile = 'C:\path\to\some.html'

$html = New-Object -COM HTMLFile
$html.write((Get-Content $htmlfile | Out-String))

Beliebte Antwort

Ich bin viel zu spät, aber hier ist dein Fehler. Sie haben absolute Pfade verwendet.

ForEach ($item in $results) {

    # This is working
    $ID = $item.GetAttributeValue("data-pid", "")

    # This is looping over the same item
    $Date = $item.SelectSingleNode("//span[@class='date']").InnerText

    # This is looping over the different items (i.e. this is what what you want)
    $Date = $item.SelectSingleNode(".//span[@class='date']").InnerText
}


Related

Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum