Webscraping mit Powershell - Eine Einführung

Webscraping mit Powershell

Eine Einführung

Tomaso Vasella
von Tomaso Vasella
am 11. Februar 2021
Lesezeit: 22 Minuten

Keypoints

So funktioniert Webscraping mit Powershell

  • Powershell bietet leistungsfähige Funktionen für HTTP Requests
  • zwischen verschiedenen Powershell-Versionen bestehen signifikante Unterschiede
  • die Request-Parameter lassen sich mit etwas Aufwand weitestgehend anpassen
  • Mit aktuellen Webbrowsern können die nützlichen XPath-Ausdrücke einfach erzeugt werden

Im weitesten Sinn bezeichnet der Begriff Webscraping das mehr oder weniger automatisierte extrahieren von Informationen aus Webseiten. Dies bedingt vereinfacht gesagt zwei Schritte: Erstens müssen die Daten vom Webserver möglichst spezifisch abgerufen werden. Und zweitens müssen diese Daten programmatisch interpretiert (parsed) werden, um anschliessend die gewünschten Informationen extrahieren oder weiter verarbeiten zu können.

Obwohl Websites inzwischen vermehrt APIs anbieten und auch Webapplikationen selbst zunehmend solche verwenden, sind die meisten Webseiten für den menschlichen Gebrauch formatiert. Technisch gesehen sind die Inhaltsdaten, also beispielsweise der Text eines Artikels, mit Steuerdaten, Metadaten, Formatierungsangaben, Bildern und weiteren Daten vermischt. Diese Daten sind zwar notwendig für die Funktionalität und die Darstellung einer Website; aus Sicht der Datenextraktion sind sie aber eher störend. Es braucht also geeignete Werkzeuge, um aus diesem Datengemisch die gewünschten Informationen herauszuschälen.

Gründe für solche Datenextraktionen gibt es viele. So kann man sich auf diese Art etwa selbst einen RSS-Feed aus dem Inhalt einer Website zusammenstellen oder es kann gewünscht sein, öffentlich zugängliche Informationen im Rahmen eines Red Team Engagements zu sammeln. Obwohl Webscraping nach etwas recht Einfachem klingt, kann sich das in der Praxis als erstaunlich mühsam erweisen. Powershell mag für diese Aufgabe vielleicht nicht unbedingt die erste Wahl sein, aber aufgrund seiner Verbreitung lohnt es sich, die entsprechenden Möglichkeiten zu kennen. Es kommt nicht selten vor, dass derartige Aufgaben in stark eingeschränkten Umgebungen durchgeführt werden müssen und Alternativen wie Python oder Perl nicht zur Verfügung stehen.

HTTP-Abfragen mit Powershell

Die nachfolgende Tabelle gibt eine Übersicht über die gebräuchlichsten Methoden, um mittels Powershell HTTP-Anfragen durchzuführen.

MethodeTechnologiePS VersionBemerkungen
Invoke-Webrequest Powershell cmdletAb Version 3Führt umfangreiches Parsing durch, welches jedoch ab Powershell Version 7 nicht mehr erfolgt, da in dieser Version das HTML DOM des Internet Explorers nicht mehr verfügbar ist.
System.Net.WebClient .NETAb Version 2Gemäss Microsoft: Es wird nicht empfohlen, die WebClient Klasse für die neue Entwicklung zu verwenden. Verwenden Sie stattdessen die System.Net.Http.HttpClient Klasse.
System.Net.HTTPWebrequest .NETAb Version 2Gemäss Microsoft: Es wird nicht empfohlen, die HTTPWebrequest Klasse für die neue Entwicklung zu verwenden. Verwenden Sie stattdessen die System.Net.Http.HttpClient Klasse.
System.Net.Http.HttpClient .NETAb Version 3 

Neben den beschriebenen Verfahren existieren noch diverse weitere Möglichkeiten, z.B. kann mittels Powershell auch ein Internet Explorer COM Automation Objekt instantiiert werden oder es können andere COM-Objekte wie Msxml2.XMLHTTP verwendet werden.

$ie = new-object -com "InternetExplorer.Application"
$ie.navigate('https://www.example.com')
$ie.document

Invoke-Webrequest

Dieses Cmdlet ist das wahrscheinlich am häufigsten angewendete Verfahren, um mit Powershell Daten von einer Website abzurufen:

$res = Invoke-WebRequest -Uri 'http://www.example.com'
$res = Invoke-WebRequest -Uri 'http://www.example.com' -Outfile index.html
$res = Invoke-WebRequest -Uri 'http://www.example.com' -Method POST -Body "postdata"

Im Unterschied zu den weiteren vorgestellten Methoden wird hier automatisch ein User-Agent-Header gesetzt. Es ist möglich, mit dem Parameter -UserAgent darauf Einfluss zu nehmen. Zusätzlich existiert der Parameter -Headers, welcher aber das Setzen gewisser Header wie User-Agent nicht zulässt. Die volle Kontrolle über die Header lässt sich nur durch die Verwendung der weiter unten beschriebenen .NET Klassen erreichen.

Sofern kein Fehler aufgetreten ist, wird ein Objekt des Typs Microsoft.PowerShell.Commands.HtmlWebResponseObject zurück geliefert. Je nach verwendeter Version von Powershell unterscheiden sich die Eigenschaften dieses Objekts: In Version 5 wird der vom Webserver gelieferte Inhalt parsed und steht unter dem Property .ParsedHtml zur Verfügung. Dieses Property fehlt unter Powershell 7.

Das automatische Parsing kann für schnelles Webscraping sehr nützlich sein, beispielsweise lassen sich mit einem simplen Aufruf alle Links einer Webseite extrahieren:

(Invoke-WebRequest -Uri 'https://www.example.com').Links.Href

Der gesamte Inhalt der gelieferten Seite befindet sich im Property .Content des Ergebnisobjekts; falls auch die Header gewünscht sind, stehen diese in der Eigenschaft .RawContent zur Verfügung.

Sollte ein Fehler auftreten, wird kein Objekt zurückgegeben. Man kann jedoch die in der Exception enthaltene Fehlermeldung auslesen:

try
{
    $res = Invoke-WebRequest -Uri 'http://getstatuscode.com/401'
}
catch [System.Net.WebException]
{
    $ex = $_.Exception
}
$msg = $ex.Message
$status = $ex.Response.StatusCode.value__

Handelt es sich um einen Fehler, bei dem der Webserver einen Inhalt geliefert hat, beispielsweise eine Webseite bei einem 401-Fehler, so kann man auf diesen Inhalt wie folgt über die Exception zugreifen (zur Illustration ist auch der Zugriff auf die Response Header gezeigt):

try
{
    $res = Invoke-WebRequest -Uri 'http://getstatuscode.com/401'
}
catch
{
    $rs = $_.Exception.Response.GetResponseStream()
    $reader = New-Object System.IO.StreamReader($rs)
    $content = $reader.ReadToEnd()

    foreach($header in $rs.Response.Headers.AllKeys)
    {
        write-host $('{0}: {1}' -f $header, $rs.Response.Headers[$header])
    }
}

Beim Abschicken mehrerer Requests, z.B. automatisiert in einem Loop, fällt auf, dass Invoke-Webrequest sehr langsam sein kann. Dies hängt einerseits mit dem standardmässig aktivierten umfangreichen parsing der Response zusammen, andererseits wird oft für jeden Request ein Fortschrittsbalken angezeigt.

Man kann mit folgenden Parametern bzw. Einstellungen beschleunigen:

Invoke-Webrequest folgt standardmässig automatisch bis zu 5 Umleitungen (Redirects). Dieses Verhalten lässt sich mit dem Parameter -MaximumRedirection steuern.

Proxy-Unterstützung

Invoke-Webrequest verwendet standardmässig den in den Windows-Einstellungen definierten Proxy. Dies kann mit dem Parameter -Proxy, der als Argument einen URI annimmt, übersteuert werden. Falls der Proxy eine Authentisierung verlangt, können die nötigen Credentials mit dem Parameter -ProxyCredential angegeben werden, wobei ein Argument vom Typ PSCredential erforderlich ist. Ein Beispiel würde etwa so aussehen:

$secPw = ConvertTo-SecureString '************' -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential -ArgumentList 'username', $secPw
$res = Invoke-WebRequest -Uri 'https://www.example.com' -Proxy 'http://127.0.0.1:8080' -ProxyCredential $creds

Alternativ dazu kann der Parameter -ProxyUseDefaultCredentials spezifiziert werden, wodurch die Credentials des aktuellen Benutzers verwendet werden.

Sessions und Cookies

Invoke-Webrequest unterstützt die Verwendung von Cookies und ermöglicht damit auch entsprechende Sessions durch Angabe des Parameters -SessionVariable. Die entsprechende Session kann anschliessend in nachfolgenden Requests mit dem Parameter -WebSession verwendet werden.

Invoke-WebRequest -SessionVariable -Uri 'https://www.google.com'
Invoke-WebRequest -WebSession $Session -Uri 'https://www.google.com'

Die Cookies stehen mit dem Property .Cookies zur Verfügung und es können auch selbst Cookies definiert werden. In diesem Beispiel wird auch das Session-Objekt vorgängig erstellt, was nützlich sein kann, um bereits vor dem ersten Request eigene Cookies zu setzen:

$cookie = New-Object System.Net.Cookie
$cookie.Name = "specialCookie"
$cookie.Value = "value"
$cookie.Domain = "domain"

$session = New-Object Microsoft.PowerShell.Commands.WebRequestSession
$session.Cookies.Add($cookie)
Invoke-WebRequest -WebSession $session -Uri 'https://www.example.com'

System.Net.WebClient

Der Zugriff auf Websites ist auch hiermit recht einfach, wie folgende Beispiele zeigen:

$wc = New-Object System.Net.WebClient
$res = $wc.DownloadString('https://www.example.com')

Im Unterschied zu Invoke-Webrequest werden hier keine Header automatisch gesetzt. Man kann diese aber selbst angeben, um beispielsweise den User-Agent festzulegen. Dies ist häufig ratsam, da sich Webseiten manchmal anders verhalten, wenn der User-Agent fehlt.

$wc.Headers.Add('UserAgent', 'Mozilla/5.0 (Windows NT; Windows NT 10.0; de-CH)')

Falls ein Fehler auftritt, so wird auch hier ein allfällig vom Werserver gelieferter Inhalt nicht im Ergebnisobjekt verfügbar gemacht. Um darauf zuzugreifen, kann man ein analoges Verfahren wie oben beschrieben anwenden, was allerdings mit Powershell 2 nicht funktioniert, da diese Version try-catch gar nicht unterstützt.

try
{
        $res = $wc.DownloadString('http://getstatuscode.com/401')
}
catch [System.Net.WebException] 
{
        $rs = $_.Exception.Response.GetResponseStream()
        $reader = New-Object System.IO.StreamReader($rs)
        $content = $reader.ReadToEnd()
}

Proxy-Unterstützung

Auch dieses Verfahren verwendet standardmässig den in den Windows-Einstellungen definierten Proxy, den sich mit [System.Net.WebProxy]::GetDefaultProxy() abrufen lässt. Man dies ebenfalls übersteuern:

$proxy = New-Object System.Net.WebProxy('http://127.0.0.1:8080')
$proxyCreds = New-Object Net.NetworkCredential('username', '************')

$wc = New-Object System.Net.WebClient
$wc.Proxy = $proxy
$wc.Proxy.Credentials = $proxyCreds

Oder alternativ, wenn man die Default-Credentials verwenden will:

$wc.UseDefaultCredentials = $true
$wc.Proxy.Credentials = $wc.Credentials

Sessions und Cookies

System.Net.WebClient stellt keine komfortablen Methoden für Cookies zur Verfügung. Somit muss man die entsprechenden Response-Header selbst auslesen und verarbeiten, was rasch ziemlich umständlich werden kann.

$cookie = $wc.ResponseHeaders["Set-Cookie"] 

System.Net.HTTPWebrequest

Auch dieses Verfahren ist relativ einfach umzusetzen und folgt den gleichen Prinzipien wie die bereits genannten.

$wr = [System.Net.HttpWebRequest]::Create('http://www.example.com')
try
{
    $res = $wr.GetResponse()
}
catch [System.Net.WebException]
{
    $ex = $_.Exception
}

$rs = $res.GetResponseStream()
$rsReader = New-Object System.IO.StreamReader $rs
$data = $rsReader.ReadToEnd()

Auch POST-Requests sind möglich:

$data = [byte[]][char[]]'postdatastring'
$wr = [System.Net.HttpWebRequest]::Create('http://ptsv2.com/t/g1eiu-1612179889/post')
$wr.Method = 'POST'
$requestStream = $wr.GetRequestStream()
$requestStream.Write($data, 0, $data.Length);

try
{
    $res = $wr.GetResponse()
}
catch [System.Net.WebException]
{
    $ex = $_.Exception
}

$rs = $res.GetResponseStream()
$rsReader = New-Object System.IO.StreamReader $rs
$data = $rsReader.ReadToEnd()

Sofern ein Fehler auftritt, befindet sich der allenfalls vom Server ausgegebene Inhalt ebenfalls nicht im Response-Objekt, sondern in der Exception und kann von dort ausgelesen werden. Dieses Verfahren setzt ebenfalls keine Header automatisch, man kann diese aber selbst angeben, um beispielsweise den User-Agent festzulegen:

$wr.Headers['UserAgent'] = 'Mozilla/5.0 (Windows NT; Windows NT 10.0; de-CH)'

Proxy-Unterstützung

Auch dieses Verfahren verwendet standardmässig den in den Windows Einstellungen definierten Proxy, welcher analog zum obigen Beispiel einfach übersteuert werden kann:

$proxy = New-Object System.Net.WebProxy('http://127.0.0.1:8080')
$wr.proxy = $proxy

Sessions und Cookies

Cookies lassen sich einfach verwenden, indem ein entsprechender Cookie-Container spezifiziert wird. Dies kann auch bereits vor dem Absenden des Requests mittels Get.Response() durchgeführt werden.

$cookieJar = New-Object System.Net.CookieContainer
$wr.CookieContainer = $cookieJar
$res = $wr.GetResponse()

System.Net.Http.HttpClient

Das .NET Framework bietet mit HttpClient noch eine weitere Klasse für Web-Requests, die über Add-Type eingebunden werden kann. Der nachfolgend gezeigte Ausschnitt gibt auch im Fehlerfall (z.B. 404) den vom Server gelieferten Inhalt zurück, sofern vorhanden.

Add-Type -AssemblyName System.Net.Http
$httpClient = New-Object System.Net.Http.HttpClient
try
{
    $task = $httpClient.GetAsync('http://www.example.com')
    $task.wait()
    $res = $task.Result

    if ($res.isFaulted)
    {
        write-host $('Error: Status {0}, reason {1}.' -f [int]$res.Status, $res.Exception.Message)
    }
    return $res.Content.ReadAsStringAsync().Result

}
catch [Exception]
{
    write-host ('Error: {0}' -f $_)
} finally {
    if($null -ne $res)
    {
        $res.Dispose()
    }
}

Wie in diesem Beispiel ersichtlich, wird GetAsync() asynchron ausgeführt, blockiert also nicht und kann daher parallelisiert werden. Will man allerdings den gelieferten Inhalt gleich weiterverarbeiten, so muss man wie oben dargestellt auf das Resultat warten.

Das Senden von Daten ist ebenfalls recht einfach zu bewerkstelligen, indem man PostAsync() verwendet:

$data = New-Object 'system.collections.generic.dictionary[string,string]'
$data.Add('param1', 'value1')
$data.Add('param2', 'value2')
$postData = new-object System.Net.Http.FormUrlEncodedContent($data)
$task = $httpClient.PostAsync('http://www.example.com', $PostData)
Auch hier werden keine Header automatisch gesetzt, man kann diese aber einfach festlegen:
$httpClient.DefaultRequestHeaders.add('User-Agent', $userAgent)

Proxy-Unterstützung

Auch dieses Verfahren verwendet standardmässig den in den Windows-Einstellungen definierten Proxy. Um diesen manuell zu setzen hat es sich als am zuverlässigsten erwiesen, einen eigenen ClientHandler zu verwenden und die entsprechenden Einstellungen dort vorzunehmen:

Add-Type -AssemblyName System.Net.Http
$httpHandler = New-Object System.Net.Http.HttpClientHandler
$cookieJar = New-Object System.Net.CookieContainer
$httpHandler.CookieContainer = $cookieJar
$proxy = New-Object System.Net.WebProxy('http://127.0.0.1:8080')
$httpHandler.Proxy = $proxy
$httpClient = new-object System.Net.Http.HttpClient($httpHandler)

Sessions und Cookies

An obigem Beispiel ist auch ersichtlich, wie sich Cookies und damit auch Cookie-basierte Sessions verwenden lassen, indem man dem HTTP-Handler einen Cookie-Container zuweist.

TLS und Deaktivieren der Zertifikatsprüfung

Falls man mit einem Webserver kommunizieren möchte, der ungültige oder als nicht vertrauenswürdig eingestufte Zertifikate verwendet, kann es nützlich sein, die entsprechende Zertifikatsprüfung zu deaktivieren. Mit dem Befehl Invoke-Webrequest ist dies ab Powershell Version 6 mit Hilfe des Parameters -SkipCertificateCheck einfach möglich. Ausserdem können mit dem Parameter -SslProtocol die zu verwendenden SSL/TLS-Versionen angegeben werden.

Mit tieferen Versionen von Powershell oder bei den anderen Methoden ist dies etwas mühsamer. Im Fall eines SSL/TLS-Zertifikatsfehlers wird intern ein Callback aufgerufen. Man kann die Zertifikatsprüfung durch einen eigenen Callback aushebeln, was durch das Hinzufügen von C#-Code mittels Add-Type möglich ist:

Add-Type @"
using System;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
public class IgnoreCertValidErr
{
    public static void Ignore()
    {
        ServicePointManager.ServerCertificateValidationCallback = 
            delegate
            (
                Object sender, 
                X509Certificate certificate, 
                X509Chain chain, 
                SslPolicyErrors sslPolicyErrors
            )
            {
                return true;
            };
    }
}
"@

[IgnoreCertValidErr]::Ignore()

Es ist auch hier möglich, die gewünschten SSL/TLS-Protokoll-Versionen anzugeben. Die entsprechende Aufzählung (enum) SecurityProtocolType enthält die möglichen Werte dafür.

[System.Net.ServicePointManager]::SecurityProtocol = 'tls12, tls11'

Mit diesem Vorgehen lässt sich die Zertifikatsprüfung bei allen genannten Methoden deaktivieren.

Datenanalyse und Extraktion

Invoke-Webrequest nimmt schon eine weitgehende Verarbeitung der abgerufenen Inhalte vor und stellt sie als Eigenschaften des Ergebnisobjekts zur Verfügung. Dies kann in einigen Fällen sehr hilfreich sein, weil sich mit wenigen Zeilen bereits nützliche Befehle ausführen lassen. Allerdings funktionieren diejenigen Methoden, die sich auf die Eigenschaft ParsedHtml verlassen, nur mit den Powershell-Versionen 3 bis 5. Nachfolgend ein paar Beispiele.

Alle Links auf einer Webseite auflisten:

(Invoke-WebRequest -Uri 'https://www.admin.ch').Links.Href | Sort-Object | Get-Unique

Alle Links zu Bildern auflisten:

(Invoke-WebRequest -Uri 'https://www.admin.ch').Images | Select-Object src

Informationen über Formulare und Eingabefelder extrahieren:

(Invoke-WebRequest 'http://www.google.com').Forms
bc. (Invoke-WebRequest 'http://www.google.com').InputFileds

Elemente anhand ihres Klassennamens extrahieren:

(Invoke-WebRequest -Uri 'https://www.meteoschweiz.admin.ch/home.html?tab=report').ParsedHtml.getElementsByClassName('textFCK') | %{Write-Host $_.innertext}

Weitere nützliche Methoden sind getElementById, getElementsByName und getElementsByTagName.

Es lassen sich auch einfache Abläufe damit automatisieren, beispielsweise das Ausfüllen und Senden eines Formulars:

$url = 'https://www.google.com'
$html = Invoke-WebRequest -Uri $url -SessionVariable 'Session' -UserAgent 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0'
$html.Forms[0].Fields['q'] = 'powershell'
$action = $html.Forms[0].Action
$method = $html.Forms[0].Method
$res = Invoke-WebRequest -Uri "$url$action" -Method $method -Body $html.Forms[0].Fields -UserAgent 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0' -WebSession $Session

Informationen kann man auch mit Powershell-Bordmitteln direkt aus dem abgerufenen Inhalt extrahieren. Dies ist allerdings nur für die allereinfachsten Fälle ratsam, denn HTML und XML mittels Mustererkennung zu verarbeiten ist fast immer zum Scheitern verurteilt.

$wc = New-Object System.Net.WebClient
($wc.DownloadString('http://www.myip.ch/') | Select-String -Pattern "\d{1,3}(\.\d{1,3}){3}" -AllMatches).Matches.Value

$wc = New-Object System.Net.WebClient
$res = $wc.DownloadString('https://wisdomquotes.com/dalai-lama-quotes-tenzin-gyatso/')
([regex]'<blockquote><p>(.*?)</p></blockquote>').Matches($res) | ForEach-Object { $_.Groups[1].Value }

Modul PowerHTML

Eine komfortablere Methode steht mit dem Powershell-Modul PowerHTML zur Verfügung. Dieses Modul ist eine Powershell-Implementation des HtmlAgilityPack, welches einen vollständigen HTML-Parser bereitstellt. Damit sind leistungsfähige Möglichkeiten vorhanden, beispielsweise die Verwendung des XPath-Syntax. Auch in Fällen, in denen das Internet Explorer HTML DOM nicht zur Verfügung steht, beispielweise bei Invoke-Webrequest unter Powershell 7, leistet es nützliche Dienste.

Beim Installieren von Powershell-Modulen über die Powershell-Gallery ist es ratsam, vor der Installation die Abhängigkeiten zu prüfen, um zu verstehen, welche zusätzlichen und eventuell nicht erwünschten Module auch noch installiert werden. PowerHTML erfordert erfreulicherweise keine Installation weiterer Module.

Die Installation kann z.B. wie folgt durchgeführt und in einem Skript zur Verwendung importiert werden:

function loadPowerHtml
{
    if (-not (Get-Module -ErrorAction Ignore -ListAvailable PowerHTML))
    {
        Write-Host "Installing PowerHTML module"
        Install-Module PowerHTML -Scope CurrentUser -ErrorAction Stop
    }

    Import-Module -ErrorAction Stop PowerHTML
}

Als Beispiel nachfolgend der Zugriff auf die Paragraph-Elemente der Seite www.example.com:

$wc = New-Object System.Net.WebClient
$res = $wc.DownloadString('http://www.example.com')
$html = ConvertFrom-Html -Content $res
$p = $html.SelectNodes('/html/body/div/p')

Alle gefundenen <p>-Elemente sind nun in $p enthalten und können entsprechend weiterverarbeitet werden:

NodeType Name AttributeCount ChildNodeCount ContentLength InnerText
-------- ---- -------------- -------------- ------------- ---------
Element  p    0              1              156           This domain is for...
Element  p    0              1              70            More information...

Den in einem Element enthaltenen Text ausgeben:

$p[0].innerText

Ein bestimmtes Element anhand seines Textinhalts finden:

($p | Where-Object { $_.innerText -match 'domain' }).innerText

Extraktion einer Tabelle anhand ihres Klassennamens:

$wc = New-Object System.Net.WebClient
$res = $wc.DownloadString('https://www.imdb.com/title/tt0057012/')
$html = ConvertFrom-Html -Content $res
$table = $html.SelectNodes('//table') | Where-Object { $_.HasClass('cast_list') }

$cnt = 0
foreach ($row in $table.SelectNodes('tr'))
{
    $cnt += 1
    # skip header row
    if ($cnt -eq 1) { continue }

    $a = $row.SelectSingleNode('td[2]').innerText.Trim() -replace "`n|`r|\s+", " "
    $c = $row.SelectSingleNode('td[4]').innerText.Trim() -replace "`n|`r|\s+", " "

    $row = New-Object -TypeName psobject
    $row | Add-Member -MemberType NoteProperty -Name Actor -Value $a
    $row | Add-Member -MemberType NoteProperty -Name Character -Value $c

     [array]$data += $row
}

Bei stark verschachtelten Elementen kann es schnell schwierig werden, den korrekten XPath-Ausdruck zu finden. Hilfe bietet hierbei der Inspector von Browsern wie Firefox, Chrome oder Edge. Im Inspector kann ein Element angewählt werden, anschliessend steht im Kontextmenu die Funktion Copy Xpath zur Verfügung.

Fazit

Es gibt verwirrend viele Möglichkeiten, mittels Powershell Inhalte von Websites abzurufen. Für viele Fälle empfiehlt es sich, dafür Invoke-Webrequest zu verwenden und das automatisch erfolgende Parsing zu nutzen. Will man vollständige Kontrolle ausüben oder erweiterte Möglichkeiten nutzen, so ist man mit System.Net.Http.HttpClient zurzeit am besten bedient.

Zur anschliessenden Extraktion von Daten braucht man in den einfachsten Fällen nur wenige Powershell-Bordmittel. Umfassende Möglichkeiten sind durch zusätzliche Powershell-Module verfügbar.

Über den Autor

Tomaso Vasella

Tomaso Vasella hat seinen Master in Organic Chemistry an der ETH Zürich abgeschlossen und ist seit 1999 im Bereich Cybersecurity aktiv. Positionen als Berater, Engineer, Auditor und Business Developer zählen zu seinen Erfahrungen. (ORCID 0000-0002-0216-1268)

Links

Sie wollen die Sicherheit Ihrer Firewall prüfen?

Unsere Spezialisten kontaktieren Sie gern!

×
Data Leakage Prevention

Data Leakage Prevention

Tomaso Vasella

Datenverschlüsselung in der Cloud

Datenverschlüsselung in der Cloud

Tomaso Vasella

Offerten erstellen

Offerten erstellen

Tomaso Vasella

Sie wollen mehr?

Weitere Artikel im Archiv

Sie brauchen Unterstützung bei einem solchen Projekt?

Unsere Spezialisten kontaktieren Sie gern!

Sie wollen mehr?

Weitere Artikel im Archiv