㈠ 如何優雅地使用c語言編寫爬蟲
前言
大家在平時或多或少地都會有編寫網路爬蟲的需求。一般來說,編寫爬蟲的首選自然非python莫屬,除此之外,java等語言也是不錯的選擇。選擇上述語言的原因不僅僅在於它們均有非常不錯的網路請求庫和字元串處理庫,還在於基於上述語言的爬蟲框架非常之多和完善。良好的爬蟲框架可以確保爬蟲程序的穩定性,以及編寫程序的便捷性。所以,這個cspider爬蟲庫的使命在於,我們能夠使用c語言,依然能夠優雅地編寫爬蟲程序。
爬蟲的特性
配置方便。使用一句設置函數,即可定義user agent,cookie,timeout,proxy以及抓取線程和解析線程的最大數量。
程序邏輯獨立。用戶可以分別定義爬蟲的解析函數,和數據持久化函數。並且對於解析到的新url,用戶可以使用cspider提供的addUrl函數,將其加入到任務隊列中。
便捷的字元串處理。cspider中提供了基於pcre的簡單的正則表達式函數,基於libxml2的xpath解析函數,以及用於解析json的cJSON庫。
高效的抓取。cspider基於libuv調度抓取線程和解析線程,使用curl作為其網路請求庫。
使用cspider的步驟
獲取cspider_t。
自定義user agent,cookie,timeout,proxy以及抓取線程和解析線程的最大數量。
添加初始要抓取的url到任務隊列。
編寫解析函數和數據持久化函數。
啟動爬蟲。
例子
先來看下簡單的爬蟲例子,會在後面詳細講解例子。
#include<cspider/spider.h>
/*
自定義的解析函數,d為獲取到的html頁面字元串
*/
void p(cspider_t *cspider, char *d, void *user_data) {
char *get[100];
//xpath解析html
int size = xpath(d, "//body/div[@class='wrap']/div[@class='sort-column area']/div[@class='column-bd cfix']/ul[@class='st-list cfix']/li/strong/a", get, 100);
int i;
for (i = 0; i < size; i++) {
//將獲取到的電影名稱,持久化
saveString(cspider, get[i]);
}
}
/*
數據持久化函數,對上面解析函數中調用的saveString()函數傳入的數據,進行進一步的保存
*/
void s(void *str, void *user_data) {
char *get = (char *)str;
FILE *file = (FILE*)user_data;
fprintf(file, "%s\n", get);
return;
}
int main() {
//初始化spider
cspider_t *spider = init_cspider();
char *agent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:42.0) Gecko/20100101 Firefox/42.0";
//char *cookie = "bid=s3/yuH5Jd/I; ll=108288; viewed=1130500_24708145_6433169_4843567_1767120_5318823_1899158_1271597; __utma=30149280.927537245.1446813674.1446983217.1449139583.4; __utmz=30149280.1449139583.4.4.utmcsr=accounts.douban.com|utmccn=(referral)|utmcmd=referral|utmcct=/login; ps=y; ue=965166527@qq.com; dbcl2=58742090:QgZ2PSLiDLQ; ck=T9Wn; push_noty_num=0; push_doumail_num=7; ap=1; __utmb=30149280.0.10.1449139583; __utmc=30149280";
//設置要抓取頁面的url
cs_setopt_url(spider, "so.tv.sohu.com/list_p1100_p20_p3_u5185_u5730_p40_p5_p6_p77_p80_p9_2d1_p101_p11.html");
//設置user agent
cs_setopt_useragent(spider, agent);
//cs_setopt_cookie(spider, cookie);
//傳入解析函數和數據持久化函數的指針
cs_setopt_process(spider, p, NULL);
//s函數的user_data指針指向stdout
cs_setopt_save(spider, s, stdout);
//設置線程數量
cs_setopt_threadnum(spider, DOWNLOAD, 2);
cs_setopt_threadnum(spider, SAVE, 2);
//FILE *fp = fopen("log", "wb+");
//cs_setopt_logfile(spider, fp);
//開始爬蟲
return cs_run(spider);
}
例子講解
cspider_t *spider = init_cspider();獲取初始的cspider。cs_setopt_xxx這類函數可以用來進行初始化設置。其中要注意的是: cs_setopt_process(spider,p,NULL);與cs_setopt_save(spider,s,stdout);,它們分別設置了解析函數p和數據持久化函數s,這兩個函數需要用戶自己實現,還有用戶自定義的指向上下文信息user_data的指針。
在解析函數中,用戶要定義解析的規則,並對解析得到的字元串可以調用saveString進行持久化,或者是調用addUrl將url加入到任務隊列中。在saveString中傳入的字元串會在用戶自定義的數據持久函數中得到處理。此時,用戶可以選擇輸出到文件或資料庫等。
最後調用cs_run(spider)即可啟動爬蟲。
具體的API參數可在這里查看
總結
趕快使用cspider爬蟲框架來編寫爬蟲吧!如果在使用過程中發現bug,歡迎反饋。
望採納,謝謝
㈡ 我想學習網路爬蟲,哪位高手能給我發代碼c、C++都可以,先謝謝了。郵箱:[email protected]
C#特別適合於構造蜘蛛程序,這是因為它已經內置了HTTP和多線程的能力,而這兩種能力對於蜘蛛程序來說都是非常關鍵的。下面是構造一個蜘蛛程序要解決的關鍵問題:⑴ HTML分析:需要某種HTML解析器來分析蜘蛛程序遇到的每一個頁面。
⑵ 頁面處理:需要處理每一個下載得到的頁面。下載得到的內容可能要保存到磁碟,或者進一步分析處理。
⑶ 多線程:只有擁有多線程能力,蜘蛛程序才能真正做到高效。
⑷ 確定何時完成:不要小看這個問題,確定任務是否已經完成並不簡單,尤其是在多線程環境下。
一、HTML解析
提供的HTML解析器由ParseHTML類實現,使用非常方便:首先創建該類的一個實例,然後將它的Source屬性設置為要解析的HTML文檔:
以下是代碼片段:
ParseHTMLparse=newParseHTML();
parse.Source="HelloWorld";
接下來就可以利用循環來檢查HTML文檔包含的所有文本和標記。通常,檢查過程可以從一個測試Eof方法的while循環開始:
以下是代碼片段:
while(!parse.Eof())
{
charch=parse.Parse();
Parse方法將返回HTML文檔包含的字元它返回的內容只包含那些非HTML標記的字元,如果遇到了HTML標記,Parse方法將返回0值,表示現在遇到了一個HTML標記。遇到一個標記之後,我們可以用GetTag()方法來處理它。
以下是代碼片段:
if(ch==0)
{
HTMLTagtag=parse.GetTag();
}
一般地,蜘蛛程序最重要的任務之一就是找出各個HREF屬性,這可以藉助C#的索引功能完成。例如,下面的代碼將提取出HREF屬性的值(如果存在的話)。
以下是代碼片段:
Attributehref=tag["HREF"];
stringlink=href.Value;
獲得Attribute對象之後,通過Attribute.Value可以得到該屬性的值。
二、處理HTML頁面
下面來看看如何處理HTML頁面。首先要做的當然是下載HTML頁面,這可以通過C#提供的HttpWebRequest類實現:
以下是代碼片段:
HttpWebRequestrequest=(HttpWebRequest)WebRequest.Create(m_uri);
response=request.GetResponse();
stream=response.GetResponseStream();
接下來我們就從request創建一個stream流。在執行其他處理之前,我們要先確定該文件是二進制文件還是文本文件,不同的文件類型處理方式也不同。下面的代碼確定該文件是否為二進制文件。
以下是代碼片段:
if(!response.ContentType.ToLower().StartsWith("text/"))
{
SaveBinaryFile(response);
returnnull;
}
stringbuffer="",line;
如果該文件不是文本文件,我們將它作為二進制文件讀入。如果是文本文件,首先從stream創建一個StreamReader,然後將文本文件的內容一行一行加入緩沖區。
以下是代碼片段:
reader=newStreamReader(stream);
while((line=reader.ReadLine())!=null)
{
buffer+=line+"rn";
}
裝入整個文件之後,接著就要把它保存為文本文件。
以下是代碼片段:
SaveTextFile(buffer);
下面來看看這兩類不同文件的存儲方式。
二進制文件的內容類型聲明不以"text/"開頭,蜘蛛程序直接把二進制文件保存到磁碟,不必進行額外的處理,這是因為二進制文件不包含HTML,因此也不會再有需要蜘蛛程序處理的HTML。下面是寫入二進制文件的步驟。
首先准備一個緩沖區臨時地保存二進制文件的內容。
以下是代碼片段:
byte[]buffer=newbyte[1024];
接下來要確定文件保存到本地的路徑和名稱。如果要把一個myhost.com網站的內容下載到本地的c:test文件夾,二進制文件的網上路徑和名稱是,則本地路徑和名稱應當是c:testimageslogo.gif。與此同時,我們還要確保c:test目錄下已經創建了images子目錄。這部分任務由convertFilename方法完成。
以下是代碼片段:
stringfilename=convertFilename(response.ResponseUri);
convertFilename方法分離HTTP地址,創建相應的目錄結構。確定了輸出文件的名字和路徑之後就可以打開讀取Web頁面的輸入流、寫入本地文件的輸出流。
以下是代碼片段:
StreamoutStream=File.Create(filename);
StreaminStream=response.GetResponseStream();
接下來就可以讀取Web文件的內容並寫入到本地文件,這可以通過一個循環方便地完成。
以下是代碼片段:
intl;
do
{
l=inStream.Read(buffer,0,
buffer.Length);
if(l>0)
outStream.Write(buffer,0,l);
}
while(l>0);
三、多線程
我們用DocumentWorker類封裝所有下載一個URL的操作。每當一個DocumentWorker的實例被創建,它就進入循環,等待下一個要處理的URL。下面是DocumentWorker的主循環:
以下是代碼片段:
while(!m_spider.Quit)
{
m_uri=m_spider.ObtainWork();
m_spider.SpiderDone.WorkerBegin();
stringpage=GetPage();
if(page!=null)
ProcessPage(page);
m_spider.SpiderDone.WorkerEnd();
}
這個循環將一直運行,直至Quit標記被設置成了true(當用戶"Cancel"按鈕時,Quit標記就被設置成true)。在循環之內,我們調用ObtainWork獲取一個URL。ObtainWork將一直等待,直到有一個URL可用這要由其他線程解析文檔並尋找才能獲得。Done類利用WorkerBegin和WorkerEnd方法來確定何時整個下載操作已經完成。
從圖一可以看出,蜘蛛程序允許用戶自己確定要使用的線程數量。在實踐中,線程的最佳數量受許多因素影響。如果你的機器性能較高,或者有兩個處理器,可以設置較多的線程數量;反之,如果網路帶寬、機器性能有限,設置太多的線程數量其實不一定能夠提高性能。
四、任務完成了嗎?
利用多個線程同時下載文件有效地提高了性能,但也帶來了線程管理方面的問題。其中最復雜的一個問題是:蜘蛛程序何時才算完成了工作?在這里我們要藉助一個專用的類Done來判斷。
首先有必要說明一下"完成工作"的具體含義。只有當系統中不存在等待下載的URL,而且所有工作線程都已經結束其處理工作時,蜘蛛程序的工作才算完成。也就是說,完成工作意味著已經沒有等待下載和正在下載的URL。
Done類提供了一個WaitDone方法,它的功能是一直等待,直到Done對象檢測到蜘蛛程序已完成工作。下面是WaitDone方法的代碼。
以下是代碼片段:
publicvoidWaitDone()
{
Monitor.Enter(this);
while(m_activeThreads>0)
{
Monitor.Wait(this);
}
Monitor.Exit(this);
}
WaitDone方法將一直等待,直到不再有活動的線程。但必須注意的是,下載開始的最初階段也沒有任何活動的線程,所以很容易造成蜘蛛程序一開始就立即停止的現象。為解決這個問題,我們還需要另一個方法WaitBegin來等待蜘蛛程序進入"正式的"工作階段。一般的調用次序是:先調用WaitBegin,再接著調用WaitDone,WaitDone將等待蜘蛛程序完成工作。下面是WaitBegin的代碼:
以下是代碼片段:
publicvoidWaitBegin()
{
Monitor.Enter(this);
while(!m_started)
{
Monitor.Wait(this);
}
Monitor.Exit(this);
在《爬蟲/蜘蛛程序的製作(C#語言)》一文中,已經介紹了爬蟲程序實現的基本方法,可以說,已經實現了爬蟲的功能。只是它存在一個效率問題,下載速度可能很慢。這是兩方面的原因造成的:
1.分析和下載不能同步進行。在《爬蟲/蜘蛛程序的製作(C#語言)》中已經介紹了爬蟲程序的兩個步驟:分析和下載。在單線程的程序中,兩者是無法 同時進行的。也就是說,分析時會造成網路空閑,分析的時間越長,下載的效率越低。反之也是一樣,下載時無法同時進行分析,只有停下下載後才能進行下一步的 分析。問題浮出水面,我想大家都會想到:把分析和下載用不同的線程進行,問題不就解決了嗎?
2.只是單線程下載。相信大家都有用過網際快車等下載資源的經歷,它裡面是可以設置線程數的(近年版本默認是10,曾經默認是5)。它會將文件分成 與線程數相同的部分,然後每個線程下載自己的那一部分,這樣下載效率就有可能提高。相信大家都有加多線程數,提升下載效率的經歷。但細心的用戶會發現,在 帶寬一定的情況下,並不是線程越多,速度越快,而是在某一點達到峰值。爬蟲作為特殊的下載工具,不具備多線程的能力何以有效率可談?爬蟲在信息時代的目 的,難道不是快速獲取信息嗎?所以,爬蟲需要有多線程(可控數量)同時下載網頁。
好了,認識、分析完問題,就是解決問題了:
多線程在C#中並不難實現。它有一個命名空間:System.Threading,提供了多線程的支持。
要開啟一個新線程,需要以下的初始化:
ThreadStart startDownload = new ThreadStart( DownLoad );
//線程起始設置:即每個線程都執行DownLoad(),注意:DownLoad()必須為不帶有參數的方法
Thread downloadThread = new Thread( startDownload ); //實例化要開啟的新類
downloadThread.Start();//開啟線程
由於線程起始時啟動的方法不能帶有參數,這就為多線程共享資源添加了麻煩。不過我們可以用類級變數(當然也可以使用其它方法,筆者認為此方法最簡單易用)來解決這個問題。知道開啟多線程下載的方法後,大家可能會產生幾個疑問:
1.如何控制線程的數量?
2.如何防止多線程下載同一網頁?
3.如何判斷線程結束?
4.如何控制線程結束?
下面就這幾個問題提出解決方法:
1.線程數量我們可以通過for循環來實現,就如同當年初學編程的打點程序一樣。
比如已知用戶指定了n(它是一個int型變數)個線程吧,可以用如下方法開啟五個線程。
Thread[] downloadThread;
//聲名下載線程,這是C#的優勢,即數組初始化時,不需要指定其長度,可以在使用時才指定。
這個聲名應為類級,這樣也就為其它方法控制項它們提供了可能
ThreadStart startDownload = new ThreadStart( DownLoad );
//線程起始設置:即每個線程都執行DownLoad()
downloadThread = new Thread[ n ];//為線程申請資源,確定線程總數
for( int i = 0; i < n; i++ )//開啟指定數量的線程數
{
downloadThread[i] = new Thread( startDownload );//指定線程起始設置
downloadThread[i].Start();//逐個開啟線程
}
好了,實現控制開啟線程數是不是很簡單啊?
2.下面出現的一個問題:所有的線程都調用DonwLoad()方法,這樣如何避免它們同時下載同一個網頁呢?
這個問題也好解決,只要建立一下Url地址表,表中的每個地址只允許被一個線程申請即可。具體實現:
可以利用資料庫,建立一個表,表中有四列,其中一列專門用於存儲Url地址,另外兩列分別存放地址對應的線程以及該地址被申請的次數,最後一列存放 下載的內容。(當然,對應線程一列不是必要的)。當有線程申請後,將對應線程一列設定為當前線程編號,並將是否申請過一列設置為申請一次,這樣,別的線程 就無法申請該頁。如果下載成功,則將內容存入內容列。如果不成功,內容列仍為空,作為是否再次下載的依據之一,如果反復不成功,則進程將於達到重試次數 (對應該地址被申請的次數,用戶可設)後,申請下一個Url地址。主要的代碼如下(以VFP為例):
<建立表>
CREATE TABLE (ctablename) ( curl M , ctext M , ldowned I , threadNum I )
&&建立一個表ctablename.dbf,含有地址、文本內容、已經嘗試下載次數、
線程標志(初值為-1,線程標志是從0開始的整數)四個欄位
<提取Url地址>
cfullname = (ctablename) + '.dbf'&&為表添加擴展名
USE (cfullname)
GO TOP
LOCATE FOR (EMPTY( ALLTRIM( ctext ) ) AND ldowned < 2 AND
( threadNum = thisNum OR threadNum = - 1) )
&&查找尚未下載成功且應下載的屬於本線程許可權的Url地址,thisNum是當前線程的編號,
可以通過參數傳遞得到
gotUrl = curl
recNum = RECNO()
IF recNum <= RECCOUNT() THEN &&如果在列表中找到這樣的Url地址
UPDATE (cfullname) SET ldowned = ( ldowned + 1 ) , threadNum =
thisNum WHERE RECNO() = recNum &&更新表,將此記錄更新為已申請,即下載次數加1,
線程標志列設為本線程的編號。
<下載內容>
cfulltablename = (ctablename) + '.dbf'
USE (cfulltablename)
SET EXACT ON
LOCATE FOR curl = (csiteurl) && csiteurl是參數,為下載到的內容所對應的Url地址
recNumNow = RECNO()&&得到含有此地址的記錄號
UPDATE (cfulltablename) SET ctext = (ccontent) WHERE RECNO() =
recNumNow &&插入對應地址的對應內容
<插入新地址>
ctablename = (ctablename) + '.dbf'
USE (ctablename)
GO TOP
SET EXACT ON
LOCATE FOR curl = (cnewurl) &&查找有無此地址
IF RECNO() > RECCOUNT() THEN &&如果尚無此地址
SET CARRY OFF
INSERT INTO (ctablename) ( curl , ctext , ldowned , threadNum )
VALUES ( (cnewurl) , "" , 0 , -1 ) &&將主頁地址添加到列表
好了,這樣就解決了多線程中,線程沖突。當然,去重問題也可以在C#語言內解決,只根建立一個臨時文件(文本就可以),保存所有的Url地址,差對它們設置相應的屬性即可,但查找效率可能不及資料庫快。
共2頁
3.線程結束是很難判斷的,因為它總是在查找新的鏈接。用者認為可以假設:線程重復N次以後還是沒有能申請到新的Url地址,那麼可以認為它已經下載完了所有鏈接。主要代碼如下:
string url = "";
int times = 0;
while ( url == "" )//如果沒有找到符合條件的記錄,則不斷地尋找符合條件的記錄
{
url = getUrl.GetAUrl( …… );//調用GetAUrl方法,試圖得到一個url值
if ( url == "" )//如果沒有找到
{
times ++;//嘗試次數自增
continue; //進行下一次嘗試
}
if ( times > N ) //如果已經嘗試夠了次數,則退出進程
{
downloadThread[i].Abort; //退出進程
}
else//如果沒有嘗試夠次數
{
Times = 0; //嘗試次數歸零處理
}
//進行下一步針對得到的Url的處理
}
4.這個問題相對簡單,因為在問題一中已經建議,將線程聲名為類級數組,這樣就很易於控制。只要用一個for循環即可結束。代碼如下:
for( int i = 0; i < n; i++ )//關閉指定數量n的線程數
{
downloadThread[i].Abort();//逐個關閉線程
}
好了,一個蜘蛛程序就這樣完成了,在C#面前,它的實現原來如此簡單。
這里筆者還想提醒讀者:筆者只是提供了一個思路及一個可以實現的解決方案,但它並不是最佳的,即使這個方案本身,也有好多可以改進的地方,留給讀者思考。
最後說明一下我所使用的環境:
winXP sp2 Pro
VFP 9.0
Visual Studio 2003 .net中文企業版
㈢ C#編寫爬蟲程序速度怎麼樣呢,更C比
c#開發網路爬蟲還是可以的,但是如果用來開發搜索引擎就可能不是很好啦... 本人買過一個本書《使用C#開發搜索引擎》 清華大學出版社 作者:羅剛
㈣ 為什麼c語言不適合寫爬蟲
開發效率低
㈤ 我想用c編寫一個爬蟲程序,可是看完一本c語言教程後,還是覺得只會編寫一些計算類的小代碼,要學會編寫
只用c語言,只能做一些計算類小題
必須結合其他庫才能擴展其強大的功能
推薦一個:qt
網路一下你就知道了
㈥ 怎麼在DOS下用C語言寫網路爬蟲
獲取cspider_t。
自定義user agent,cookie,timeout,proxy以及抓取線程和解析線程的最大數量。
添加初始要抓取的url到任務隊列。
編寫解析函數和數據持久化函數。
啟動爬蟲。
例子
先來看下簡單的爬蟲例子,會在後面詳細講解例子。
㈦ 網路爬蟲是什麼
網路爬蟲又稱網路蜘蛛、網路機器人,它是一種按照一定的規則自動瀏覽、檢索網頁信息的程序或者腳本。網路爬蟲能夠自動請求網頁,並將所需要的數據抓取下來。通過對抓取的數據進行處理,從而提取出有價值的信息。
我們所熟悉的一系列搜索引擎都是大型的網路爬蟲,比如網路、搜狗、360瀏覽器、谷歌搜索等等。每個搜索引擎都擁有自己的爬蟲程序,比如360瀏覽器的爬蟲稱作360Spider,搜狗的爬蟲叫做Sogouspider。
網路搜索引擎,其實可以更形象地稱之為網路蜘蛛(Baispider),它每天會在海量的互聯網信息中爬取優質的信息,並進行收錄。當用戶通過網路檢索關鍵詞時,網路首先會對用戶輸入的關鍵詞進行分析,然後從收錄的網頁中找出相關的網頁,並按照排名規則對網頁進行排序,最後將排序後的結果呈現給用戶。在這個過程中網路蜘蛛起到了非常想關鍵的作用。
網路的工程師們為「網路蜘蛛」編寫了相應的爬蟲演算法,通過應用這些演算法使得「網路蜘蛛」可以實現相應搜索策略,比如篩除重復網頁、篩選優質網頁等等。應用不同的演算法,爬蟲的運行效率,以及爬取結果都會有所差異。
爬蟲可分為三大類:通用網路爬蟲、聚焦網路爬蟲、增量式網路爬蟲。
通用網路爬蟲:是搜索引擎的重要組成部分,上面已經進行了介紹,這里就不再贅述。通用網路爬蟲需要遵守robots協議,網站通過此協議告訴搜索引擎哪些頁面可以抓取,哪些頁面不允許抓取。
robots協議:是一種「約定俗稱」的協議,並不具備法律效力,它體現了互聯網人的「契約精神」。行業從業者會自覺遵守該協議,因此它又被稱為「君子協議」。
聚焦網路爬蟲:是面向特定需求的一種網路爬蟲程序。它與通用爬蟲的區別在於,聚焦爬蟲在實施網頁抓取的時候會對網頁內容進行篩選和處理,盡量保證只抓取與需求相關的網頁信息。聚焦網路爬蟲極大地節省了硬體和網路資源,由於保存的頁面數量少所以更新速度很快,這也很好地滿足一些特定人群對特定領域信息的需求。
增量式網路爬蟲:是指對已下載網頁採取增量式更新,它是一種只爬取新產生的或者已經發生變化網頁的爬蟲程序,能夠在一定程度上保證所爬取的頁面是最新的頁面。
隨著網路的迅速發展,萬維網成為大量信息的載體,如何有效地提取並利用這些信息成為一個巨大的挑戰,因此爬蟲應運而生,它不僅能夠被使用在搜索引擎領域,而且在大數據分析,以及商業領域都得到了大規模的應用。
1)數據分析
在數據分析領域,網路爬蟲通常是搜集海量數據的必備工具。對於數據分析師而言,要進行數據分析,首先要有數據源,而學習爬蟲,就可以獲取更多的數據源。在採集過程中,數據分析師可以按照自己目的去採集更有價值的數據,而過濾掉那些無效的數據。
2)商業領域
對於企業而言,及時地獲取市場動態、產品信息至關重要。企業可以通過第三方平台購買數據,比如貴陽大數據交易所、數據堂等,當然如果貴公司有一個爬蟲工程師的話,就可通過爬蟲的方式取得想要的信息。
爬蟲是一把雙刃劍,它給我們帶來便利的同時,也給網路安全帶來了隱患。有些不法分子利用爬蟲在網路上非法搜集網民信息,或者利用爬蟲惡意攻擊他人網站,從而導致網站癱瘓的嚴重後果。關於爬蟲的如何合法使用,推薦閱讀《中華人民共和國網路安全法》。
為了限制爬蟲帶來的危險,大多數網站都有良好的反爬措施,並通過robots.txt協議做了進一步說明,下面是淘寶網robots.txt的內容:
從協議內容可以看出,淘寶網對不能被抓取的頁面做了規定。因此大家在使用爬蟲的時候,要自覺遵守robots協議,不要非法獲取他人信息,或者做一些危害他人網站的事情。
首先您應該明確,不止Python這一種語言可以做爬蟲,諸如PHP、Java、C/C++都可以用來寫爬蟲程序,但是相比較而言Python做爬蟲是最簡單的。下面對它們的優劣勢做簡單對比:
PHP:對多線程、非同步支持不是很好,並發處理能力較弱;Java也經常用來寫爬蟲程序,但是Java語言本身很笨重,代碼量很大,因此它對於初學者而言,入門的門檻較高;C/C++運行效率雖然很高,但是學習和開發成本高。寫一個小型的爬蟲程序就可能花費很長的時間。
而Python語言,其語法優美、代碼簡潔、開發效率高、支持多個爬蟲模塊,比如urllib、requests、Bs4等。Python的請求模塊和解析模塊豐富成熟,並且還提供了強大的Scrapy框架,讓編寫爬蟲程序變得更為簡單。因此使用Python編寫爬蟲程序是個非常不錯的選擇。
爬蟲程序與其他程序不同,它的的思維邏輯一般都是相似的,所以無需我們在邏輯方面花費大量的時間。下面對Python編寫爬蟲程序的流程做簡單地說明:
先由urllib模塊的request方法打開URL得到網頁HTML對象。
使用瀏覽器打開網頁源代碼分析網頁結構以及元素節點。
通過BeautifulSoup或則正則表達式提取數據。
存儲數據到本地磁碟或資料庫。
當然也不局限於上述一種流程。編寫爬蟲程序,需要您具備較好的Python編程功底,這樣在編寫的過程中您才會得心應手。爬蟲程序需要盡量偽裝成人訪問網站的樣子,而非機器訪問,否則就會被網站的反爬策略限制,甚至直接封殺IP,相關知識會在後續內容介紹。
開課吧廣場-人才學習交流平台