本來(lái)想繼續(xù)寫Go方面的灼芭,不過由于五一節(jié)前收到需要爬取3個(gè)網(wǎng)站的一些數(shù)據(jù),那就剛好總結(jié)一下。文章講的都是很基本讓你大概知道爬蟲是個(gè)什么東西用來(lái)做什么的效诅,適合新手入門,之后有可能會(huì)逐步加深功能趟济,譬如多線程乱投,隊(duì)列,深網(wǎng)爬取顷编,反爬等篡腌。
一句話概括爬蟲
利用Http、Https協(xié)議模擬人操作將開放性的web傳輸內(nèi)容保存到本地中勾效。
爬蟲準(zhǔn)備
- 開發(fā)語(yǔ)言(這次用C#寫)
- 目標(biāo)數(shù)據(jù)
開始爬取案例一
這次需要爬取的是平行進(jìn)口車的數(shù)據(jù)-
分析網(wǎng)頁(yè)的數(shù)據(jù)來(lái)源
首先了解需求之后打開F12嘹悼,看到有好多數(shù)據(jù)請(qǐng)求會(huì)影響我們分析有用的數(shù)據(jù)來(lái)源,所以一般可以直接選擇XHR看接口层宫,這樣就可以篩走很多不需要的請(qǐng)求杨伙,最終定位到這個(gè)接口是我們所需要的。
- 代碼爬取
由于是工作匯總毁菱,所以這次就直接用內(nèi)部的類庫(kù)了米死,但是基本邏輯是一樣的(訪問請(qǐng)求地址,發(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; //請(qǐng)求接口并接收返回內(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); //入庫(kù)
這種是最簡(jiǎn)單的爬取接口直接返回json沒有做cookies驗(yàn)證或者sign之類的窗慎,所以基本上這就已經(jīng)完成一個(gè)爬取需求了物喷。
接下來(lái)案例二
第二個(gè)案例同樣是需要爬取車型數(shù)據(jù),至于有什么特殊我們接下來(lái)看step 2. 寫代碼利用webclient用get請(qǐng)求這個(gè)網(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)); //入庫(kù)
這時(shí)候捕捉數(shù)據(jù)需要用到正則表達(dá)式做匹配處理闸溃,至于怎么用這里就不多說(shuō)了整吆。
題外話 爬取數(shù)據(jù)要注意的事項(xiàng)
- 注意爬取的時(shí)間間隔,避免被封IP或者導(dǎo)致別人的服務(wù)器奔潰辉川;
- 用到正則爬取表蝙,最好把多余的空格換行去掉,方便寫正則匹配乓旗;
- 保存數(shù)據(jù)到庫(kù)里面的時(shí)候不要每條都操作dbinsert府蛇,最好一批dbinsert;
- 多些判斷驗(yàn)證條件可以讓你思考問題更加嚴(yán)謹(jǐn)屿愚,從而形成習(xí)慣汇跨、積累經(jīng)驗(yàn);
- 爬取時(shí)盡量保存更多有用字段數(shù)據(jù)而不是局限于需求提出的字段這樣可以避免二次爬取的煩惱妆距;
coding不難穷遂,用更多的時(shí)間思考問題,才能減少敲鍵盤的時(shí)間娱据。