點擊我前往Github查看源代碼 別忘記star
本項目github地址:https://github.com/wangqifan/ZhiHu
一.對請求IP等進行限制的。
以知乎為例,當我們的請求速度到達一定的閾值,會觸發反爬蟲機制!
在我爬取知乎百萬用戶信息中,出現了429錯誤(Too Many Requests) 詳情請見我的博客http://www.cnblogs.com/zuin/p/6227834.html

應對策略.
1.降低爬蟲采集速率,使速率略低於閾值
進行測試,偵探出閾值。
開啟6個線程抓取時,服務器返回429
for (int i = 0; i < 6; i++) { ThreadPool.QueueUserWorkItem(GetUser); }
開啟5個線程時,運行良好,沒有遭到阻礙
for (int i = 0; i < 6; i++) { ThreadPool.QueueUserWorkItem(GetUser); }
所以,如果任務量比較小可以采取這種策略進行
2.建立代理池
c#實現代理服務很簡單

詳細請見我的博客http://www.cnblogs.com/zuin/p/6261677.html
每次請求都在代理池中隨機獲取一個代理,這樣就不會達到閾值了。缺點是網上收集代理有效率很低,隨時都可能無法使用。
3。使用雲代理服務
服務商的代理穩定,高質量。以阿布雲為例
官方網站:https://www.abuyun.com/
將資源下載進行修改即可
public static string DownLoadString(string url)
{
string Source = string.Empty;
try
{
string proxyHost = "http://proxy.abuyun.com";
string proxyPort = "9020";
// 代理隧道驗證信息
string proxyUser = "H71T6AMK7GRE";
string proxyPass = "D3F01F";
var proxy = new WebProxy();
proxy.Address = new Uri(string.Format("{0}:{1}", proxyHost, proxyPort));
proxy.Credentials = new NetworkCredential(proxyUser, proxyPass);
ServicePointManager.Expect100Continue = false;
Stopwatch watch = new Stopwatch();
watch.Start();
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0";
request.Accept = "*/*";
request.Method = "GET";
request.Referer = "https://www.zhihu.com/";
request.Headers.Add("Accept-Encoding", " gzip, deflate, br");
request.KeepAlive = true;//啟用長連接
request.Proxy = proxy;
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (Stream dataStream = response.GetResponseStream())
{
if (response.ContentEncoding.ToLower().Contains("gzip"))//解壓
{
using (GZipStream stream = new GZipStream(response.GetResponseStream(), CompressionMode.Decompress))
{
using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
{
Source = reader.ReadToEnd();
}
}
}
else if (response.ContentEncoding.ToLower().Contains("deflate"))//解壓
{
using (DeflateStream stream = new DeflateStream(response.GetResponseStream(), CompressionMode.Decompress))
{
using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
{
Source = reader.ReadToEnd();
}
}
}
else
{
using (Stream stream = response.GetResponseStream())//原始
{
using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
{
Source = reader.ReadToEnd();
}
}
}
}
}
request.Abort();
watch.Stop();
Console.WriteLine("請求網頁用了{0}毫秒", watch.ElapsedMilliseconds.ToString());
}
catch
{
Console.WriteLine("出錯了,請求的URL為{0}", url);
}
return Source;
}
其他:根據友軍情報,服務器可能不是對IP進行限制,而是對賬戶進行限制,及時使用代理每次請求都是同一賬戶,如果對賬戶進行限制,可以申請大量賬戶,建立cookie池,每次請求都隨機獲取一個cookie,保證低於閾值。除了cookie池還有useragent池,根據情況建立。
二.對參數進行加密
現代web應用富AJAX,如果是想要數據包含在ajax中,直接分析ajax返回數據就可以了,但是人家可沒有那么容易讓你的手
看看網易雲音樂

網易對參數進行了加密,想破解加密算法可行性太低,對於這種參數加密,采取在應用中內嵌瀏覽器。
采用的是 WebBrowser
引入命名空間
using System.Windows.Forms;
封裝好下載頁面方法
private static string htmlstr; private static void GetHtmlWithBrowser(object url) { htmlstr = string.Empty; using(WebBrowser wb = new WebBrowser())
{ wb.AllowNavigation = true; wb.Url = new Uri(url.ToString()); while (wb.ReadyState != WebBrowserReadyState.Complete) { Application.DoEvents(); } if (wb.ReadyState == WebBrowserReadyState.Complete) { HtmlDocument doc = wb.Document; htmlstr = doc.Window.Frames[0].Document.Body.InnerHtml; Console.WriteLine(htmlstr); }
} }
做個測試 按單曲搜索下“煙霞”


這樣我們就拿到了搜索數據
,
