Benutzer mit den meisten Antworten
Outlook item.htmlbody in HTML object wandeln und tags suchen

Frage
-
Moin,
ich lese mit einem PS script eine Outlook Mailbox und PST aus und speichere unter anderem die msg Dateien auf Disk.
Diese msg Dateien öffne ich mit einen anderen script und nutze .CreateitemFromTemplate um ein Outlook Objekt zu erstellen.
Nun habe ich Zugriff auf .body und .htmlbody.
Aus dem Mail Body möchte ich all URLs extrahieren.
Das mache ich aktuell mit regex. Klappt auch ganz gut soweit, aber einige Links werden nicht korrekt erfasst.
Deshalb möchte ich den htmlbody in ein HTML object wandeln und dann mit .getElementsByTagName(‘a’) auf die Links zugreifen.
Versucht habe ich das mit new-object -COM HTMLFile aber es klappt nicht.Kann mit jemand sagen, wie ich aus einem string mit HTML Daten ein HTML Objekt erstellen kann auf das ich dann alle HMTL Methoden anwenden kann?
Danke und Gruß
Michael- Bearbeitet deroppi Freitag, 12. Dezember 2014 13:23 korrigiert
Antworten
-
Vielen Dank Peter!
Nachdem ich recht viel gesucht und probiert habe, ist mir eine einfachere Lösung gelungen.
Von dem HtmlAgilityPack hatte ich gelesen, wollte es aber nicht einsetzen.
So wie unten gezeigt funktioniert es in PS v4 und ist ziemlich mächtig.Mein Regex Lösung zur Linksuche muss ich auch noch nutzen, da ja nicht alle Emails als HTML kommen.
Also suche ich nun zuerst im htmlbody und wenn der leer ist, dann such ich im Text.Suche Links und Bilder in einem HTML String:
$htmlDoc= New-Object -com "HTMLFILE" $page = @' <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Test Dokument</title> </head> <body> <p>Hallo Welt!</p> <p><a href="HTTP://www.Microsoft.de">Ich bin Link! </a></p> <p><a href="http://www.PowerShell-Group.eu">Noch Linker!</a></p> <p><img src="http://www.powershell-group.eu/wp-content/uploads/2013/10/Logo-Gross2.png"> <p> <a href="http://google .de">Ich bin ein kaputter Link, wenn als Text geparsed< /a > </body> </html> '@ $htmlDoc.IHTMLDocument2_write($page) write-host Links $htmlDoc.IHTMLDocument2_links | select -expandproperty "href" write-host Images $htmlDoc.IHTMLDocument2_images | select -expandproperty "src" [void]$htmlDoc.close
Der Vollständigkeit halber hier noch die Suche im Text mit Filter für bestimmte Endungen.
Den regex Ausdruck habe ich aus dem Internet, es gibt viele Ansätze, dieser hier lief bei mir am Besten, mit Ausnahme von Links die in mehrere Zeilen aufgebrochen waren.
# extracting URLs from text $ExtFilter = "", "txt","jpg", "jpeg","gif","png","bmp","bin", "wmv" ,"dtd" $text= @' Das ist ein Text in dem eine Link enthalten ist. Um ganz viel Geld zu bekommen klicken sie hier: https://www.google.de/?gws_rd=ssl#q=ganz+viel+Geld !!! Klicken sie sofort und ohne zu denken. '@ $regex="(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?" $URLs=[regex]::matches($Text, $regex, [system.Text.RegularExpressions.RegexOptions]::Singleline) Foreach ($URL in $URLs) { $split=[string]$URL $split=$split.split(".") if (($ExtFilter -notcontains $split[-1]) -and (@($split).length -gt 1)) { write-host $URL } }
Ich bin neu bei PS, also seht mir bitte irgendwelche grauenhaften Konstrukte nach.
- Bearbeitet deroppi Freitag, 12. Dezember 2014 16:32
- Als Antwort vorgeschlagen Peter Kriegel Samstag, 13. Dezember 2014 11:15
- Als Antwort markiert deroppi Samstag, 13. Dezember 2014 12:05
Alle Antworten
-
Hallo Michael!
Bei XML haben wir gute .NET Klassen die einen String (Text) in ein XML Document Object Model (DOM) umwandeln.
Für HTML gibt es da nix fertig eingebautes vom Microsoft, das mir bekannt ist.
Dafür musst du dir das HTML Agility Pack von Codeplex herunterladen und in der PowerShell nutzen:http://htmlagilitypack.codeplex.com/
Lee Holmes vom Microsoft PowerShell Team hat darüber einen Artikel geschrieben:
http://www.leeholmes.com/blog/2010/03/05/html-agility-pack-rocks-your-screen-scraping-world/
Um aus einem String ein HTML DOM zu machen könnte der Code wie folgt aussehen:
# In PowerShell 2.0 und früher müssen wir die .NET 2.0 Version der DLL laden # Ab der PowerShell 3.0 müssen wir die .NET 4.0 oder 4.5 Version der DLL laden If($PSVersionTable.CLRVersion.Major -lt 4) { Add-Type -Path 'C:\Pfad\zur\DLL\HtmlAgilityPack.1.4.6\Net20\HtmlAgilityPack.dll' } Else { Add-Type -Path 'C:\Pfad\zur\DLL\HtmlAgilityPack.1.4.6\Net40\HtmlAgilityPack.dll' } # HTML Text $HtmLText = @' <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Test Dokument</title> </head> <body> <p>Hallo Welt!</p> <p><a href="HTTP://www.Microsoft.de">Ich bin Link! </a></p> <p><a href="http://www.PowerShell-Group.eu">Noch Linker!</a></p> </body> </html> '@ # Leeres HtmlDocument erstellen $HtmlDoc = New-Object HtmlAgilityPack.HtmlDocument # Text in das HTML Document laden $HtmlDoc.LoadHtml($HtmLText) # Mit der XPath abfragesprache alle <A> Link Tags suchen und einzeln verarbeiten foreach($HtmlLinkNode in $HtmlDoc.DocumentNode.SelectNodes('//a[@href]')) { # leere Variable für das HReft Attribut $Href = '' # in den Attributen des <A> Tags das HRef Attribut suchen ForEach($Attribute in $HtmlLinkNode.Attributes) { IF($Attribute.Name -eq 'HRef') { # HRef vom <A> Tag auslesen $Href = $Attribute.Value } } # neues Objekt erstellen, für die gemeinsame Ausgabe vomn Linktext und HRef New-Object PSObject -Property @{ LinkText = $HtmlLinkNode.InnerText LinkHRef = $Href }
PowerShell Artikel, Buchtipps und kostenlose PowerShell Tutorials + E-Books
auf der deutschsprachigen PowerShell Community
Mein 21 Teiliger PowerShell Video Grundlehrgang
Deutsche PowerShell Videos auf Youtube
Folge mir auf:
Twitter | Facebook | Google+- Bearbeitet Peter Kriegel Freitag, 12. Dezember 2014 13:28
-
Vielen Dank Peter!
Nachdem ich recht viel gesucht und probiert habe, ist mir eine einfachere Lösung gelungen.
Von dem HtmlAgilityPack hatte ich gelesen, wollte es aber nicht einsetzen.
So wie unten gezeigt funktioniert es in PS v4 und ist ziemlich mächtig.Mein Regex Lösung zur Linksuche muss ich auch noch nutzen, da ja nicht alle Emails als HTML kommen.
Also suche ich nun zuerst im htmlbody und wenn der leer ist, dann such ich im Text.Suche Links und Bilder in einem HTML String:
$htmlDoc= New-Object -com "HTMLFILE" $page = @' <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Test Dokument</title> </head> <body> <p>Hallo Welt!</p> <p><a href="HTTP://www.Microsoft.de">Ich bin Link! </a></p> <p><a href="http://www.PowerShell-Group.eu">Noch Linker!</a></p> <p><img src="http://www.powershell-group.eu/wp-content/uploads/2013/10/Logo-Gross2.png"> <p> <a href="http://google .de">Ich bin ein kaputter Link, wenn als Text geparsed< /a > </body> </html> '@ $htmlDoc.IHTMLDocument2_write($page) write-host Links $htmlDoc.IHTMLDocument2_links | select -expandproperty "href" write-host Images $htmlDoc.IHTMLDocument2_images | select -expandproperty "src" [void]$htmlDoc.close
Der Vollständigkeit halber hier noch die Suche im Text mit Filter für bestimmte Endungen.
Den regex Ausdruck habe ich aus dem Internet, es gibt viele Ansätze, dieser hier lief bei mir am Besten, mit Ausnahme von Links die in mehrere Zeilen aufgebrochen waren.
# extracting URLs from text $ExtFilter = "", "txt","jpg", "jpeg","gif","png","bmp","bin", "wmv" ,"dtd" $text= @' Das ist ein Text in dem eine Link enthalten ist. Um ganz viel Geld zu bekommen klicken sie hier: https://www.google.de/?gws_rd=ssl#q=ganz+viel+Geld !!! Klicken sie sofort und ohne zu denken. '@ $regex="(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?" $URLs=[regex]::matches($Text, $regex, [system.Text.RegularExpressions.RegexOptions]::Singleline) Foreach ($URL in $URLs) { $split=[string]$URL $split=$split.split(".") if (($ExtFilter -notcontains $split[-1]) -and (@($split).length -gt 1)) { write-host $URL } }
Ich bin neu bei PS, also seht mir bitte irgendwelche grauenhaften Konstrukte nach.
- Bearbeitet deroppi Freitag, 12. Dezember 2014 16:32
- Als Antwort vorgeschlagen Peter Kriegel Samstag, 13. Dezember 2014 11:15
- Als Antwort markiert deroppi Samstag, 13. Dezember 2014 12:05
-
Hallo Michael!
Coole Lösung mit dem COM Object! Danke!
Man könnte auch den HTML Text auf der Festplatte temporär (im TEMP Verzeichnis) als .htm abspeichernden und in einen unsichtbaren internet Explorer laden. Dieser wird dann auch über COM angesteuert, dann hatt man auch das DOM.
PowerShell Artikel, Buchtipps und kostenlose PowerShell Tutorials + E-Books
auf der deutschsprachigen PowerShell Community
Mein 21 Teiliger PowerShell Video Grundlehrgang
Deutsche PowerShell Videos auf Youtube
Folge mir auf:
Twitter | Facebook | Google+ -