從爬蟲必要的幾個基本需求來講:
1.抓取
py的urllib不一定去用,但是要學(xué),如果還沒用過的話。
比較好的替代品有requests等第三方更人性化、成熟的庫,如果pyer不了解各種庫,那就白學(xué)了。
抓取最基本就是拉網(wǎng)頁回來。
如果深入做下去,會發(fā)現(xiàn)要面對不同的網(wǎng)頁要求,比如有認(rèn)證的,不同文件格式、編碼處理,各種奇怪的url合規(guī)化處理、重復(fù)抓取問題、cookies跟隨問題、多線程多進程抓取、多節(jié)點抓取、抓取調(diào)度、資源壓縮等一系列問題。
所以第一步就是拉網(wǎng)頁回來,慢慢會發(fā)現(xiàn)各種問題待優(yōu)化。
2.存儲
抓回來一般會用一定策略存下來,而不是直接分析,個人覺得更好的架構(gòu)應(yīng)該是把分析和抓取分離,更加松散,每個環(huán)節(jié)出了問題能夠隔離另外一個環(huán)節(jié)可能出現(xiàn)的問題,好排查也好更新發(fā)布。
那么存文件系統(tǒng)、SQLorNOSQL數(shù)據(jù)庫、內(nèi)存數(shù)據(jù)庫,如何去存就是這個環(huán)節(jié)的重點。
可以選擇存文件系統(tǒng)開始,然后以一定規(guī)則命名。
3.分析
對網(wǎng)頁進行文本分析,提取鏈接也好,提取正文也好,總之看的需求,但是一定要做的就是分析鏈接了。
可以用認(rèn)為最快最優(yōu)的辦法,比如正則表達(dá)式。
然后將分析后的結(jié)果應(yīng)用與其他環(huán)節(jié):)
4.展示
要是做了一堆事情,一點展示輸出都沒有,如何展現(xiàn)價值。
所以找到好的展示組件,去show出肌肉也是關(guān)鍵。
如果為了做個站去寫爬蟲,抑或要分析某個東西的數(shù)據(jù),都不要忘了這個環(huán)節(jié),更好地把結(jié)果展示出來給別人感受。
“入門”是良好的動機,但是可能作用緩慢。如果你手里或者腦子里有一個項目,那么實踐起來你會被目標(biāo)驅(qū)動,而不會像學(xué)習(xí)模塊一樣慢慢學(xué)習(xí)。另外如果說知識體系里的每一個知識點是圖里的點,依賴關(guān)系是邊的話,那么這個圖一定不是一個有向無環(huán)圖。因為學(xué)習(xí)A的經(jīng)驗可以幫助你學(xué)習(xí)B。因此,你不需要學(xué)習(xí)怎么樣“入門”,因為這樣的“入門”點根本不存在!你需要學(xué)習(xí)的是怎么樣做一個比較大的東西,在這個過程中,你會很快地學(xué)會需要學(xué)會的東西的。當(dāng)然,你可以爭論說需要先懂python,不然怎么學(xué)會python做爬蟲呢?但是事實上,你完全可以在做這個爬蟲的過程中學(xué)習(xí)python :D看到前面很多答案都講的“術(shù)”——用什么軟件怎么爬,那我就講講“道”和“術(shù)”吧——爬蟲怎么工作以及怎么在python實現(xiàn)。先長話短說summarize一下:你需要學(xué)習(xí)基本的爬蟲工作原理基本的http抓取工具,scrapyBloom Filter: Bloom Filters by Example如果需要大規(guī)模網(wǎng)頁抓取,你需要學(xué)習(xí)分布式爬蟲的概念。其實沒那么玄乎,你只要學(xué)會怎樣維護一個所有集群機器能夠有效分享的分布式隊列就好。最簡單的實現(xiàn)是python-rq: https://github.com/nvie/rqrq和Scrapy的結(jié)合:darkrho/scrapy-redis · GitHub后續(xù)處理,網(wǎng)頁析取(grangier/python-goose · GitHub),存儲(Mongodb)以下是短話長說:說說當(dāng)初寫的一個集群爬下整個豆瓣的經(jīng)驗吧。1)首先你要明白爬蟲怎樣工作。想象你是一只蜘蛛,現(xiàn)在你被放到了互聯(lián)“網(wǎng)”上。那么,你需要把所有的網(wǎng)頁都看一遍。怎么辦呢?沒問題呀,你就隨便從某個地方開始,比如說人民日報的首頁,這個叫initial pages,用$表示吧。在人民日報的首頁,你看到那個頁面引向的各種鏈接。于是你很開心地從爬到了“國內(nèi)新聞”那個頁面。太好了,這樣你就已經(jīng)爬完了倆頁面(首頁和國內(nèi)新聞)!暫且不用管爬下來的頁面怎么處理的,你就想象你把這個頁面完完整整抄成了個html放到了你身上。突然你發(fā)現(xiàn), 在國內(nèi)新聞這個頁面上,有一個鏈接鏈回“首頁”。作為一只聰明的蜘蛛,你肯定知道你不用爬回去的吧,因為你已經(jīng)看過了啊。所以,你需要用你的腦子,存下你已經(jīng)看過的頁面地址。這樣,每次看到一個可能需要爬的新鏈接,你就先查查你腦子里是不是已經(jīng)去過這個頁面地址。如果去過,那就別去了。好的,理論上如果所有的頁面可以從initial page達(dá)到的話,那么可以證明你一定可以爬完所有的網(wǎng)頁。那么在python里怎么實現(xiàn)呢?很簡單import Queue
initial_page = "http://www.renminribao.com"
url_queue = Queue.Queue()
seen = set()
seen.insert(initial_page)
url_queue.put(initial_page)
while(True): #一直進行直到??菔癄€
if url_queue.size()>0:
current_url = url_queue.get()? ? #拿出隊例中第一個的url
store(current_url)? ? ? ? ? ? ? #把這個url代表的網(wǎng)頁存儲好
for next_url in extract_urls(current_url): #提取把這個url里鏈向的url
if next_url not in seen:
seen.put(next_url)
url_queue.put(next_url)
else:
break
寫得已經(jīng)很偽代碼了。所有的爬蟲的backbone都在這里,下面分析一下為什么爬蟲事實上是個非常復(fù)雜的東西——搜索引擎公司通常有一整個團隊來維護和開發(fā)。2)效率如果你直接加工一下上面的代碼直接運行的話,你需要一整年才能爬下整個豆瓣的內(nèi)容。更別說Google這樣的搜索引擎需要爬下全網(wǎng)的內(nèi)容了。問題出在哪呢?需要爬的網(wǎng)頁實在太多太多了,而上面的代碼太慢太慢了。設(shè)想全網(wǎng)有N個網(wǎng)站,那么分析一下判重的復(fù)雜度就是N*log(N),因為所有網(wǎng)頁要遍歷一次,而每次判重用set的話需要log(N)的復(fù)雜度。OK,OK,我知道python的set實現(xiàn)是hash——不過這樣還是太慢了,至少內(nèi)存使用效率不高。通常的判重做法是怎樣呢?Bloom Filter. 簡單講它仍然是一種hash的方法,但是它的特點是,它可以使用固定的內(nèi)存(不隨url的數(shù)量而增長)以O(shè)(1)的效率判定url是否已經(jīng)在set中??上煜聸]有白吃的午餐,它的唯一問題在于,如果這個url不在set中,BF可以100%確定這個url沒有看過。但是如果這個url在set中,它會告訴你:這個url應(yīng)該已經(jīng)出現(xiàn)過,不過我有2%的不確定性。注意這里的不確定性在你分配的內(nèi)存足夠大的時候,可以變得很小很少。一個簡單的教程:Bloom Filters by Example注意到這個特點,url如果被看過,那么可能以小概率重復(fù)看一看(沒關(guān)系,多看看不會累死)。但是如果沒被看過,一定會被看一下(這個很重要,不然我們就要漏掉一些網(wǎng)頁了?。?。 [IMPORTANT: 此段有問題,請暫時略過]好,現(xiàn)在已經(jīng)接近處理判重最快的方法了。另外一個瓶頸——你只有一臺機器。不管你的帶寬有多大,只要你的機器下載網(wǎng)頁的速度是瓶頸的話,那么你只有加快這個速度。用一臺機子不夠的話——用很多臺吧!當(dāng)然,我們假設(shè)每臺機子都已經(jīng)進了最大的效率——使用多線程(python的話,多進程吧)。3)集群化抓取爬取豆瓣的時候,我總共用了100多臺機器晝夜不停地運行了一個月。想象如果只用一臺機子你就得運行100個月了...那么,假設(shè)你現(xiàn)在有100臺機器可以用,怎么用python實現(xiàn)一個分布式的爬取算法呢?我們把這100臺中的99臺運算能力較小的機器叫作slave,另外一臺較大的機器叫作master,那么回顧上面代碼中的url_queue,如果我們能把這個queue放到這臺master機器上,所有的slave都可以通過網(wǎng)絡(luò)跟master聯(lián)通,每當(dāng)一個slave完成下載一個網(wǎng)頁,就向master請求一個新的網(wǎng)頁來抓取。而每次slave新抓到一個網(wǎng)頁,就把這個網(wǎng)頁上所有的鏈接送到master的queue里去。同樣,bloom filter也放到master上,但是現(xiàn)在master只發(fā)送確定沒有被訪問過的url給slave。Bloom Filter放到master的內(nèi)存里,而被訪問過的url放到運行在master上的Redis里,這樣保證所有操作都是O(1)。(至少平攤是O(1),Redis的訪問效率見:LINSERT – Redis)考慮如何用python實現(xiàn):在各臺slave上裝好scrapy,那么各臺機子就變成了一臺有抓取能力的slave,在master上裝好Redis和rq用作分布式隊列。代碼于是寫成#slave.py
current_url = request_from_master()
to_send = []
for next_url in extract_urls(current_url):
to_send.append(next_url)
store(current_url);
send_to_master(to_send)
#master.py
distributed_queue = DistributedQueue()
bf = BloomFilter()
initial_pages = "www.renmingribao.com"
while(True):
if request == 'GET':
if distributed_queue.size()>0:
send(distributed_queue.get())
else:
break
elif request == 'POST':
bf.put(request.url)
好的,其實你能想到,有人已經(jīng)給你寫好了你需要的:darkrho/scrapy-redis · GitHub4)展望及后處理雖然上面用很多“簡單”,但是真正要實現(xiàn)一個商業(yè)規(guī)??捎玫呐老x并不是一件容易的事。上面的代碼用來爬一個整體的網(wǎng)站幾乎沒有太大的問題。但是如果附加上你需要這些后續(xù)處理,比如有效地存儲(數(shù)據(jù)庫應(yīng)該怎樣安排)有效地判重(這里指網(wǎng)頁判重,咱可不想把人民日報和抄襲它的大民日報都爬一遍)有效地信息抽?。ū热缭趺礃映槿〕鼍W(wǎng)頁上所有的地址抽取出來,“朝陽區(qū)奮進路中華道”),搜索引擎通常不需要存儲所有的信息,比如圖片我存來干嘛...及時更新(預(yù)測這個網(wǎng)頁多久會更新一次)如你所想,這里每一個點都可以供很多研究者十?dāng)?shù)年的研究。雖然如此,“路漫漫其修遠(yuǎn)兮,吾將上下而求索”。所以,不要問怎么入門,直接上路就好了:)
最后“
自己多問下為什么學(xué)python”
如果一門語言沒有改變你的編程思維,那么它不值得你去學(xué)習(xí)”。如果這么說,我們大學(xué)的時候,學(xué)習(xí)了c,c++,java,C#,算是值得學(xué)習(xí)么?很多時候是不值得,我覺得我們大學(xué)的課程就是用java,c#,c++把"C程序設(shè)計"又上了一遍.
這是因為,學(xué)校的老師會C和java之類的,所以要跟著規(guī)矩開這門課,(這也就是為什么,許多學(xué)校還在教vb,),這也就是為什么,你所以為的一樣就是大家都有For都有while,都有switch..都有Class...都有int 都有float,所謂的不一樣就是用C有指針,java沒有,這就是為什么教育是失敗的,這也就是為什么,我目前認(rèn)識的幾個編程大牛
python的優(yōu)點:簡單 我所說的簡單,是相比于象C和C++這樣的語言,你為了編程,要學(xué)習(xí)許多偏底層的東西.在比如,你在學(xué)習(xí)一個新的編程范式,或者想要馬上做個例子看看,試驗?zāi)硞€API,如果你是寫java的,你不得不去寫一個main,寫一些構(gòu)造,即使有IDE這樣的東西,能夠為你帶來代碼生成器,而我做得就是寫一段“腳本”,或者打開python交互式解釋器就行了。
自己認(rèn)識的python朋友出去工作,工資比較高,然后自己又剛剛好是會python所以選擇學(xué)習(xí)python,這樣的人比較危險但是也比較有激勵,還有就是覺得python比其他開發(fā)語言好用。
學(xué)完python前景會咋樣
其實我個人是很看好python未來的就業(yè)前景的,因為我認(rèn)識太多的工程師都已經(jīng)在學(xué)python,很多都是月收入大幾萬的
我個人也并非一直用python。前些年主要用c/c++以及java開發(fā)一些通信,移動系統(tǒng),互聯(lián)網(wǎng)通信。近3年開始才轉(zhuǎn)向python。坦白的說,這可能與你相處的公司以及環(huán)境不大一樣。隨便舉個例子,google的protocol buffer協(xié)議一出來就具有c++/python/java三種語言支持。google的廣告系統(tǒng)早在03,04年左右就一并對python進行了webservice支持,大部分涉及基礎(chǔ)核心系統(tǒng)的公司,都開始對python進行了擴展支持。甚至開源社區(qū)的postgresql數(shù)據(jù)庫,除了自身的ansi SQL,pgsql,pg/TCL,PG/PERL之外對python進行了內(nèi)嵌支持,唯獨卻沒有呼聲很高的java。在FREEBSD(MIT)/LINUX(GPL)平臺上,對java可能排斥性比較大,但綜合而言,目前python發(fā)展還沒有java那種普及,主要是python大部分工作仍然是在較為深入地系統(tǒng)層和框架層做設(shè)計開發(fā),例如django,SQLAlchemy,fail2ban,mail郵件系統(tǒng),twisted等等。這部分對于那種習(xí)慣應(yīng)用前輩們框架的編碼人員而言,缺乏創(chuàng)造力的他們根本無法適用這種開發(fā)。尤其在python涉及一些系統(tǒng)層面需要有較強的c/c++能力,這部分人在國內(nèi)要么就累得要死沒時間,要么就啥都不會就會拷貝代碼,而國內(nèi)公司也鮮有主動去做這部分基礎(chǔ)勞動的,大多都是等別人做好了在直接拿來用,所以造就了任何技術(shù)性的東西出來,國內(nèi)都是先等等看,然后抄襲應(yīng)用。
大環(huán)境如此,但千萬誤認(rèn)為先等等看吧。對于一個技術(shù)人員而言,缺乏對新技術(shù)的渴望與熱情,這是一種非常危險的事情。我工作8年了,按照國內(nèi)很多的人的說法早已不做代碼了,但又一次在聽一個老外的演講,他說他50多歲仍然每天堅持寫代碼,了解最新的動態(tài),所以他才能做到他們公司的首席科學(xué)家,因此它才能時刻指導(dǎo)項目團隊前進并保證項目的質(zhì)量。他坦言對于一個不寫代碼并且不了解最新的技術(shù)動態(tài)的技術(shù)人員或者技術(shù)團隊的負(fù)責(zé)人而言,這種團隊也就足夠做作小項目,一旦壓力和項目過大,就會有很多問題漏出來。
對于新人而言,無論學(xué)習(xí)什么技術(shù),都要以鼓勵的姿態(tài)出現(xiàn)。太多用薪水和你個人所看到的現(xiàn)狀去衡量一門技術(shù),那絕對是欠缺眼光的。任何一門技術(shù),一旦有人學(xué)習(xí),他有可能逐漸成為這個領(lǐng)域的專家,即便再濫再沒有人用的開發(fā)語言技術(shù),他也有可能就是明日的奠基者或者大師。
自己如何確定目標(biāo)
在生活中學(xué)會不斷挖掘自己的潛力。我們都是一個普通人,可能并不清楚自己到底在哪方面占有優(yōu)勢。所以,學(xué)著在生活中找到自己的優(yōu)勢,并根據(jù)優(yōu)勢選擇一定的就業(yè)方向。
不隨波逐流。不要看周圍的人做什么,自己就做什么,也許別人做的并不適合你。別人的優(yōu)勢很可能會成為你的劣勢。所以,堅定自己的想法,讓自己知道那些方面適合自己,自己可以勝任。
不斷嘗試可能成為自己的優(yōu)勢。你不知道什么適合自己,所以才要大膽、勇敢地嘗試。找到一種可以屬于你的獨特的優(yōu)勢。
堅定信念。一旦你堅定了自己的信念,就不要被別人的意見或是諷刺或是嘲笑所干擾。別人不是你,不懂的你在想什么,不清楚你開始這件事的源頭。你的事情,不了解你的人,沒有資格輕易評說。
不茫然,不多想。別讓太多的事干擾到你奮斗下去的信念。夢想不容許太多的雜念。那些雜念只會讓你的心愈來愈脆弱,多為一個人考慮,到頭來,傷害的還是自己。
選擇自己學(xué)習(xí)方法
每個人都有適合自己的方法,有的人去選擇自學(xué),有的人選擇看視頻學(xué)習(xí),有的人選擇報名培訓(xùn)班,那在這個時候,你就要自己考慮清楚,到底那樣對的幫助是最大的,個人覺得是跟著培訓(xùn)班最好的,畢竟人家的實戰(zhàn)項目多,我們學(xué)軟件開發(fā)的都知道實戰(zhàn)項目對于學(xué)好一門語言是 很重要的。
學(xué)習(xí)python有那些誤區(qū)
具體里面的誤區(qū)非常的多,那些就不需要我去寫出來,我給你說的一般都是心態(tài)的問題,首先一個覺得自己會java和c++,然后我學(xué)習(xí)python就很牛,但是你要知道語言是有很多相同的地方,但是不是通用,一定要自己學(xué)習(xí)的仔細(xì)。還有一種就是覺得我不會英語,我要先去把英語學(xué)習(xí)好在來學(xué)python。因為自己想還壞主意然后學(xué)習(xí),這樣的都是容易找進誤區(qū)的。
怎么樣才能學(xué)好python
學(xué)好python你需要一個良好的環(huán)境,一個優(yōu)質(zhì)的開發(fā)交流群,群里都是那種相互幫助的人才是可以的,我有建立一個python學(xué)習(xí)交流群,在群里我們相互幫助,相互關(guān)心,相互分享內(nèi)容,這樣出問題幫助你的人就比較多,群號是304加上050最後799,這樣就可以找到大神聚合的群,如果你只愿意別人幫助你,不愿意分享或者幫助別人,那就請不要加了,你把你會的告訴別人這是一種分享。
感覺寫的好,對你有幫助,就點個贊唄,別光只收藏哈.~( ̄▽ ̄)~
?