Wie werden alle Bilder von einer Site auf dem C # + HtmlAgilityPack heruntergeladen?

.net c# html-agility-pack parsing

Frage

Ich benutze Programme wie: Teleport, HTTrack, Offline Explorer, DownThemAll und andere. Alle Bilder werden nur gefunden - DownThemAll. Aber ich habe viele Seiten, mit denen man Bilder von den Waren herunterladen möchte. DownThemAll ist nicht geeignet.

Ich habe das Programm auf C # + HtmlAgilityPack geschrieben, aber sie hat nicht alle Bilder der Waren gefunden.

Im Idealfall möchte ich Folgendes:

  1. Das Programm lädt die Datei URLS.txt. In denen solche Referenzen sind:

http://www.onlinetrade.ru/catalogue/televizori-c181/

http://www.onlinetrade.ru/catalogue/3d_ochki-c130/

etc

  1. Das Programm lädt auf diesen Seiten alle Bilder der Ware.

Was raten Sie? Vielleicht irre ich den Code auf C # zu schreiben?

HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
WebClient wc = new WebClient();
string url = wc.DownloadString("http://www.onlinetrade.ru/catalogue/televizori-c181/");
doc.LoadHtml(url);

HtmlNodeCollection nodes = doc.DocumentNode.SelectNodes("//a[@class='catalog__displayedItem__columnFotomainLnk']/img");

if (nodes != null)
            {
                foreach (HtmlNode node in nodes)
                {                    
                    listBox1.Items.Add(node.Attributes["src"].Value);
                }
            }

Akzeptierte Antwort

Du hast es gut gemacht. In dieser Lösung verwende ich LINQ und TPL.

Diese Seite verwendet Seitenumbrüche, daher müssen Sie alle Seiten laden, um alle Bilder des Produkts herunterladen zu können.

  1. Erste Seite laden (HtmlNode)
  2. Entdecken Sie, wie viele Seiten dieser Produktkatalog hat
  3. Andere Seiten laden (HtmlNode)

Dann haben Sie eine Sammlung von Seiten

  1. Laden Sie img Knoten, die Sie herunterladen möchten
  2. Erstellen Sie ein Tupel mit der Image-URL und der neuen WebClient-Instanz¹
  3. Bild herunterladen
public class ImageDownloader
{
    public void DownloadImagesFromUrl(string url, string folderImagesPath)
    {
        var uri = new Uri(url + "/?per_page=50");
        var pages = new List<HtmlNode> { LoadHtmlDocument(uri) };

        pages.AddRange(LoadOtherPages(pages[0], url));

        pages.SelectMany(p => p.SelectNodes("//a[@class='catalog__displayedItem__columnFotomainLnk']/img"))
             .Select(node => Tuple.Create(new UriBuilder(uri.Scheme, uri.Host, uri.Port, node.Attributes["src"].Value).Uri, new WebClient()))
             .AsParallel()
             .ForAll(t => DownloadImage(folderImagesPath, t.Item1, t.Item2));
    }

    private static void DownloadImage(string folderImagesPath, Uri url, WebClient webClient)
    {
        try
        {
            webClient.DownloadFile(url, Path.Combine(folderImagesPath, Path.GetFileName(url.ToString())));
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }

    private static IEnumerable<HtmlNode> LoadOtherPages(HtmlNode firstPage, string url)
    {
        return Enumerable.Range(1, DiscoverTotalPages(firstPage))
                         .AsParallel()
                         .Select(i => LoadHtmlDocument(new Uri(url + "/?per_page=50&page=" + i)));
    }

    private static int DiscoverTotalPages(HtmlNode documentNode)
    {
        var totalItemsDescription = documentNode.SelectNodes("//div[@class='catalogItemList__numsInWiev']").First().InnerText.Trim();
        var totalItems = int.Parse(Regex.Match(totalItemsDescription, @"\d+$").ToString());
        var totalPages = (int)Math.Ceiling(totalItems / 50d);
        return totalPages;
    }

    private static HtmlNode LoadHtmlDocument(Uri uri)
    {
        var doc = new HtmlDocument();
        var wc = new WebClient();
        doc.LoadHtml(wc.DownloadString(uri));

        var documentNode = doc.DocumentNode;
        return documentNode;
    }
}

Und Sie können so verwenden:

DownloadImagesFromUrl("http://www.onlinetrade.ru/catalogue/televizori-c181/", @"C:\temp\televizori-c181\images");

Und dann wurden 178 Bilder heruntergeladen.

Wenn Bilder heruntergeladen werden, kann dies manchmal fehlschlagen. Daher empfehle ich, das Wiederholungsmuster mit Polly zu implementieren.

Obs¹ : WebClient unterstützt keinen parallelen Betrieb, deshalb erstelle ich einen für jede Bild-URL.



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