標籤:

最近使用python寫了爬蟲,感覺體驗非常不好,請教各位?

最近用python寫了爬蟲,一開始用的3.4,好不容易寫完了,但在運行時時常會停止工作,在減少了線程數(16-&>8)後,穩定性有所提升,但依舊偶爾存在停止工作的問題。因此換了python3.5,發現有些包不支持3.5,於是聽從建議換到了最流行的2.7版本,結果sqlite3包無故報錯。

DatabaseError: malformed database schema (is_transient) - near "where": syntax error

在sql語句中根本沒有where的情況下報這樣的錯誤,而原程序在python3.4下是可以成功運行的,當然3to2的差異我也改了。

最後,在放棄python之前,我想問問各位,python的優勢究竟在哪裡?我個人感覺語言本身有些不穩定,時常會冒出一些莫名其妙的錯誤。這究竟是我的問題還是python的問題。


咱們一點一點來聊:

好不容易寫完了,但在運行時時常會停止工作,在減少了線程數(16-&>8)後,穩定性有所提升,但依舊偶爾存在停止工作的問題。

首先,爬蟲屬於IO密集型程序(網路IO和磁碟IO),這類程序的瓶頸大多在網路和磁碟讀寫的速度上,多線程在一定程度上可以加速爬蟲的效率,但是這個「加速」無法超過min(出口帶寬,磁碟寫的速度),而且,關於Python的多線程,由於GIL的存在,實際上是有一些初學者不容易發現的坑的。

發現有些包不支持3.5

Python2和3的分裂確實比較腦殘,但是據我所知,Python爬蟲相關的庫,大部分已經支持到了Python3.x的,不知道題主用到了什麼庫。當然,我是傾向於用Python2.7.x的~~~

於是聽從建議換到了最流行的2.7版本,結果sqlite3包無故報錯。

DatabaseError: malformed database schema (is_transient) - near "where": syntax error

在sql語句中根本沒有where的情況下報這樣的錯誤,而原程序在python3.4下是可以成功運行的,當然3to2的差異我也改了。

大大的「syntax error」已經告訴你你的SQL語句出錯了~但是,對於爬蟲選擇資料庫,考慮到爬蟲數據的多變,建議題主使用NoSQL資料庫,如果你暫時沒有或者比較迷茫資料庫選擇,建議從MongoDB開始嘗試。

最後,在放棄python之前,我想問問各位,python的優勢究竟在哪裡?我個人感覺語言本身有些不穩定,時常會冒出一些莫名其妙的錯誤。這究竟是我的問題還是python的問題。

這裡,第一個建議是,將「python」寫成「Python」,這是一個軟體工程師的嚴謹態度。其次,Python不敢說是完美的,但是「是我的問題還是python的問題」這句話的答案應該是題主的問題,如果Python可以被一個初學者花三分鐘就挑出一個致命的Bug,那麼它絕不會有當下的市場。

其實Python本身是非常簡單的,雖然有一些「高級」的用法,但是就算不用,一樣可以快速寫出實用的代碼。編程設計到更多的東西是編程語言之外的東西,網路協議、設計模式、數學、演算法等等,這些都是跨越編程語言但是編程會使用到的知識,也是高質量代碼與低水平代碼的差異所在。


個人覺得在python開發中遇到的問題在其他語言實現時一般也會遇到。解決這些問題的過程就是加深自己某方面理解的過程。

題主沒找到問題根本來回換python版本,正好碰到了python的軟肋,版本差別大。建議多搜搜錯誤信息,理解問題所在。

python的優勢就如大家所說,簡單明了,能很快上手,有大量資源。


我覺得是編程理念的問題。

編程在大部分情況下都是為了解決問題。為了炫技而做的編程其實是很少的情況。

以爬蟲為例。

寫爬蟲、扒數據,通常都是整個大問題中的很小一部(一般是第一步),扒過來的數據作分析、做篩選、或者說做發帖機器人、哪怕只是只是簡單的批量下載妹子圖。整個事情的主要精力和主要「產生收益」的環境是後面的。那自然,寫爬蟲這件事情自然就應該是怎麼快怎麼來,怎麼省精力怎麼來。

大部分情況下,Py是做這個事情的最優選擇(至少是第一次的最優選擇)。所有的編譯型語言你就不用想了,準確說,不提供互動式環境的語言都可以不考慮,調試代價太高。那麼剩下來的還有什麼呢?Python,Nodejs, Ruby。

Nodejs是的設計理念是非同步,而對於爬蟲這樣的程序而言,非同步就有點多此一舉的感覺。

Ruby其實也是個不錯的選擇,但是有一些天生的缺陷,它的語法太「精妙」了,你在使用的時候,常常會不由自主的陷入「我可以做的更優雅一些」這樣的陷阱之中,而這樣優雅給你帶來的收益並不啊,你的下一個爬蟲的業務邏輯和你的這個爬蟲和可能一點相似之處都沒有。你很難做到一處優雅、處處優雅。除非你的主業是寫Ruby(寫ROR的不算哦),不然你會很容易陷入選擇困難症之中。

反觀Python,簡單、粗暴、無腦幹。足夠簡單的語法可以可以讓你把主要精力放在:

對面伺服器怎麼返回來一坨屎

憑什麼又屏蔽老子

你就不能一次性把數據載入完

你這個js函數的參數怎麼能先傳sign2,再傳sign1呢!」【真實的故事,某著名網盤簽名函數計算時,function(sign2,sign1),為此我卡了兩個小時】

小伙你的頁面結構寫的太渣了

哈哈哈丫502錯誤了

我果然是個天才」

這些重要的問題上。

當你有了這幾次類似體驗之後,你發現有些事情是有相似性的。你開始接觸一些爬蟲的框架,也積累了一些用的順手的庫,提取了一些可以復用的代碼,開始有了更開闊的思路。你發現要是能夠直接使用目標網站上的JS多好啊,然後開始在Py裡面跑js。你發現下載連接似乎是固定的嘛,那我為什麼不直接調用wget呢?老闆說「你給我個應用程序啊,有界面那種」,你發現用py2exe打包命令行,c#+wpf拖個窗體程序也沒那麼麻煩。

這個時候你就會有「Python真是好」的感嘆,喝著茶就把程序寫完了。(什麼,你說性能?不然你以為為什麼要喝茶呢,等一下嘛。不行加錢升配置啊)

【完】


「在運行時時常會停止工作,在減少了線程數(16-&>8)後,穩定性有所提升,但依舊偶爾存在停止工作的問題」

很明顯這是因為你不懂多線程編程,沒有對相關數據進行加鎖保護導致的問題。如果你的邏輯比較複雜的話,後期 debug 這種問題非常困難。

如果你不懂得在多線程程序中時時刻刻考慮另外的線程的存在,對數據進行必要的加鎖保護的話,建議你還是不要用多線程了。(如果你一定要用多線程的話,你只能用 Rust 了——在那裡,沒有對數據進行適當的保護的多線程程序編譯通不過的。)

我寫過一次多線程的爬蟲,然後再也沒用過多線程寫爬蟲了。太費心。

另外就是,請記住 Python 3.x 和 2.x 是相近的兩種不同的語言,本來好好的程序換另一個出錯很正常。3to2 和 2to3 只是輔助工具,不能完全解決問題的(不然也不用搞得不兼容了)。


我猜你是你爬蟲抓的網頁里含有where,你一併寫到sql里了,導致的你的語句里含有where。

這種問題一般是你自己的問題。


推薦閱讀:

改善Python程序的91個建議(筆記二)
【Python3網路爬蟲開發實戰】1.5.2-PyMongo的安裝
對ldap實現增刪改查--附demo
隊列和棧
演算法,西瓜切十刀,最多是多少塊?

TAG:Python |