流程清晰之后,我们就可以制作软件来对网盘地址链接批量处理得到下载链接。
选型
我们的整个操作流程类似模拟浏览器操作,最好的解决方法其实是使用Selenium直接操作浏览器抓取。不过这方面我还没什么研究,就直接用最近发现的木鱼大牛的 FSLib.Network 库来实现。这个类库是实现了HTTP访问过程中对Cookie的自动处理,在大多数情况下都可以模拟浏览器。
使用nuget在项目中安装 FSLib.Network 包:
Install-Package network.fishlee.net
获取流程实现
下面来依据流程完成通过页面地址来获得文件下载连接的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
| private async void GetDownLoadUrl(string fileUrl) { var client = new HttpClient(); StringBuilder Result; byte[] bytes; string downPath = string.Empty; int id = Convert.ToInt32(Extract(fileUrl, "\\d{7,}")); fileUrl = fileUrl.Replace("ymhwp", "yimuhe"); var filecontext = client.Create<string>(HttpMethod.Get, fileUrl); await filecontext.SendTask(); if (filecontext.IsValid()) { fileUrl = fileUrl.Replace("file", "down"); var downcontext = client.Create<string>(HttpMethod.Get, fileUrl); await downcontext.SendTask(); if (downcontext.IsValid()) { 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('\0', 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()) { 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()) { HtmlDocument html = new HtmlDocument(); html.LoadHtml(h1.Result); downPath = html.GetElementbyId("downs").Attributes["href"].Value; tBAfter.AppendText(downPath + NewLine); } }
} }
|
批量获取实现
我的批量实现思路为将要获取的链接加入一个队列当中,线程从队头移出数据一条进行地址获取,获取成功不进行操作,失败则将地址添回到队尾。循环获取直到队列为空。另一个队列储存正在处理的数据,仅当两个线程均为空时才会陆续结束所有线程。线程执行的方法在上边的方法基础上又做了一些修改。
具体实现代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
| 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); var client = new HttpClient(); StringBuilder Result; byte[] bytes; string downPath = string.Empty; int id = Convert.ToInt32(Extract(fileUrl, "\\d{7,}")); fileUrl = fileUrl.Replace("ymhwp", "yimuhe"); var filecontext = client.Create<string>(HttpMethod.Get, fileUrl); await filecontext.SendTask(); if (filecontext.IsValid()) { fileUrl = fileUrl.Replace("file", "down"); var downcontext = client.Create<string>(HttpMethod.Get, fileUrl); await downcontext.SendTask(); if (downcontext.IsValid()) { 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('\0', 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()) { 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()) { HtmlDocument html = new HtmlDocument(); html.LoadHtml(h1.Result); downPath = html.GetElementbyId("downs").Attributes["href"].Value; tBAfter.AppendText(downPath + NewLine); } } } if (string.IsNullOrWhiteSpace(downPath)) { _pathList.Add(path); } _pathReady.Remove(path); } } }
|
结束
本文旨在抛砖引玉,因为一些都懂得的原因,就不给出成品的下载地址了,有需要的童鞋可以自行完成。