最近用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的問題。
回複內容:
個人覺得在python開發中遇到的問題在其他語言實現時一般也會遇到。解決這些問題的過程就是加深自己某方面理解的過程。
題主沒找到問題根本來回換python版本,正好碰到了python的軟肋,版本差別大。建議多搜搜錯誤資訊,理解問題所在。
python的優勢就如大家所說,簡單明了,能很快上手,有大量資源。我猜你是你爬蟲抓的網頁裡含有where,你一併寫到sql裡了,導致的你的語句裡含有where。
這種問題一般是你自己的問題。我覺得是編程理念的問題。
編程在大部分情況下都是為瞭解決問題。為了炫技而做的編程其實是很少的情況。
以爬蟲為例。
寫爬蟲、扒資料,通常都是整個大問題中的很小一部(一般是第一步),扒過來的資料作分析、做篩選、或者說做發帖機器人、哪怕只是只是簡單的批量下載妹子圖。整個事情的主要精力和主要“產生收益”的環境是後面的。那自然,寫爬蟲這件事情自然就應該是怎麼快怎麼來,怎麼省精力怎麼來。
大部分情況下,Py是做這個事情的最優選擇(至少是第一次的最優選擇)。所有的編譯型語言你就不用想了,準確說,不提供互動式環境的語言都可以不考慮,調試代價太高。那麼剩下來的還有什麼呢?Python,Nodejs, Ruby。
Nodejs是的設計理念是非同步,而對於爬蟲這樣的程式而言,非同步就有點多此一舉的感覺。
Ruby其實也是個不錯的選擇,但是有一些天生的缺陷,它的文法太“精妙”了,你在使用的時候,常常會不由自主的陷入“我可以做的更優雅一些”這樣的陷阱之中,而這樣優雅給你帶來的收益並不啊,你的下一個爬蟲的商務邏輯和你的這個爬蟲和可能一點相似之處都沒有。你很難做到一處優雅、處處優雅。除非你的主業是寫Ruby(寫ROR的不算哦),不然你會很容易陷入選擇困難症之中。
反觀Python,簡單、粗暴、無腦幹。足夠簡單的文法可以可以讓你把主要精力放在:
““
對面伺服器怎麼返回來一坨屎”
““
憑什麼又屏蔽老子”
““
你就不能一次性把資料載入完”
““
你這個js函數的參數怎麼能先傳sign2,再傳sign1呢!”【真實的故事,某著名網盤簽名Function Compute時,function(sign2,sign1),為此我卡了兩個小時】
““
小夥你的頁面結構寫的太渣了”
““
哈哈哈丫502錯誤了”
““
我果然是個天才”
這些重要的問題上。
當你有了這幾次類似體驗之後,你發現有些事情是有相似性的。你開始接觸一些爬蟲的架構,也積累了一些用的順手的庫,提取了一些可以複用的代碼,開始有了更開闊的思路。你發現要是能夠直接使用目標網站上的JS多好啊,然後開始在Py裡面跑js。你發現下載串連似乎是固定的嘛,那我為什麼不直接調用wget呢?老闆說“你給我個應用程式啊,有介面那種”,你發現用py2exe打包命令列,c#+wpf拖個表單程式也沒那麼麻煩。
這個時候你就會有“Python真是好”的感歎,喝著茶就把程式寫完了。(什麼,你說效能?不然你以為為什麼要喝茶呢,等一下嘛。不行加錢升配置啊)
【完】我做不出美味的飯,是不是廚具的問題?「在運行時時常會停止工作,在減少了線程數(16->8)後,穩定性有所提升,但依舊偶爾存在停止工作的問題」
很明顯這是因為你不懂多線程編程,沒有對相關資料進行加鎖保護導致的問題。如果你的邏輯比較複雜的話,後期 debug 這種問題非常困難。
如果你不懂得在多線程程式中
時時刻刻考慮另外的線程的存在,對資料進行必要的
加鎖保護的話,建議你還是不要用多線程了。(如果你一定要用多線程的話,你只能用 Rust 了——在那裡,沒有對資料進行適當的保護的多線程程式編譯通不過的。)
我寫過一次多線程的爬蟲,然後再也沒用過多線程寫爬蟲了。太費心。
另外就是,請記住 Python 3.x 和 2.x 是相近的
兩種不同的語言,本來好好的程式換另一個出錯很正常。3to2 和 2to3 只是協助工具輔助,不能完全解決問題的(不然也不用搞得不相容了)。咱們一點一點來聊:
好不容易寫完了,但在運行時時常會停止工作,在減少了線程數(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中某一項對理解有比較大的問題。
優勢其實是簡單無腦一把抓,只要懂編碼懂http懂html大概懂一點js,如果要寫資料庫的話稍微懂點兒資料庫實在不懂也可以靠orm直接對象化操作資料庫,各種輪子現成的不用重新造,各種架構齊全的細節不用操心……
有沒有更方便的選擇?有。目前用node寫更簡單,除此之外……當然,坑也更多就是了。可以的話就上代碼吧!talk is cheap, show me the code為什麼題主不去研究為什麼停止工作而是去換版本?python又不是windows→_→