本來想繼續(xù)寫Go方面的,不過由于五一節(jié)前收到需要爬取3個網(wǎng)站的一些數(shù)據(jù),那就剛好總結(jié)一下。文章講的都是很基本讓你大概知道爬蟲是個什么東西用來做什么的,適合新手入門,之后有可能會逐步加深功能,譬如多線程,隊列,深網(wǎng)爬取,反爬等。
一句話概括爬蟲
利用Http、Https協(xié)議模擬人操作將開放性的web傳輸內(nèi)容保存到本地中。
爬蟲準備
- 開發(fā)語言(這次用C#寫)
- 目標數(shù)據(jù)
開始爬取案例一
這次需要爬取的是平行進口車的數(shù)據(jù)
-
分析網(wǎng)頁的數(shù)據(jù)來源
首先了解需求之后打開F12,看到有好多數(shù)據(jù)請求會影響我們分析有用的數(shù)據(jù)來源,所以一般可以直接選擇XHR看接口,這樣就可以篩走很多不需要的請求,最終定位到這個接口是我們所需要的。
既然知道了是哪個接口,請求頭的信息也知道了,那么就可以模擬發(fā)送請求了。請求接口請求頭信息 - 代碼爬取
由于是工作匯總,所以這次就直接用內(nèi)部的類庫了,但是基本邏輯是一樣的(訪問請求地址,發(fā)送參數(shù),得到內(nèi)容,解析內(nèi)容)這里需要做一步escape解析得到中文。
var html = "";
var postUrl = "http://*************/conditionList?version=v2.0";
var postData = "page_size=200&price_range=&pbid=&page=1&mtat=&level=&import=3&drive=&displacement=&bodywork=";
html = client.POST(postUrl, postData).HTML; //請求接口并接收返回內(nèi)容
html = UAP.Function.String.EscapeDecode(html); //這里需要做escape解析
if (string.IsNullOrWhiteSpace(html)) //判斷內(nèi)容是否為空
{
Console.WriteLine("html is null");
return;
}
var data = UAP.JSON.Parse(html); //解析成為JSON
if (!(data.Int("code") == 200 && data.Boolean("success"))) //判斷接口是否正常
{
Console.WriteLine("code or success not match");
return;
}
var list = data["data"]["list"];
var dt = new UAP.Data.DataTable(list);
if (dt.Rows.Count <= 0) //數(shù)據(jù)是否有值
{
Console.WriteLine("dt count is 0");
return;
}
CAR.DB.admin.Once().Inserts("table", dt); //入庫

這種是最簡單的爬取接口直接返回json沒有做cookies驗證或者sign之類的,所以基本上這就已經(jīng)完成一個爬取需求了。
接下來案例二
第二個案例同樣是需要爬取車型數(shù)據(jù),至于有什么特殊我們接下來看


step 2. 寫代碼利用webclient用get請求這個網(wǎng)站得到內(nèi)容
var html = "";
var postUrl = "";
List<object> ls = new List<object>();
postUrl = "http://*************/meiguiche/";
html = client.GET(postUrl).HTML; //獲取數(shù)據(jù)
html = Regex.Replace(html, @"\s*\n\s*", ""); //關(guān)鍵去掉多余空格和換行
var matchs = Regex.Matches(html, @"<a href=.(http://www.*********.com/\d+/meiguiche/).>(.*?)</a>");
if (matchs.Count == 0) //判斷正則匹配是否有值
{
Console.WriteLine("matchs is null");
return;
}
foreach (Match match in matchs)
{
ls.Add(
UAP.JSON.NEW
.Add("id", match.Result("$1").RegexGetResult(@"(\d+)"))
.Add("name", match.Result("$2"))
.Add("url", match.Result("$1"))
);
}
if (ls.Count == 0)
{
Console.WriteLine("ls count is 0");
return;
}
CAR.DB.admin.Once().Inserts("table", new UAP.Data.DataTable(ls)); //入庫
這時候捕捉數(shù)據(jù)需要用到正則表達式做匹配處理,至于怎么用這里就不多說了。
題外話 爬取數(shù)據(jù)要注意的事項
- 注意爬取的時間間隔,避免被封IP或者導(dǎo)致別人的服務(wù)器奔潰;
- 用到正則爬取,最好把多余的空格換行去掉,方便寫正則匹配;
- 保存數(shù)據(jù)到庫里面的時候不要每條都操作dbinsert,最好一批dbinsert;
- 多些判斷驗證條件可以讓你思考問題更加嚴謹,從而形成習(xí)慣、積累經(jīng)驗;
- 爬取時盡量保存更多有用字段數(shù)據(jù)而不是局限于需求提出的字段這樣可以避免二次爬取的煩惱;
coding不難,用更多的時間思考問題,才能減少敲鍵盤的時間。

