背景
我们在前面已经介绍过很多网络爬虫的图文:
- 如何利用 C# 爬取 One 持有者返利数据!
- 如何利用 C# 爬取Gate.io交易所的公告!
- 如何利用 C# 爬取BigOne交易所的公告!
- 如何利用 C# 爬取 ONE 的交易数据?
- 如何利用 C# 爬取「猫眼电影:热映口碑榜」及对应影片信息!
- 如何利用 C# 爬取「猫眼电影专业版:票房」数据!
- 如何利用 C# 爬取「猫眼电影:最受期待榜」及对应影片信息!
- 如何利用 C# 爬取「猫眼电影:国内票房榜」及对应影片信息!
- 如何利用 C# + Python 破解猫眼电影的反爬虫机制?
这里有一个潜在的问题,如果网络请求过于频繁,会被对方服务器封掉IP,导致无法获取数据。
解决方案有两个:一个是降低请求的频率,另一个是使用 IP 代理服务器,即通过不同的 IP 代理服务器来进行网络请求,这样对方服务器就会认为是不同 IP 进行的网络请求,不会判定为异常,被封掉。
今天,咱们就一起通过程序来寻找免费的代理服务器,并通过代理服务器来下载 CSDN 博主的图文。
技术分析
获取免费 IP 代理服务器的网页如下:
该网页采用分页的方式进行显示,每页显示100条数据,对应的网址如下:
<u>第一页</u>
https://www.xicidaili.com/wt/1
<u>第二页</u>
https://www.xicidaili.com/wt/2
以此类推,我们就得到抓取网页的 URL 地址。
我们再来看一下网页的源码。
所有数据全部放置在 <tr>
标签中,只要我们获取对应网页的 HTML DOM TREE 即可。
代码实现
Step1 创建存储 IP 代理服务器的结构 ProxyDataItem
。
public class ProxyDataItem
{
/// <summary>
/// 国家
/// </summary>
public string Country { get; set; } = "cn";
/// <summary>
/// ip 地址
/// </summary>
public string IpAddress { get; set; } = string.Empty;
/// <summary>
/// 端口号
/// </summary>
public string Port { get; set; } = string.Empty;
/// <summary>
/// 服务器地址
/// </summary>
public string ServerAddress { get; set; } = string.Empty;
/// <summary>
/// 是否匿名
/// </summary>
public string IsAnonymous { get; set; } = string.Empty;
/// <summary>
/// 速度
/// </summary>
public string Speed { get; set; } = string.Empty;
/// <summary>
/// 连接时间
/// </summary>
public string ConnectionTime { get; set; } = string.Empty;
}
Step2 获取给定 URL 地址的 HTML DOM TREE。
public static IHtmlDocument GetHtmlDocument(string url)
{
IHtmlDocument document;
try
{
document = new JumonyParser().LoadDocument(url);
}
catch
{
document = null;
}
return document;
}
Step3 获取 IP 代理服务器的列表。
public static string EntryPoint = @"https://www.xicidaili.com/";
public static List<ProxyDataItem> GetProxy(int page)
{
List<ProxyDataItem> result = new List<ProxyDataItem>();
string url = EntryPoint + @"/wt/" + page;
IHtmlDocument document = HtmlSpiter.GetHtmlDocument(url);
if (document == null)
return result;
List<IHtmlElement> lists = document.Find("tr").ToList();
for (int i = 1; i < lists.Count; i++)
{
ProxyDataItem item = new ProxyDataItem();
List<IHtmlElement> lst = lists[i].Find("td").ToList();
try
{
item.Country = lst[0].FindFirst("img").Attribute("alt").AttributeValue;
item.IpAddress = lst[1].InnerHtml();
item.Port = lst[2].InnerHtml();
item.ServerAddress = lst[3].FindFirst("a").InnerHtml();
item.IsAnonymous = lst[4].InnerHtml();
item.Speed = lst[6].FindFirst("div").Attribute("title").AttributeValue;
item.ConnectionTime = lst[7].FindFirst("div").Attribute("title").AttributeValue;
result.Add(item);
}
catch
{
;
}
}
return result;
}
Step4 验证 IP 代理服务器的有效性。
通过该 IP 代理服务器向百度服务器发出访问请求,如果返回的响应中包含“百度”这个字符串,说明通过该 IP 代理服务器能够访问百度主页,也即该 IP 代理服务器有效。
public static bool ValidateProxy(ProxyDataItem proxy)
{
if (proxy == null)
throw new ArgumentNullException();
string address = proxy.IpAddress;
int port;
if (int.TryParse(proxy.Port, out port) == false)
return false;
try
{
WebProxy proxyObject = new WebProxy(address, port);
HttpWebRequest req = WebRequest.Create("https://www.baidu.com") as HttpWebRequest;
if (req == null)
return false;
req.Proxy = proxyObject; //设置代理
HttpWebResponse resp = (HttpWebResponse) req.GetResponse();
Encoding bin = Encoding.GetEncoding("UTF-8");
using (StreamReader sr = new StreamReader(resp.GetResponseStream(), bin))
{
string str = sr.ReadToEnd();
if (str.Contains("百度"))
{
resp.Close();
return true;
}
return false;
}
}
catch
{
return false;
}
}
Step5 通过代理服务器爬取 CSDN 博主网页。
public static bool SaveToHtml(string url, string fileName, ProxyDataItem proxy)
{
string address = proxy.IpAddress;
int port;
if (int.TryParse(proxy.Port, out port) == false)
return false;
try
{
WebProxy proxyObject = new WebProxy(address, port);
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
if (request == null)
return false;
request.Proxy = proxyObject; //设置代理
HttpWebResponse resp = (HttpWebResponse) request.GetResponse();
Encoding bin = Encoding.GetEncoding("UTF-8");
using (StreamReader sr = new StreamReader(resp.GetResponseStream(), bin))
{
string str = sr.ReadToEnd();
StreamWriter vStreamReader = new StreamWriter(fileName, false, Encoding.UTF8);
vStreamReader.Write(str);
vStreamReader.Flush();
vStreamReader.Close();
}
return true;
}
catch
{
return false;
}
}
总结
我们来看一下从网站爬取的 IP 代理服务器列表(98条记录):
经过验证的 IP 代理服务器列表(18条记录):
爬取 CSDN 博主的网页:
有关爬取 CSDN 博主网页的图文可以参见:如何利用C#爬取CSDN的博客文章?。
爬取的网页列表:
好了,今天就到这里吧!希望本次介绍的技术对大家有用。See You!
相关图文:
- 如何利用 C# 实现 K 最邻近算法?
- 如何利用 C# 实现 K-D Tree 结构?
- 如何利用 C# + KDTree 实现 K 最邻近算法?
- 如何利用 C# 对神经网络模型进行抽象?
- 如何利用 C# 实现神经网络的感知器模型?
- 如何利用 C# 实现 Delta 学习规则?
- 如何利用 C# 爬取带 Token 验证的网站数据?
- 如何利用 C# 向 Access 数据库插入大量数据?
- 如何利用 C# 开发「桌面版百度翻译」软件!
- 如何利用 C# 开发「股票数据分析软件」(上)
- 如何利用 C# 开发「股票数据分析软件」(中)
- 如何利用 C# 开发「股票数据分析软件」(下)
- 如何利用 C# 爬取「财报说」中的股票数据?
- 如何利用BigOne的API制作自动化交易系统 -- 身份验证
- 如何利用BigOne的API制作自动化交易系统 -- 获取账户资产
- 如何利用BigOne的API制作自动化交易系统 -- 订单系统