如何使用python3.5.2+pyqt5編寫無阻塞多線程GUI
這么久的問題居然沒人回答…因為我沒用過py,所以也沒什么好答案。我一般用C++和QT。udp傳遞消息如果項目簡單我就放在主循環里,如果復雜我一般用boost庫再開一個線程,在另一個循環中接收消息。不知道py怎么寫的,但應該也是差不多的。我奇怪的是為什么會阻塞?我覺得是代碼有問題…
Python到底好用嗎
在我還在讀大學那幾年假設讓我推薦一門編程語言學習,我會推薦Java/PHP/C#其中的一門,這兩年再讓我推薦一門編程語言那么我一定會推薦Python或者Go語言,今天就著重講一下為什么我會推薦Python語言。
一切都因為人工智能在大概10年前,大家經常說的三個互聯網技術行業主題分別是物聯網、云計算、大數據,最近幾年大家說得比較多的主要是區塊鏈和人工智能,而最近一年區塊鏈說得越來越少了,人工智能卻說得越來越多。
阿爾法狗、百度無人車、微軟Cortana、微軟小冰、百度小度智能音箱、YouTube、今日頭條......一個個成熟的人工智能系統正在走向消費市場,可以說實現人工智能是技術行業的最高理想。
Python成為人工智能領域的頭牌語言是有原因的,在Python語言自身語言特點來說,Python確實是人工智能領域最合適的編程語言之一。
Python語法非常接近自然語言、簡單高效可靠Python語言是一門非常優雅的編程語言,語法特點上簡單、高效、可靠。Python語言的語法談不上嚴謹,也就是我們通常說的怎么寫都行,這樣讓Python在開發的時候足夠雷厲風行,不像Java這些編程語言這些編程語言,明明三兩句話就能講清楚的,必須要啰哩啰嗦的講半天。Python的語法簡潔到難以置信,一切為了效率而生,并且Python本身也是解釋型編程語言,比如在很多編程語言編譯的時候必須要給出類型限制、約束,Python語言就不需要做這些操作。
當然最重要的就是Python語言非常接近自然語言,寫Python代碼就跟寫作文一樣,這一點是要遠遠超過其他編程語言的。Python語言極其高效,主要是Python跟C/C++關系密切,這一點后面專門會說。
Python是可靠的,Python擁有非常多的穩定、可靠的第三方庫,網頁開發、應用開發、移動應用開發、硬件開發、數據處理都是Python擅長的領域,Web領域的Django,科學計算的NumPy、Pandas,機器學習領域的scikit-learn,自然語言處理的nltk,這些都是Python在各個領域的一些非常矚目的解決方案,毫無疑問Python是非常可靠的。
Python跟C/C++非常友好、這是Python高效的根本原因一句話總結就是:Python慢、可是Python可以直接連接很多高效的C/C++接口。
好像在大家眼里,解釋型編程語言效率都比較低,可是為什么現在很多解釋型語言效率非常高,現在再也沒人敢叫Python/PHP小腳本語言了,而這些編程語言能夠保持高效的根本原因其實是一樣的,那就是跟C/C++相處十分友好。
PHP跟C語言很近,Python則跟C/C++相處非常友好,Python只需要關注邏輯算法本質,他只要能夠調用好AI接口就好了,真正做底層計算的始終是高效的C/C++,Python只需要關注好邏輯運算就好,只需要告訴C/C++第一步怎么計算、第二步怎么計算,具體的實現全都交給C/C++就好了,因此Python的代碼量也會很小,開發效率非常高。
C/C++擅長寫底層算法,而Python用來做上層邏輯開發更完美,C/C++在上層邏輯開發方面不如Python,反過來Python做底層算法不如C/C++有效率,剛好兩者搭配就是一個完美的解決方案,PHP也是一樣,只關心業務,其余的全部交給C語言。
Python標準庫強大、跨平臺性能好、社區也夠完善Python是Google官方支持的,強大的TensorFlow深度學習框架Google就用了很大比例的Python開發,Google為了Python也構建起了一個不錯的社區,盡管跟Java/PHPJavaScript社區相比還有比較大的差距。
Python還擁有非常強的兼容性,跨平臺性能是不輸PHP和Java的。Python本身又是開源的,開源就意味著有源源不斷的社區貢獻,這一點能夠不斷促進Python的進步。Python也是一門面向對象的編程語言,可是對過程編程也有很好的支持,面向對象編程使用基于數據和函數的對象編程。
Python還擁有非常豐富的標準庫,這一點是Python強大的根本原因,正則表達式、文檔生成、線程、單元測試、數據庫、瀏覽器、CGI庫、FTP支持、Email、XML/HTML、WAV、密碼系統、GUI編程、Tk以及其他系統有關的操作,可以說Python已經非常強大了,它能做的事情太多了。
Python應用非常廣泛、使用企業也非常多,國內如金山、百度、阿里巴巴、騰訊、今日頭條(字節跳動)、新浪微博等企業,在國外比如Google、NASA、微軟、YouTube、Facebook等企業也都在使用Python,這個編程語言使用的企業很多,尤其是人工智能現在正在高速發展,Python以后還有可能大展拳腳。
本文為字節跳動簽約作者EmacserVimer悟空問答原創文章,未經允許轉載、抄襲必究!零基礎小白如何在最短的時間快速入門python爬蟲
答:本文邀請feifan來回答,他總結了使用python自帶庫完成爬蟲的方法,并且列出了爬蟲在實際中可能遇到的幾個問題,教會你零基礎入門python爬蟲~
此處的爬蟲并不是百度或者google這樣需要沿著某條路徑采集互聯網上所有信息的機器人,而是針對某個特定的網頁,從中提取出我們需要的信息。比如我們在中關村上查到了一臺手機的詳情頁,想把其中的cpu信息、操作系統、分辨率等等字段提出出來。即此處的爬蟲是指針對特定網頁結構、規模很小、抓取路徑收斂的情況而言。下文我們以一個實例,看看如何從頭寫一個python爬蟲。
抓取頁面基本方法瀏覽器中看到的頁面,實際上是通過一系列的http請求加載并渲染服務器的資源。同理只要我們能夠用python發出http請求,通過get或post的方法獲得服務器返回的html片段、html頁面或json數據串,就可以從中抓取到想要的內容。
python中對http請求的封裝是在urllib和urllib2兩個庫里。
urllib提供了一些工具方法,用于對發送請求時的字符串進行轉義或編碼。
發送get/post請求則需要用到urllib2中提供的幾個類
在掌握了如何在python中構造http請求后,下一步需要做的就是結合具體的網頁,分析出web頁面的請求方式、參數傳遞方式和必要的header信息(如cookie等)。chrome控制臺的network分析基本上可以滿足需求,但一款抓包利器無疑可以提升我們的效率。推薦使用fiddler進行抓包和解包,可以更清晰第看到http中所用的不同請求方式。
字符串查找、正則表達式、html解析http請求的response通常包含兩種:json字符串,或html代碼片段,信息的提取就轉變成了字符串處理。此時無論是通過字符串查找、正則表達式匹配,只要能定位到目標字段即可。
但更好的方法是對html的Dom樹進行解析,尤其是存在多個目標字段需要抓取時,解析html的方式能夠對特殊格式的字段信息進行批量解析。
這里使用python自帶的htmlparser進行解析,htmlparser對html片段進行深度優先的遍歷,在遍歷的過程中可以識別出開始標簽、結束標簽和標簽中的內容,因此提供了一種基于標簽tag的編程方式。看下面的例子
需要提取手機的操作系統、核心數、cpu型號等信息,根據html的標簽、屬性名稱,代碼如下:
針對中關村上的某個手機詳細
handle_data可以提取html標簽中的數據,但handle_data存在兩個問題。
(1)當標簽內容為空時,handle_data自動跳過該標簽。這里的標簽為空是指標簽中不包含任意字符串內容、不包含其他的子標簽。注意,當標簽中含有&nb等空白字符串時,handle_data可以解析出其中的data。比如以下結構中,電話號碼一列允許為空,通過html_parser解析后只得到4個<td>的標簽內容。
由于會跳過內容為空的標簽的解析,就會打亂html的結構,由于數據的缺失返回的list長度不定,導致無法將list中每項內容與html中的內容對應起來。
(2)標簽中包含子標簽時,內容會被分割到不同的handle_data函數中,比如
由于handle_data是針對每個標簽返回數據,以上的td里包含了一個span子標簽,handle_data分為2次返回數據。即第一次調用handle_data返回狀態:,第二次調用handle_data返回已拒絕。我們希望<td>標簽中的內容作為整體返回,而現在被分割成了兩塊,同樣會破壞結構。
解決以上兩個問題的關鍵方法在于,使用cache緩存字符串,把對數據的處理從handle_data推遲到handle_endtag。只有遇到end_tag時,才能確定標簽閉合,使數據完整。
爬蟲被屏蔽后怎么辦服務器會通過一些策略屏蔽惡意爬蟲,以避免對服務器資源的消耗,如檢查同一IP的訪問頻率、訪問間隔等。
所以我們也應該使用一些簡單策略,使我們的爬蟲看起來更像是人的行為,以繞開服務器的檢測機制。常用的方法包括延長相鄰請求的間隔,相鄰間隔使用隨機時長。
在請求的header字段中包含了user-agent字段,服務器通過檢測user-agent字段確定客戶端的類型。如果不指定user-agent字段,請求時腳本會默認填充該字段,如下圖
#python中默認的user-agent字段
網上有一些說法user-agent的值會影響爬蟲是否能夠抓取web內容,為了避免爬蟲被屏蔽,將user-agent的值設為瀏覽器的類型:Mozilla/5.0(WindowsNT6.1;WOW64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/55.0.2883.87Safari/537.36
但在實際抓取的幾個web站點中,user-agent的值對爬蟲被屏蔽沒有影響,在使用時不用刻意設置user-agent的值。
以上的方法都是避免爬蟲被屏蔽掉。但萬一很不幸爬蟲已經被屏蔽了,發出請求返回的結果是輸入驗證碼的頁面,此時該如何解決呢?
對于支持https協議的站點,此時可以嘗試的一種方案是:改用https協議。
項目中遇到爬蟲被百度屏蔽的現象,嘗試了很多方法都無效。后來將原來鏈接中的http協議換成https爬蟲又開始工作了。原理雖然不清楚,但簡單可行。
帶驗證碼的登錄很多web內容只有在登錄后才有權限訪問,服務器通過創建session并下發sessionid來維持與客戶端的鏈接狀態。客戶端在每次發送請求時,都在cookie中攜帶sessionid等字段信息。sessionid是無法復用的,也即在瀏覽器中登錄后所獲得的sessionid直接拿到python腳本中使用,返回的結果仍然是跳轉到登錄頁面的。因為通過http下發的sessionid是捆綁到端口號的,也就是與服務器維持通信的是客戶端上的某個進程,把瀏覽器中的sessionid拿到python腳本中,由于更換了進程sessionid當然失效了。
既然無法繞開登錄,我們就在python腳本中完成登錄的過程,拿到登錄后返回的cookie、sessinoid等。這里有兩個難點需要解決,1)服務器登錄邏輯的分析與猜測;2)解決登錄時存在的驗證碼識別問題。
登錄除了需要post提交用戶名、密碼和sessionid之外,通常也會隱式提交部分參數,可以用chrome瀏覽器的調試模式查看post提交的參數及對應的值,登錄成功之后,我們就可以拿到返回的cookie值了。
登錄時的驗證碼可以通過OCR自動識別,嘗試了google的tesseract-ocr準確率并不高。所以推薦手動輸入驗證碼,幫助爬蟲完成登錄,畢竟授權只需要一次輸入。
手動輸入驗證碼的思路如下,在請求sessionid的同時保存驗證碼的圖片,人工讀取驗證碼的內容,與username和password一起提交。示例代碼如下:
需要抓取javascript加載的結果詳細參考外部鏈接:https://impythonist.wordpress.com/2015/01/06/ultimate-guide-for-scraping-javascript-rendered-web-pages/
這篇文章中的思路是,通過使用webkitlibrary建立本地的javascript執行環境,模擬瀏覽器對頁面的加載渲染,從而抓取javascript處理后的頁面內容。
這個例子中javascript所加載的結果,也是通過ajax重新向服務器發起請求返回的,直接發送ajax請求并抓取結果即可。在本地搭建javascript的執行環境有些畫蛇添足,但也是一種可以參考的思路。
本文總結了使用python自帶庫完成爬蟲的方法,并且列出了爬蟲在實際中可能遇到的幾個問題,比如爬蟲被屏蔽、需要輸入驗證碼進行登錄等。實踐中的難點在于分析和猜測服務器的登錄邏輯,并且提取必需的參數完成登錄鑒權。
python爬蟲怎么做
大到各類搜索引擎,小到日常數據采集,都離不開網絡爬蟲。爬蟲的基本原理很簡單,遍歷網絡中網頁,抓取感興趣的數據內容。這篇文章會從零開始介紹如何編寫一個網絡爬蟲抓取數據,然后會一步步逐漸完善爬蟲的抓取功能。
工具安裝
我們需要安裝python,python的requests和BeautifulSoup庫。我們用Requests庫用抓取網頁的內容,使用BeautifulSoup庫來從網頁中提取數據。
安裝python
運行pipinstallrequests
運行pipinstallBeautifulSoup
抓取網頁
完成必要工具安裝后,我們正式開始編寫我們的爬蟲。我們的第一個任務是要抓取所有豆瓣上的圖書信息。我們以https://book.douban.com/subject/26986954/為例,首先看看開如何抓取網頁的內容。
使用python的requests提供的get()方法我們可以非常簡單的獲取的指定網頁的內容,代碼如下:
提取內容
抓取到網頁的內容后,我們要做的就是提取出我們想要的內容。在我們的第一個例子中,我們只需要提取書名。首先我們導入BeautifulSoup庫,使用BeautifulSoup我們可以非常簡單的提取網頁的特定內容。
連續抓取網頁
到目前為止,我們已經可以抓取單個網頁的內容了,現在讓我們看看如何抓取整個網站的內容。我們知道網頁之間是通過超鏈接互相連接在一起的,通過鏈接我們可以訪問整個網絡。所以我們可以從每個頁面提取出包含指向其它網頁的鏈接,然后重復的對新鏈接進行抓取。
通過以上幾步我們就可以寫出一個最原始的爬蟲。在理解了爬蟲原理的基礎上,我們可以進一步對爬蟲進行完善。
寫過一個系列關于爬蟲的文章:https://www.toutiao.com/i6567289381185389064/。感興趣的可以前往查看。
Python基本環境的搭建,爬蟲的基本原理以及爬蟲的原型
Python爬蟲入門(第1部分)
如何使用BeautifulSoup對網頁內容進行提取
Python爬蟲入門(第2部分)
爬蟲運行時數據的存儲數據,以SQLite和MySQL作為示例
Python爬蟲入門(第3部分)
使用seleniumwebdriver對動態網頁進行抓取
Python爬蟲入門(第4部分)
討論了如何處理網站的反爬蟲策略
Python爬蟲入門(第5部分)
對Python的Scrapy爬蟲框架做了介紹,并簡單的演示了如何在Scrapy下進行開發
Python爬蟲入門(第6部分)
python線程與進程的區別
1、運行方式不同
進程不能單獨執行,它只是資源的集合。
進程要操作CPU,必須要先創建一個線程。
所有在同一個進程里的線程,是同享同一塊進程所占的內存空間。
2、關系
進程中第一個線程是主線程,主線程可以創建其他線程;其他線程也可以創建線程;線程之間是平等的。
進程有父進程和子進程,獨立的內存空間,唯一的標識符:pid。
3、速度
啟動線程比啟動進程快。
運行線程和運行進程速度上是一樣的,沒有可比性。
線程共享內存空間,進程的內存是獨立的。
4、創建
父進程生成子進程,相當于復制一份內存空間,進程之間不能直接訪問
創建新線程很簡單,創建新進程需要對父進程進行一次復制。
一個線程可以控制和操作同級線程里的其他線程,但是進程只能操作子進程。
5、交互
同一個進程里的線程之間可以直接訪問。兩個進程想通信必須通過一個中間代理來實現。
python selenium多線程怎么用
不同的線程創建不同的driver,也可以創建相同的