一木禾网盘文件下载地址批量获取实现

流程清晰之后,我们就可以制作软件来对网盘地址链接批量处理得到下载链接。

选型

我们的整个操作流程类似模拟浏览器操作,最好的解决方法其实是使用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)
{
//建立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('\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())
{
//返回验证码校验值、成功为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);
}
}

}
}

批量获取实现

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

具体实现代码如下:

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);
//建立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('\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())
{
//返回验证码校验值、成功为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);
}
}
}

结束

本文旨在抛砖引玉,因为一些都懂得的原因,就不给出成品的下载地址了,有需要的童鞋可以自行完成。

欢迎关注我的其它发布渠道