Ich habe folgende Seite, von der ich eine Liste von Proxy-Servern aus einer Tabelle erhalten möchte:
http://proxy-list.org/spanish/search.php?search=&country=any&type=any&port=any&ssl=any
Jede Zeile in der Tabelle ist ein ul-Element. Mein Problem ist, wenn ich das erste li-Element erhalte, dessen Klasse "proxy" vom ul-Element ist. Ich möchte die IP und den Port erhalten, also führe ich einen InnerText aus, aber da li-Element einen untergeordneten Skriptknoten hat, gibt es den Text des Skriptknotens zurück.
Unterhalb eines Bildes der Struktur der Seite:
Ich habe unten Code mit Html Agility Pack und LINQ versucht:
WebClient webClient = new WebClient();
string page = webClient.DownloadString("http://proxy-list.org/spanish/search.php?search=&country=any&type=any&port=any&ssl=any");
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(page);
List<List<string>> table = doc.DocumentNode.SelectSingleNode("//div[@class='table']")
.Descendants("ul")
.Where(ul => ul.Elements("li").Count() > 1)
.Select(ul => ul.Elements("li").Select(li =>
{
string result = string.Empty;
if (li.HasClass("proxy"))
{
HtmlNode liTmp = li.Clone();
liTmp.RemoveAllChildren();
result = liTmp.InnerText.Trim();
}
else
{
result = li.InnerText.Trim();
}
return result;
}).ToList()).ToList();
Ich kann eine Liste erhalten, in der jedes Element eine Liste mit den Feldern (Proxy, PaÃs, Tipo, Velocidad, HTTPS / SSL) ist, aber Feld-Proxy ist immer leer. Auch bekomme ich nicht die Säulen "País" und "Ciudad".
Dies liegt daran, dass diese Werte nach dem Laden der Seite durch JavaScript in das DOM eingefügt werden. Tatsächlich ist der Wert innerhalb des Proxy()
eine Base64-Darstellung dessen, wonach Sie suchen.
In dem Bild, das Sie über den Wert MTQ4LjI0My4zNy4xMDE6NTMyODE=
haben, wird MTQ4LjI0My4zNy4xMDE6NTMyODE=
zu 148.243.37.101:53281
dekodiert
Die unverarbeitete analysierte Zeichenfolge, die Sie dem Agility-Paket zuführen, enthält nur das Proxy
Feld ...
<div class=\ "table-wrap\">\r\n
<div class=\ "table\">\r\n
<ul>\r\n
<li class=\ "proxy\">
<script type=\ "text/javascript\">
Proxy('MTM4Ljk3LjkyLjI0OTo1MzgxNg==')
</script>
</li>\r\n
<li class=\ "https\">HTTP</li>\r\n
<li class=\ "speed\">29.5kbit</li>\r\n
<li class=\ "type\">
<strong>Elite</strong>
</li>\r\n
<li class=\ "country-city\">\r\n
<div>\r\n
<span class=\ "country\" title=\ "Brazil\">
<span class=\ "country-code\">
<span class=\ "flag br\"></span>
<span class=\ "name\">BR Brasil</span>
</span>
</span>
<!--\r\n -->
<span class=\ "city\">
<span>Rondon</span>
</span>\r\n </div>\r\n </li>\r\n </ul>\r\n
<div class=\ "clear\"></div>\r\n
Verwenden Sie den folgenden Code:
HttpClient client = new HttpClient();
var docResult = client.GetStringAsync("http://proxy-list.org/spanish/search.php?search=&country=any&type=any&port=any&ssl=any").Result;
HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(docResult);
Regex reg = new Regex(@"Proxy\('(?<value>.*?)'\)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
var stuff = doc.DocumentNode.SelectSingleNode("//div[@class='table']")
.Descendants("li")
.Where(x => x.HasClass("proxy"))
.Select(li =>
{
return li.InnerText;
}).ToList();
foreach (var item in stuff)
{
var match = reg.Match(item);
var proxy = Encoding.Default.GetString(System.Convert.FromBase64String(match.Groups["value"].Value));
Console.WriteLine($"{item}\t\tproxy = {proxy}");
}