如何在C#+HtmlAgilityPack上从网站下载所有图像

本文关键字:下载 图像 网站 C#+HtmlAgilityPack | 更新日期: 2023-09-27 18:28:06

我使用的程序包括:Teleport、HTTrack、Offline Explorer、DownThemAll等。所有图片都只能找到-DownThemAll。但我有很多页面,你想用它们下载商品的图片。DownThemAll不适用。

我在C#+HtmlAgilityPack上写了这个程序,但她没有找到所有商品的图片。

理想情况下,我想要以下内容:

  1. 程序加载文件URLS.txt。其中的引用包括:

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

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

etc

  1. 程序在这些页面上加载商品的所有图片

你有什么建议?也许我在C#上写代码是错的?

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);
                }
            }

如何在C#+HtmlAgilityPack上从网站下载所有图像

你进展顺利。在这个解决方案中,我使用LINQ和TPL。

这个网站使用分页,所以你必须加载所有页面才能下载所有产品的图像。

  1. 加载第一页(HtmlNode)
  2. 了解此产品目录有多少页
  3. 加载其他页面(HtmlNode)

然后你有一个页面的集合

  1. 加载要下载的img节点
  2. 使用de Image url和新的WebClient实例创建元组
  3. 下载图像
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;
    }
}

你可以这样使用:

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

然后下载了178张图片。

当图像下载时,有时可能会失败,所以我建议您使用Polly实现重试模式。

Obsã:WebClient不支持并行操作,所以我为每个图像url创建一个。