• .NET如何做爬虫
  • 发布于 2个月前
  • 338 热度
    0 评论
表妹上高三了,需要在某网站上下载试卷刷题,通常每周日回家需要下载某些名校的N套题,然后筛选部分后打印再带回寝室。她把下载的这个任务交给了小编,小编也不想动手点击,幸好小编学过几天编程,于是想用程序的方式解决这个问题,首先要解决的是通过列表获取下载地址,这步骤已经解决了,就是通过HttpClient读取页面的内容通过正则表达式匹配列表的下载链接然后自动下载,但是遇到问题,HttpClient貌似不能直接在程序中下载文件。于是就查到用文件流的方式来读取,具体怎么实现,本文将分享出来。

准备工作
这里我们拿微软官方下载文件.NET7来做例子,首先找到网址:
https://dotnet.microsoft.com/zh-cn/download
然后找到下载地址,点击下载后在浏览器的下载内容中复制下载地址:
https://download.visualstudio.microsoft.com/download/pr/5b9d1f0d-9c56-4bef-b950-c1b439489b27/b4aa387715207faa618a99e9b2dd4e35/dotnet-sdk-7.0.100-win-x64.exe
在实际的开发环境中,可以请求后用正则表达式批量抓取。

编写代码
  const int BufferSize = 8192;// 定义缓存大小,8192 字节
  static readonly HttpClient _httpClient = new HttpClient();//用单例创建http请求
        /// <summary>
        /// 从网页上下载文件并保存到指定目录
        /// </summary>
        /// <param name="url">文件下载地址</param>
        /// <param name="directoryName">文件下载目录</param>
        /// <param name="fileName">不包括扩展名</param>
        /// <returns>下载是否成功</returns>
        static async Task<bool> DownloadFile(string url, string directoryName, string fileName)
        {
              bool sign = true;
              try
            {
                HttpResponseMessage response = await _httpClient.GetAsync(url);
                using (Stream stream = await response.Content.ReadAsStreamAsync())
                {
                    //获取文件后缀
                    string extension = Path.GetExtension(response.RequestMessage.RequestUri.ToString());
                    using (FileStream fileStream = new FileStream($"{directoryName}/{fileName}{extension}", FileMode.CreateNew))
                    {
                        byte[] buffer = new byte[BufferSize];
                        int readLength = 0;
                        int length;
                        while ((length = await stream.ReadAsync(buffer, 0, buffer.Length)) != 0)
                        {
                            readLength += length;
                            // 通过流写入到文件
                            fileStream.Write(buffer, 0, length);
                        }
                    }
                }
            }
            catch (IOException)
            {  //日志可以详细写
                sign = false;
                Console.WriteLine("请检查文件名是否重复或者超时!");
            }
            return sign;
        }
调用:
我们用main方法来模拟调用
       static void Main(string[] args)
        {   //获取的url地址
            string down = "https://download.visualstudio.microsoft.com/download/pr/5b9d1f0d-9c56-4bef-b950-c1b439489b27/b4aa387715207faa618a99e9b2dd4e35/dotnet-sdk-7.0.100-win-x64.exe";
            string path = AppDomain.CurrentDomain.BaseDirectory + "//Files";
            if (!Directory.Exists(path))
            { Directory.CreateDirectory(path); }
            string filename = System.IO.Path.GetFileName(down);
            //由于main方法不是异步方法,故调用需要.GetAwaiter().GetResult(),正常不建议这么做
            var rel=  DownloadFile(down, path, filename).GetAwaiter().GetResult();
             Console.WriteLine(rel);
        }//返回true
可以在bin目录查看下载成功了

结语
本案例实现了用程序下载文件的例子,使用了HttpClient请求,获取内容后通过文件流来保存文件。本案例仅供参考,程序猿的你有啥更好的方法吗?文笔水平有限,欢迎留言或提出异议。
用户评论