• 一木禾网盘下载分析及批量获取下载地址的实现(下)


    分析过后,我们接着来做一下代码实现

    三、获取流程实现

    近期正巧看到了木鱼在自己博客里发布的一个HTTP客户端库,困扰于原生HttpWebRequest的我立马就下来用了用,效果果然不错,所以本项目的HTTP请求就由

    FSLib.Network 类库来完成,语法差别不大,不太懂的地方可以回复。

    添加类库可以使用nuget:

    Install-Package network.fishlee.net

     

    下面来写通过展示地址来获得下载连接的方法:

    private async void GetDownLoadUrl(string fileUrl)
    {
        //建立HTTP客户端
        var client = new HttpClient();
        //用于接收验证码
        StringBuilder Result;
        //验证码的字符数组
        byte[] bytes;
        //用于接收下载链接
        string downPath = string.Empty;
        //通过正则匹配到链接中的 fileid
       int id = Convert.ToInt32(Extract(fileUrl, "\d{7,}"));
        //有时会出现一级域名为ymhwp的情况,这里先做一下替换,以防不测
        fileUrl = fileUrl.Replace("ymhwp", "yimuhe");
        //创建展示页面请求
        var filecontext = client.Create<string>(HttpMethod.Get, fileUrl);
        //发送请求
        await filecontext.SendTask();
        if (filecontext.IsValid())//如果请求成功
        {
            //替换链接中的fil为down,使其成为下载页面地址
            fileUrl = fileUrl.Replace("file", "down");
            //创建下载页面请求
             var downcontext = client.Create<string>(HttpMethod.Get, fileUrl);
            await downcontext.SendTask();
            if (downcontext.IsValid())
            {
                //设置初始返回值为0,表示验证码输入错误,即识别失败
                int response = 0;
                while (response == 0)//循环识别,直到识别成功
                {
                    //创建验证码图片请求
                       var vcode = client.Create<Byte[]>(HttpMethod.Get, "http://www.yimuhe.com/n_downcode.php");
                    await vcode.SendTask();
                    if (vcode.IsValid())
                    {
                        //将获取到的验证码图片存入字节数组中
                        bytes = vcode.Result;
                        Result = new StringBuilder('', 256);
                        //识别验证码
                        GetVcodeFromBuffer(1, bytes, bytes.Length, Result);
                        //创建检验验证码请求
                        var resp = client.Create<string>(HttpMethod.Post,
                            "http://www.yimuhe.com/n_downcode.php", data: "action=yz&id=" + id + "&code=" + Result);
                        await resp.SendTask();
                        if (resp.IsValid())
                        {
                            //返回验证码校验值、成功为1失败为0
                            response = Convert.ToInt32(resp.Result);
                        }
                    }
                }
                //创建获取下载地址请求
                var h1 = client.Create<string>(HttpMethod.Post,
                        "http://www.yimuhe.com/n_dd.php?file_id=" + id + "&ser=99", refer: "http://www.yimuhe.com/down-2546737.html", data: id.ToString());
                await h1.SendTask();
                if (h1.IsValid())
                {
                    //通过HtmlAgilityPack库完成html解析,获得下载地址
                       HtmlDocument html = new HtmlDocument();
                    html.LoadHtml(h1.Result);
                    downPath = html.GetElementbyId("downs").Attributes["href"].Value;
                    tBAfter.AppendText(downPath + NewLine);
                }
            }
    
        }
    }

    通过以上方法即可实现单个文件下载地址的获取。

    四、批量获取实现

    我的批量实现思路为将要获取的链接加入一个队列当中,线程从队头移出数据一条进行地址获取,获取成功不进行操作,失败则将地址添回到队尾。循环获取直到队列为空。另一个队列储存正在处理的数据,仅当两个线程均为空时才会陆续结束所有线程。线程执行的方法在上边的方法基础上又做了一些修改。

    具体实现代码如下:

    private async void GetDownLoadUrl()
    {
        //当链接队列和正在处理队列存在不为空时,循环执行以下代码
        while (_pathList.Count > 0 || _pathReady.Count > 0)
        {
            //当链接队列不为空时
            if (_pathList.Count > 0)
            {
    
                //从队头取出一条数据
                string fileUrl = _pathList[0];
                _pathList.RemoveAt(0);
                _pathReady.Add(fileUrl);
                //建立HTTP客户端
                var client = new HttpClient();
                //用于接收验证码
                StringBuilder Result;
                //验证码的字符数组
                byte[] bytes;
                //用于接收下载链接
                string downPath = string.Empty;
                //通过正则匹配到链接中的 fileid
                int id = Convert.ToInt32(Extract(fileUrl, "\d{7,}"));
                //有时会出现一级域名为ymhwp的情况,这里先做一下替换,以防不测
                fileUrl = fileUrl.Replace("ymhwp", "yimuhe");
                //创建展示页面请求
                var filecontext = client.Create<string>(HttpMethod.Get, fileUrl);
                //发送请求
                await filecontext.SendTask();
                if (filecontext.IsValid())//如果请求成功
                {
                    //替换链接中的fil为down,使其成为下载页面地址
                    fileUrl = fileUrl.Replace("file", "down");
                    //创建下载页面请求
                    var downcontext = client.Create<string>(HttpMethod.Get, fileUrl);
                    await downcontext.SendTask();
                    if (downcontext.IsValid())
                    {
                        //设置初始返回值为0,表示验证码输入错误,即识别失败
                        int response = 0;
                        while (response == 0)//循环识别,直到识别成功
                        {
                            //创建验证码图片请求
                            var vcode = client.Create<Byte[]>(HttpMethod.Get, "http://www.yimuhe.com/n_downcode.php");
                            await vcode.SendTask();
                            if (vcode.IsValid())
                            {
                                //将获取到的验证码图片存入字节数组中
                                bytes = vcode.Result;
                                Result = new StringBuilder('', 256);
                                //识别验证码
                                GetVcodeFromBuffer(1, bytes, bytes.Length, Result);
                                //创建检验验证码请求
                                var resp = client.Create<string>(HttpMethod.Post,
                                    "http://www.yimuhe.com/n_downcode.php", data: "action=yz&id=" + id + "&code=" + Result);
                                await resp.SendTask();
                                if (resp.IsValid())
                                {
                                    //返回验证码校验值、成功为1失败为0
                                    response = Convert.ToInt32(resp.Result);
                                }
                            }
                        }
                        //创建获取下载地址请求
                        var h1 = client.Create<string>(HttpMethod.Post,
                                "http://www.yimuhe.com/n_dd.php?file_id=" + id + "&ser=99", refer: "http://www.yimuhe.com/down-2546737.html", data: id.ToString());
                        await h1.SendTask();
                        if (h1.IsValid())
                        {
                            //通过HtmlAgilityPack库完成html解析,获得下载地址
                            HtmlDocument html = new HtmlDocument();
                            html.LoadHtml(h1.Result);
                            downPath = html.GetElementbyId("downs").Attributes["href"].Value;
                            //将获取到的地址显示到界面
                            tBAfter.AppendText(downPath + NewLine);
                        }
                    }
                }
                //如果downPath为空,则请求失败
                if (string.IsNullOrWhiteSpace(downPath))
                {
                    //将请求链接添回队尾
                    _pathList.Add(path);
                }
                //处理完毕,移出当前处理队列
                _pathReady.Remove(path);
            }
        }
    }

    到此程序就基本完成了,其他的细节,如识别类库载入等也不再赘述,有问题可以回复问我,新人发博客,排版很差,不好意思。

  • 相关阅读:
    Kafka日志及Topic数据清理
    python
    kotlin集合操作
    tomcat 下配置 可 调试
    linux 安装nexus3
    启动 idea 编译报错 kotlin
    nginx 增加 lua模块
    logstash配合filebeat监控tomcat日志
    redis 高级特性 不要太好用
    SpringBoot与Docker1
  • 原文地址:https://www.cnblogs.com/WayneShao/p/5175567.html
Copyright © 2020-2023  润新知