吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 3162|回复: 5
收起左侧

[其他转载] .net 爬取网页图片

  [复制链接]
redblue 发表于 2021-2-3 23:09

话不多说,直接上代码,大体功能实现了,里面有些错误处理没处理
使用方法:spider.exe images  其中images为指定的存储目录,也可以指定绝对路径
也可以打包成linux程序在linux上使用,在后面提供windows/linux下的单文件程序

using HtmlAgilityPack;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace spider
{
    /// <summary>
    /// 结果结构体
    /// </summary>
    struct Result
    {
        public string url;
        public string title;
    }
    class Program
    {
        private static readonly string[] UA =  {
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36 Edg/88.0.705.56",
            "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50",
            "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11",
            "Mozilla/5.0 (Linux; U; android 2.3.7; en-us; Nexus One Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
            "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11",
        };
        //http客服端
        private static readonly HttpClient client = new HttpClient();

        //下载地址
        private static readonly string url = "https://www.mzitu.com/mm/";
        static async Task Main(string[] args)
        {
            //设置保存路径,默认保存在程序同级目录
            string storagePath = args.Length >= 1 ? args[0] : "";
            //设置请求头
            SetReferer(client, url);
            Random rd = new Random();
            client.DefaultRequestHeaders.Add("User-Agent", UA[rd.Next(0, UA.Length)]);
            //获取总页数
            int pages = await GetMaxPage(url, "//div[@class='pagination']/div/a[last()-1]");
            for (int i = 1; i <= pages; i++)
            {
                //获取每页的链接和标题
                string currUrl = url + $"page/{i}";
                Console.WriteLine(currUrl);
                List<Result> results = await GetCurrentPageLinks(currUrl);
                foreach (Result result in results)
                {
                    //Console.WriteLine($"{result.url}----{result.title}");
                    if (!Directory.Exists(Path.Combine(storagePath, result.title)))
                    {
                        Directory.CreateDirectory(Path.Combine(storagePath, result.title));
                    }
                    int imagePages = await GetMaxPage(result.url, "//div[@class='pagenavi']/a[last()-1]");
                    for (int j = 1; j <= imagePages; j++)
                    {
                        string imagePageUrl = result.url + $"/{j}";
                        Console.WriteLine(imagePageUrl);
                        string imageUrl = await GetImageUrl(imagePageUrl);
                        await DownloadAsync(imageUrl, Path.Combine(storagePath, result.title));
                    }
                    //Thread.Sleep(2000);
                }
                //Thread.Sleep(3000);
            }
        }
        /// <summary>
        /// 发送get请求
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        static async Task<string> GetByAsync(string url)
        {
            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
            try
            {
                HttpResponseMessage responseMessage = await client.GetAsync(url);
                HttpContent content = responseMessage.Content;
                string contentString = await content.ReadAsStringAsync();
                return contentString;
            }
            catch (Exception ex)
            {
                Console.WriteLine("请求错误:" + ex.ToString());
                return "";
            }
        }
        /// <summary>
        /// 下载图片并保存
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        static async Task DownloadAsync(string url, string dir)
        {
            Console.WriteLine($"正在下载:{url}");
            string fileName = Path.GetFileName(url);
            string filePath = Path.Combine(dir, fileName);
            byte[] byteArr = await client.GetByteArrayAsync(url);

            using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write))
            {
                fs.Write(byteArr, 0, byteArr.Length);
                fs.Close();
                fs.Dispose();
            };
            Console.WriteLine($"图片{url}下载完成");
        }
        /// <summary>
        /// 获取页面上的最大页数
        /// </summary>
        /// <param name="url"></param>
        /// <param name="pattern"></param>
        /// <returns></returns>
        static async Task<int> GetMaxPage(string url, string pattern)
        {
            HtmlNode documentNode = await GetDocumentNode(url);
            HtmlNode Node = documentNode.SelectSingleNode(pattern);
            return Node != null ? int.Parse(Node.InnerText) : 0;
        }
        /// <summary>
        /// 获取列表页面的链接和标题
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        static async Task<List<Result>> GetCurrentPageLinks(string url)
        {
            List<Result> LinkList = new List<Result>();
            HtmlNode documentNode = await GetDocumentNode(url);
            HtmlNodeCollection NodeCollection = documentNode.SelectNodes("//ul[@id='pins']/li/span[1]/a");
            if(NodeCollection == null)
            {
                return LinkList;
            }
            foreach (HtmlNode Node in NodeCollection)
            {
                string href = Node.GetAttributeValue("href", "");
                string title = Node.InnerText;
                Result result = new Result { url = href, title = title };
                LinkList.Add(result);
            }
            return LinkList;
        }
        /// <summary>
        /// 获取HTML Document
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        static async Task<HtmlNode> GetDocumentNode(string url)
        {
            HtmlDocument doc = new HtmlDocument();
            string html = await GetByAsync(url);
            doc.LoadHtml(html);
            HtmlNode documentNode = doc.DocumentNode;
            return documentNode;
        }
        /// <summary>
        /// 获取页面上图片的地址
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        static async Task<string> GetImageUrl(string url)
        {
            HtmlNode documentNode = await GetDocumentNode(url);
            HtmlNode Node = documentNode.SelectSingleNode("//div[@class='main-image']/p/a/img");
            string src = Node.GetAttributeValue("src", "");
            return src;
        }

        /// <summary>
        /// 设置请求Refer而
        /// </summary>
        /// <param name="client"></param>
        /// <param name="url"></param>
        static void SetReferer(HttpClient client, string url)
        {
            Uri uri = new Uri(url);
            string path = uri.LocalPath;
            client.DefaultRequestHeaders.Add("Referer", url.Replace(path, ""));
        }
    }
}

文件下载地址:https://wws.lanzouj.com/iXS4lla6xrc 密码:6uu5  压缩包里面是一个exe程序和一个linux程序

免费评分

参与人数 2吾爱币 +2 热心值 +1 收起 理由
Fixedsys + 1 + 1 谢谢@Thanks!
asdf998 + 1 谢谢@Thanks!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

fissssssh 发表于 2021-2-3 23:23

GetByAsync可以使用HttpClient.GetStringAsync代替
DownloadAsync也可使用HttpClient.GetStreamAsync().CopyTo(fs)简化
luanshils 发表于 2021-2-4 00:29
很强,但是看过py的爬图片,我一下子觉得.net是不是繁琐了
头像被屏蔽
绝地飞鸿 发表于 2021-2-4 09:51
WANCHEN 发表于 2021-3-15 13:31
感谢分享,正好需要这方面示例
lanwd 发表于 2021-3-15 14:08
感谢楼主 分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 20:28

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表