python 基础知识点整理 和具体应用
Python教程
Python是一種簡(jiǎn)單易學(xué),功能強(qiáng)大的編程語(yǔ)言。它包括了高效的高級(jí)數(shù)據(jù)結(jié)構(gòu)和簡(jiǎn)單而有效的方法,面向?qū)ο缶幊獭ython優(yōu)雅的語(yǔ)法,動(dòng)態(tài)類(lèi)型,以及它天然的解釋能力,使其成為理想的語(yǔ)言,腳本和應(yīng)用程序快速開(kāi)發(fā)在大多數(shù)平臺(tái)上的許多領(lǐng)域。
Python解釋器及其擴(kuò)展標(biāo)準(zhǔn)庫(kù)的源碼和編譯版本可以從Python的Web站點(diǎn),http://www.python.org/所有主要平臺(tái)可自由查看,并且可以自由發(fā)布。該站點(diǎn)上也包含了分配和指針到很多免費(fèi)的第三方Python模塊,程序,工具,以及附加的文檔。
Python的解釋器很容易擴(kuò)展新的功能,并在C或C ++(或由C來(lái)調(diào)用其他語(yǔ)言)實(shí)現(xiàn)的數(shù)據(jù)類(lèi)型。 Python也很適于作為定制應(yīng)用的一種擴(kuò)展語(yǔ)言。
本教程向讀者介紹了非正式的Python語(yǔ)言和系統(tǒng)的基本概念和功能。它有助于理解Python和實(shí)戰(zhàn)練習(xí),當(dāng)然所有的例子都是自包含的,所以這本手冊(cè)可以離線(xiàn)閱讀為好。
有關(guān)標(biāo)準(zhǔn)對(duì)象和模塊的詳細(xì)介紹,請(qǐng)參見(jiàn)Python標(biāo)準(zhǔn)庫(kù)。Python語(yǔ)言參考給出了語(yǔ)言的更正式的定義。需要編寫(xiě)C或C + +擴(kuò)展,請(qǐng)閱讀擴(kuò)展和嵌入Python解釋器和Python/C的API參考手冊(cè)。也有幾本書(shū)涵蓋了各個(gè)深度的Python。
本教程并不試圖全面,涵蓋每一個(gè)功能,甚至每一個(gè)常用功能。相反,它介紹了許多Python中最引人注目的功能,會(huì)給Python語(yǔ)言的韻味和風(fēng)格是一個(gè)好開(kāi)始。看完之后,你就可以閱讀和編寫(xiě)Python模塊和程序,將準(zhǔn)備進(jìn)一步了解Python標(biāo)準(zhǔn)庫(kù)描述的各種Python庫(kù)模塊。
Python概述
Python是一種高層次的,解釋性的,交互式和面向?qū)ο蟮哪_本語(yǔ)言。Python被設(shè)計(jì)成具有很強(qiáng)的可讀性,它使用英語(yǔ)如其他語(yǔ)言常用空白作為標(biāo)點(diǎn)符號(hào),它比其他語(yǔ)言語(yǔ)法結(jié)構(gòu)更少。
-
Python被解析:這意味著它是在運(yùn)行時(shí)由解釋器處理,你并不需要在執(zhí)行前編譯程序。這類(lèi)似于Perl和PHP。
-
Python是互動(dòng):這意味著你可以在Python的提示和解釋器進(jìn)行交互,直接寫(xiě)出你的程序。
-
Python是面向?qū)ο蟮?#xff1a;這意味著Python支持面向?qū)ο蟮姆绞交虺绦?#xff0c;它封裝了對(duì)象中的代碼的技術(shù)。
-
Python是初學(xué)者的語(yǔ)言:Python是為初級(jí)程序員一種偉大的語(yǔ)言,并支持廣泛的應(yīng)用,從簡(jiǎn)單的文本處理,WWW瀏覽器,以游戲開(kāi)發(fā)。
Python的歷史:
Python是由Guido van Rossum在八十年代末和九十年代初在全國(guó)研究所數(shù)學(xué)與計(jì)算機(jī)科學(xué)在荷蘭開(kāi)發(fā)。
Python從許多其他語(yǔ)言,包括ABC,Modula-3語(yǔ)言,C語(yǔ)言,C+ +,Algol-68,Smalltalk和unix的shell等腳本語(yǔ)言得到參考開(kāi)發(fā)。
Python是有版權(quán)的。比如Perl,Python源代碼現(xiàn)在是GNU通用公共許可證(GPL)下提供。
Python的現(xiàn)在是由一個(gè)核心開(kāi)發(fā)團(tuán)隊(duì)在維護(hù),雖然Guido van Rossum仍然持有在指導(dǎo)其進(jìn)展至關(guān)重要的作用。
Python的特點(diǎn):
Python的功能亮點(diǎn)包括:
-
易于學(xué)習(xí):Python有相對(duì)較少的關(guān)鍵字,結(jié)構(gòu)簡(jiǎn)單,明確的語(yǔ)法。這讓學(xué)生學(xué)習(xí)的時(shí)間相對(duì)較短。
-
易于閱讀:Python代碼是更加明確,可見(jiàn)。
-
易于維護(hù):Python的成功在于它的源代碼是相當(dāng)容易維護(hù)。
-
廣泛的標(biāo)準(zhǔn)庫(kù):Python的最大優(yōu)點(diǎn)是體積庫(kù)很方便,在UNIX,Windows和Macintosh跨平臺(tái)兼容。
-
交互模式:支持交互模式中,可以從終端輸入結(jié)果正確的語(yǔ)言,讓交互測(cè)試的代碼片段和調(diào)試。
-
便攜式:Python可以在多種硬件平臺(tái)上運(yùn)行,并且對(duì)所有的平臺(tái)上使用相同的接口。
-
擴(kuò)展:可以添加低級(jí)別的模塊在Python解釋器。這些模塊使程序員可以添加或自定義自己的工具來(lái)提高效率。
-
數(shù)據(jù)庫(kù):Python提供接口給所有主要的商業(yè)數(shù)據(jù)庫(kù)。
-
GUI編程:Python支持,可以創(chuàng)建并移植到許多系統(tǒng)調(diào)用,庫(kù)和Windows系統(tǒng),如Windows MFC,Macintosh和Unix的X Window系統(tǒng)的GUI應(yīng)用程序。
-
可擴(kuò)展性:Python提供了一個(gè)更好的結(jié)構(gòu),并支持比shell腳本大型程序。
除了上面提到的功能,Python也有很好的功能,幾個(gè)列舉如下:
-
支持功能和結(jié)構(gòu)化的編程方法,以及面向?qū)ο蟆?/p>
-
它可以作為一種腳本語(yǔ)言,或者可以被編譯為字節(jié)碼建立大型的應(yīng)用程序。
-
非常高的動(dòng)態(tài)數(shù)據(jù)類(lèi)型,并且支持動(dòng)態(tài)類(lèi)型檢查。
-
支持自動(dòng)垃圾收集。
-
它可以用C,C + +,COM和ActiveX,CORBA和Java很容易地集成。
Python環(huán)境安裝
本地環(huán)境設(shè)置
如果愿意設(shè)置您的Python環(huán)境,讓我們了解如何建立Python環(huán)境。 Python可在各種平臺(tái),包括Linux和Mac OS X,可嘗試打開(kāi)一個(gè)終端窗口并輸入“python”,以檢查是否已經(jīng)安裝了python,什么版本,如果已經(jīng)有安裝。
-
Unix (Solaris, Linux, FreeBSD, AIX, HP/UX, SunOS, IRIX, etc.)
-
Win 9x/NT/2000
-
Macintosh (Intel, PPC, 68K)
-
OS/2
-
DOS (multiple versions)
-
PalmOS
-
Nokia 手機(jī)
-
Windows CE
-
Acorn/RISC OS
-
BeOS
-
Amiga
-
VMS/OpenVMS
-
QNX
-
VxWorks
-
Psion
-
Python也可被移植到Java和.NET 虛擬機(jī)
獲得Python
最新源代碼,二進(jìn)制文件,文檔,新聞等可在Python的官方網(wǎng)站:
Python官方網(wǎng)站:http://www.python.org/
可以從以下站點(diǎn)下載Python文檔。文件格式是HTML,PDF和PostScript。
Python文檔網(wǎng)站:?www.python.org/doc/
安裝Python:
Python發(fā)行版適用于各種平臺(tái)。你只需要下載適用于您的平臺(tái)的二進(jìn)制代碼并安裝Python。
如果二進(jìn)制代碼針對(duì)您的平臺(tái)無(wú)法使用,你需要一個(gè)C編譯器來(lái)手動(dòng)編譯源代碼。編譯源代碼提供了選擇,為安裝功能方面更大的靈活性。
這里是在各種平臺(tái)上安裝Python的快速概覽:
UNIX和Linux的安裝方式:
下面是簡(jiǎn)單的步驟,在Unix/ Linux機(jī)器上安裝Python。
-
打開(kāi)Web瀏覽器并轉(zhuǎn)至http://www.python.org/download/
-
按照鏈接下載壓縮的源代碼在Unix/ Linux操作系統(tǒng)。
-
下載并解壓文件。
-
編輯模塊/安裝文件,如果你想自定義一些選項(xiàng)。
-
執(zhí)行./configure 腳本
-
make
-
make install
這將安裝python的標(biāo)準(zhǔn)位置在 /usr/local/bin目錄和它的庫(kù)安裝在/usr/local/lib/pythonXX,其中XX是Python使用的版本。
Windows上安裝:
下面是Windows機(jī)器上安裝Python的步驟。
-
打開(kāi)Web瀏覽器并轉(zhuǎn)至?http://www.python.org/download/
-
按照鏈接到Windows安裝python-XYZ.msi文件,其中XYZ是你要安裝的版本。
-
要使用此安裝程序python-XYZ.msi,Windows系統(tǒng)必須支持Microsoft安裝程序2.0。只需安裝程序文件保存到本地計(jì)算機(jī),然后運(yùn)行它,看看是否你的機(jī)器支持MSI。
-
通過(guò)雙擊它在Windows中運(yùn)行下載的文件。這將出Python的安裝向?qū)?#xff0c;這些都很容易使用。只需接受默認(rèn)設(shè)置,等到安裝完成后。
Macintosh上安裝:
最新的Mac電腦配備安裝了Python,但可能好幾年前的機(jī)器沒(méi)有安裝。見(jiàn)http://www.python.org/download/mac/上獲得的最新版本以及額外的工具來(lái)支持在Mac上開(kāi)發(fā)的指令。對(duì)于老的Mac OS的Mac OS X10.3之前(2003年推出),MacPython上是可用的。“
只要到這個(gè)鏈接,完整Mac OS安裝安裝細(xì)節(jié)。
設(shè)置PATH:
程序和其他可執(zhí)行文件可以住在許多目錄,所以操作系統(tǒng)提供,列出目錄的操作系統(tǒng)搜索可執(zhí)行文件的搜索路徑。
路徑被存儲(chǔ)在環(huán)境變量,這是由操作系統(tǒng)維護(hù)的命名字符串。這些變量包含可用于命令行解釋器和其他程序的信息。
路徑變量名為Path的Unix或路徑在Windows(UNIX是區(qū)分大小寫(xiě)的,Windows是沒(méi)有)。
在Mac OS中,安裝程序處理的道路細(xì)節(jié)。調(diào)用任何特定目錄Python解釋器,必須Python的目錄添加到您的路徑。
設(shè)置路徑,在Unix/Linux上:
將Python目錄添加到在Unix系統(tǒng)中的特定會(huì)話(huà)的路徑:
-
在csh shell:?輸入
SETENV?PATH "$PATH:/usr/local/bin/python" ?然后按回車(chē)鍵。 -
在 bash shell (Linux):?輸入
export PATH="$PATH:/usr/local/bin/python" 然后按回車(chē)鍵。 -
在 sh 或??ksh shell:?輸入?
PATH="$PATH:/usr/local/bin/python"?然后按回車(chē)鍵。
注:?/usr/local/bin/python 為Python目錄的路徑
設(shè)置路徑Windows系統(tǒng):
以Python目錄添加到了 Windows 特定會(huì)話(huà)的路徑:
-
在命令提示符下:?輸入?
path %path%;C:\Python 然后按Enter鍵。
注意:C:\Python 是Python目錄的路徑
Python環(huán)境變量:
這里是重要的環(huán)境變量,其可以被Python確認(rèn):
| PYTHONPATH | 有類(lèi)似路徑的作用。這個(gè)變量告訴Python解釋器在哪里可以找到導(dǎo)入到程序中的模塊文件。 PYTHONPATH應(yīng)包括Python源代碼庫(kù)目錄,包含Python源代碼的目錄。 PYTHONPATH是由Python安裝程序有時(shí)會(huì)預(yù)設(shè)。 |
| PYTHONSTARTUP | 包含了在每次啟動(dòng)的解釋器(類(lèi)似于Unix.profile或.login文件)時(shí)執(zhí)行Python源代碼的初始化文件的路徑。這個(gè)文件通常命名為.pythonrc.py。在Unix中,通常包含加載實(shí)用程序或修改PYTHONPATH命令。 |
| PYTHONCASEOK | 在Windows中使用,以指示Python找到一個(gè)import語(yǔ)句,第一個(gè)不區(qū)分大小寫(xiě)的匹配。將此變量設(shè)置為任意值來(lái)激活它。 |
| PYTHONHOME | 備選模塊搜索路徑。它通常嵌入在PYTHONSTARTUP或PYTHONPATH目錄,以使交換模塊庫(kù)的簡(jiǎn)單。 |
運(yùn)行Python:
有三種不同的方式來(lái)啟動(dòng)Python:
(1) 交互式解釋器:
可以輸入python,并在開(kāi)始通過(guò)命令行啟動(dòng)在交互式解釋器它編碼的時(shí)候。從UNIX,DOS或其他系統(tǒng)提供了一個(gè)命令行解釋器或shell窗口。
$python # Unix/Linuxor python% # Unix/Linuxor C:>python # Windows/DOS下面是所有可用的命令行選項(xiàng)的列表:
| -d | 提供調(diào)試輸出 |
| -O | 生成優(yōu)化代碼(結(jié)果為.pyo文件) |
| -S | 不運(yùn)行導(dǎo)入網(wǎng)站,在啟動(dòng)時(shí)查找Python路徑 |
| -v | 詳細(xì)輸出(在導(dǎo)入語(yǔ)句詳細(xì)的跟蹤) |
| -X | 禁止基于類(lèi)內(nèi)置異常(只使用字符串);開(kāi)始1.6版本過(guò)時(shí) |
| -c cmd | 作為cmd 字符串運(yùn)行Python腳本發(fā)送 |
| file | 從給定的文件運(yùn)行Python腳本 |
(2) 腳本的命令行:
Python腳本可以在命令行中通過(guò)調(diào)用應(yīng)用程序中的解釋,如下面的執(zhí)行:
$python script.py # Unix/Linuxor python% script.py # Unix/Linuxor C:>python script.py # Windows/DOS注意:請(qǐng)確保該文件的權(quán)限模式可以執(zhí)行。
(3)集成開(kāi)發(fā)環(huán)境
您可以從圖形用戶(hù)界面(GUI)環(huán)境中運(yùn)行Python。所有需要的是一個(gè)支持Python系統(tǒng)的GUI應(yīng)用程序。
-
UNIX:IDLE也是早期的UNIX系統(tǒng)為Python的IDE。
-
Windows:PythonWin是第一個(gè)Windows界面的Python和一個(gè)GUI的IDE。
-
Macintosh:Python的的Macintosh版本隨著閑置的IDE可從主站下載,不是MACBINARY就是BinHex'd文件。
Python基本語(yǔ)法
Python與Perl,C和Java語(yǔ)言等有許多相似之處。不過(guò),也有語(yǔ)言之間有一些明確的區(qū)別。本章的目的是讓你迅速學(xué)習(xí)Python的語(yǔ)法。
第一個(gè)Python程序:
交互模式編程:
調(diào)用解釋器不經(jīng)過(guò)腳本文件作為參數(shù),顯示以下提示:
$ python Python 2.6.4 (#1, Nov 11 2014, 13:34:43) [GCC 4.1.2 20120704 (Red Hat 5.6.2-48)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>>鍵入下列文字在Python提示符,然后按Enter鍵:
>>> print "Hello, Python!";如果您運(yùn)行的是新的Python版本,那么需要使用打印語(yǔ)句括號(hào)像print ("Hello, Python!");。但是在Python版本2.6.4,這將產(chǎn)生以下結(jié)果:
Hello, Python!腳本模式編程:
調(diào)用解釋器及腳本作為參數(shù),并開(kāi)始執(zhí)行的腳本,并一直持續(xù)到腳本完成。當(dāng)腳本完成時(shí),解釋器不再是活動(dòng)的。
讓我們?cè)谀_本中編寫(xiě)一個(gè)簡(jiǎn)單的Python程序。所有的Python文件將具有.py擴(kuò)展。所以,把下面的代碼寫(xiě)在一個(gè)test.py文件。
print "Hello, Python!";在這里,我假設(shè)你已經(jīng)在PATH變量中設(shè)置Python解釋器。現(xiàn)在,嘗試如下運(yùn)行這個(gè)程序:
$ python test.py這將產(chǎn)生以下結(jié)果:
Hello, Python!讓我們嘗試另一種方式來(lái)執(zhí)行Python腳本。下面是修改后的test.py文件:
#!/usr/bin/pythonprint "Hello, Python!";在這里,假設(shè)Python解釋器在/usr/bin目錄中可用。現(xiàn)在,嘗試如下運(yùn)行這個(gè)程序:
$ chmod +x test.py # This is to make file executable $./test.py這將產(chǎn)生以下結(jié)果:
Hello, Python!Python標(biāo)識(shí)符:
Python標(biāo)識(shí)符是用來(lái)標(biāo)識(shí)一個(gè)變量,函數(shù),類(lèi),模塊或其他對(duì)象的名稱(chēng)。一個(gè)標(biāo)識(shí)符開(kāi)始以字母A到Z或a?z或后跟零個(gè)或多個(gè)字母下劃線(xiàn)(_),下劃線(xiàn)和數(shù)字(0?9)。
Python中標(biāo)識(shí)符內(nèi)不允許標(biāo)點(diǎn)符號(hào),如@,$和%。 Python是一種區(qū)分大小寫(xiě)的編程語(yǔ)言。因此,Manpower 和manpower在Python中是兩個(gè)不同的標(biāo)識(shí)符。
這里有Python標(biāo)識(shí)符命名約定:
-
類(lèi)名以大寫(xiě)字母以及所有其它標(biāo)識(shí)符以小寫(xiě)字母。
-
開(kāi)頭單個(gè)前導(dǎo)下劃線(xiàn)的標(biāo)識(shí)符表示由該標(biāo)識(shí)符約定意思是私有的。
-
開(kāi)頭兩個(gè)前導(dǎo)下劃線(xiàn)的標(biāo)識(shí)符表示一個(gè)強(qiáng)烈的私有的標(biāo)識(shí)符。
-
如果標(biāo)識(shí)符末尾還具有兩個(gè)下劃線(xiàn)結(jié)束時(shí),該標(biāo)識(shí)符是一個(gè)語(yǔ)言定義的特殊名稱(chēng)。
保留字:
下面列出了在Python中的保留字。這些保留字不可以被用作常量或變量,或任何其它標(biāo)識(shí)符。所有Python關(guān)鍵字只包含小寫(xiě)字母。
| and | exec | not |
| assert | finally | or |
| break | for | pass |
| class | from | |
| continue | global | raise |
| def | if | return |
| del | import | try |
| elif | in | while |
| else | is | with |
| except | lambda | yield |
行和縮進(jìn):
一個(gè)程序員學(xué)習(xí)Python時(shí),遇到的第一個(gè)需要注意的地方是,不使用括號(hào)來(lái)表示代碼的類(lèi)和函數(shù)定義塊或流程控制。代碼塊是由行縮進(jìn),這是嚴(yán)格執(zhí)行表示方式。
在縮進(jìn)位的數(shù)目是可變的,但是在塊中的所有語(yǔ)句必須縮進(jìn)相同的量。在這個(gè)例子中,兩個(gè)功能塊都很好使用:
if True:print "True" else:print "False"然而,在本實(shí)施例中的第二塊將產(chǎn)生一個(gè)錯(cuò)誤:
if True:print "Answer"print "True" else:print "Answer"print "False"因此,在Python中所有的連續(xù)線(xiàn)縮進(jìn)的空格數(shù)同樣的會(huì)結(jié)成塊。以下是各種語(yǔ)句塊中的例子:
注意:不要試圖理解所使用的邏輯或不同的功能。只要確定你明白,即使他們各種模塊無(wú)需括號(hào)。
#!/usr/bin/pythonimport systry:# open file streamfile = open(file_name, "w") except IOError:print "There was an error writing to", file_namesys.exit() print "Enter '", file_finish, print "' When finished" while file_text != file_finish:file_text = raw_input("Enter text: ")if file_text == file_finish:# close the filefile.closebreakfile.write(file_text)file.write("\n") file.close() file_name = raw_input("Enter filename: ") if len(file_name) == 0:print "Next time please enter something"sys.exit() try:file = open(file_name, "r") except IOError:print "There was an error reading file"sys.exit() file_text = file.read() file.close() print file_text多行語(yǔ)句:
Python語(yǔ)句通常用一個(gè)新行結(jié)束。 但是,Python允許使用續(xù)行字符(\)來(lái)表示,該行應(yīng)該繼續(xù)下去(跨行)。例如:
total = item_one + \item_two + \item_three包含在[],{}或()括號(hào)內(nèi)的陳述并不需要使用續(xù)行符。例如:
days = ['Monday', 'Tuesday', 'Wednesday','Thursday', 'Friday']Python引號(hào):
Python接受單引號(hào)('),雙引號(hào)(“)和三(''或”“”)引用,以表示字符串常量,只要是同一類(lèi)型的引號(hào)開(kāi)始和結(jié)束的字符串。
三重引號(hào)可以用于跨越多個(gè)行的字符串。例如,所有下列是合法的:
word = 'word' sentence = "This is a sentence." paragraph = """This is a paragraph. It is made up of multiple lines and sentences."""Python注釋:
一個(gè)井號(hào)(#),這不是一個(gè)字符串文字開(kāi)頭的注釋。“#”號(hào)之后字符和到物理行是注釋的一部分,Python解釋器會(huì)忽略它們。
#!/usr/bin/python# First comment print "Hello, Python!"; # second comment這將產(chǎn)生以下結(jié)果:
Hello, Python!注釋可能會(huì)在聲明中表達(dá)或同一行之后:
name = "Madisetti" # This is again comment你可以使用多行注釋如下:
# This is a comment. # This is a comment, too. # This is a comment, too. # I said that already.使用空行:
一行只含有空格,可能帶有注釋,如果是空行那么Python完全忽略它。
在交互式解釋器會(huì)話(huà)中,必須輸入一個(gè)空的物理行終止多行語(yǔ)句。
等待用戶(hù):
程序的下面一行顯示的提示,按回車(chē)鍵退出,等待用戶(hù)按下回車(chē)鍵:
#!/usr/bin/pythonraw_input("\n\nPress the enter key to exit.")在這里,“\n\n已”被用來(lái)顯示實(shí)際行之前創(chuàng)建兩個(gè)換行。一旦用戶(hù)按下鍵時(shí),程序結(jié)束。這是一個(gè)很好的技巧,保持一個(gè)控制臺(tái)窗口打開(kāi),直到用戶(hù)完成應(yīng)用程序運(yùn)行。
在一行中多個(gè)語(yǔ)句:
分號(hào)( ; ) 允許在單行寫(xiě)入多條語(yǔ)句,不管語(yǔ)句是否啟動(dòng)一個(gè)新的代碼塊。下面是使用分號(hào)示例:
import sys; x = 'foo'; sys.stdout.write(x + '\n')多個(gè)語(yǔ)句組作為套件:
一組單獨(dú)的語(yǔ)句,在Python單一的代碼塊被稱(chēng)為序列。復(fù)雜的語(yǔ)句,如if, while, def, and class,那些需要一個(gè)標(biāo)題行和套件。
標(biāo)題行開(kāi)始的聲明(與關(guān)鍵字),并終止與冒號(hào)(:)),接著是一個(gè)或多個(gè)線(xiàn)構(gòu)成該套件。例如:
if expression : suite elif expression : suite else : suite命令行參數(shù):
我們可能已經(jīng)看到了,比如,很多程序可以運(yùn)行,它們提供有關(guān)如何運(yùn)行的一些基本信息。 Python中可以使用 -h 做到這一點(diǎn):
$ python -h usage: python [option] ... [-c cmd | -m mod | file | -] [arg] ... Options and arguments (and corresponding environment variables): -c cmd : program passed in as string (terminates option list) -d : debug output from parser (also PYTHONDEBUG=x) -E : ignore environment variables (such as PYTHONPATH) -h : print this help message and exit[ etc. ]您也可以設(shè)定您的腳本,它應(yīng)該以這樣的方式接受各種選項(xiàng)。??命令行參數(shù)是一個(gè)高級(jí)主題并在以后學(xué)習(xí),當(dāng)您通過(guò)其它的Python概念后。
Python變量類(lèi)型
變量是只不過(guò)保留的內(nèi)存位置用來(lái)存儲(chǔ)值。這意味著,當(dāng)創(chuàng)建一個(gè)變量,那么它在內(nèi)存中保留一些空間。
根據(jù)一個(gè)變量的數(shù)據(jù)類(lèi)型,解釋器分配內(nèi)存,并決定如何可以被存儲(chǔ)在所保留的內(nèi)存中。因此,通過(guò)分配不同的數(shù)據(jù)類(lèi)型的變量,你可以存儲(chǔ)整數(shù),小數(shù)或字符在這些變量中。
變量賦值:
Python的變量不必顯式地聲明保留的存儲(chǔ)器空間。當(dāng)分配一個(gè)值給一個(gè)變量的聲明將自動(dòng)發(fā)生。等號(hào)(=)來(lái)賦值給變量。
操作數(shù)=操作符的左邊是變量,操作數(shù)=操作符的右側(cè)的名稱(chēng)在變量中存儲(chǔ)的值。例如:
#!/usr/bin/pythoncounter = 100 # An integer assignment miles = 1000.0 # A floating point name = "John" # A stringprint counter print miles print name在這里,分配值100,1000.0和“John”分別給變量counter,miles和respectively。當(dāng)運(yùn)行這個(gè)程序,這將產(chǎn)生以下結(jié)果:
100 1000.0 John多重賦值:
Python允許您同時(shí)指定一個(gè)值給幾個(gè)變量。例如:
a = b = c = 1這里,整數(shù)對(duì)象創(chuàng)建的值1,并且所有三個(gè)變量被分配到相同的內(nèi)存位置。您也可以將多個(gè)對(duì)象分別到多個(gè)變量。例如:
a, b, c = 1, 2, "john"這里,兩個(gè)整對(duì)象用值1和2分配給變量a和b,并且值為“john”的字符串對(duì)象被分配到變量c。
標(biāo)準(zhǔn)的數(shù)據(jù)類(lèi)型:
存儲(chǔ)在內(nèi)存中的數(shù)據(jù)可以是多種類(lèi)型的。例如,一個(gè)人的年齡被存儲(chǔ)為一個(gè)數(shù)字值和他的地址被存儲(chǔ)為字母數(shù)字字符。Python用于對(duì)每個(gè)人的操作的各種標(biāo)準(zhǔn)類(lèi)型定義在存儲(chǔ)方法。
Python有五個(gè)標(biāo)準(zhǔn)的數(shù)據(jù)類(lèi)型:
-
數(shù)字
-
字符串
-
列表
-
元組
-
字典
Python數(shù)字:
數(shù)字?jǐn)?shù)據(jù)類(lèi)型存儲(chǔ)數(shù)值。它們是不可變的數(shù)據(jù)類(lèi)型,這意味著改變一個(gè)新分配的對(duì)象的數(shù)字?jǐn)?shù)據(jù)類(lèi)型的結(jié)果值。
當(dāng)分配一個(gè)值給他們創(chuàng)建的對(duì)象。例如:
var1 = 1 var2 = 10也可以使用del語(yǔ)句刪去有關(guān)一些對(duì)象。 del語(yǔ)句的語(yǔ)法是:
del var1[,var2[,var3[....,varN]]]]也可以使用del語(yǔ)句刪除單個(gè)或多個(gè)對(duì)象。例如:
del var del var_a, var_bPython支持四種不同的數(shù)值類(lèi)型:
-
int (有符號(hào)整數(shù))
-
long (長(zhǎng)整數(shù)[也可以以八進(jìn)制和十六進(jìn)制表示])
-
float (浮點(diǎn)實(shí)數(shù)值)
-
complex (復(fù)數(shù))
例如:
這里是數(shù)字的一些例子:
| 10 | 51924361L | 0.0 | 3.14j |
| 100 | -0x19323L | 15.20 | 45.j |
| -786 | 0122L | -21.9 | 9.322e-36j |
| 080 | 0xDEFABCECBDAECBFBAEl | 32.3+e18 | .876j |
| -0490 | 535633629843L | -90. | -.6545+0J |
| -0x260 | -052318172735L | -32.54e100 | 3e+26J |
| 0x69 | -4721885298529L | 70.2-E12 | 4.53e-7j |
-
Python允許使用一個(gè)小寫(xiě)L表示長(zhǎng)整型,但建議您只使用一個(gè)大寫(xiě)的L到避免和數(shù)字1 長(zhǎng)得一樣不容易分辨,Python顯示長(zhǎng)整數(shù)用一個(gè)大寫(xiě)L。
-
復(fù)數(shù)包含一個(gè)有序?qū)Ρ硎緸閍 + bj,其中,a是實(shí)部,b是復(fù)數(shù)的虛部實(shí)浮點(diǎn)數(shù)。
Python字符串:
在Python中的字符串被確定為一組連續(xù)的字符在引號(hào)之間。 Python允許在任何對(duì)單引號(hào)或雙引號(hào)。串的子集,可以使用切片操作符可采用([]和[:]),索引從0開(kāi)始的字符串的開(kāi)始和結(jié)束(-1)。
加號(hào)(+)符號(hào)的字符串連接操作符,而星號(hào)(*)表示重復(fù)操作。例如:
#!/usr/bin/pythonstr = 'Hello World!'print str # Prints complete string print str[0] # Prints first character of the string print str[2:5] # Prints characters starting from 3rd to 5th print str[2:] # Prints string starting from 3rd character print str * 2 # Prints string two times print str + "TEST" # Prints concatenated string這將產(chǎn)生以下結(jié)果:
Hello World! H llo llo World! Hello World!Hello World! Hello World!TESTPython列表:
列表是最通用的Python復(fù)合數(shù)據(jù)類(lèi)型。列表中包含以逗號(hào)分隔,并在方括號(hào)([])包含的項(xiàng)目。在一定程度上,列表相似C語(yǔ)言中的數(shù)組,它們之間的一個(gè)區(qū)別是,所有屬于一個(gè)列表中的項(xiàng)目可以是不同的數(shù)據(jù)類(lèi)型的。
存儲(chǔ)在一個(gè)列表中的值可以使用切片操作符來(lái)訪(fǎng)問(wèn)([]和[:])用索引從0開(kāi)始,在列表的開(kāi)始位置和結(jié)束為-1。加號(hào)(+)符號(hào)列表連接運(yùn)算符,星號(hào)(*)重復(fù)操作。例如:
#!/usr/bin/pythonlist = [ 'abcd', 786 , 2.23, 'john', 70.2 ] tinylist = [123, 'john']print list # Prints complete list print list[0] # Prints first element of the list print list[1:3] # Prints elements starting from 2nd till 3rd print list[2:] # Prints elements starting from 3rd element print tinylist * 2 # Prints list two times print list + tinylist # Prints concatenated lists這將產(chǎn)生以下結(jié)果:
['abcd', 786, 2.23, 'john', 70.200000000000003] abcd [786, 2.23] [2.23, 'john', 70.200000000000003] [123, 'john', 123, 'john'] ['abcd', 786, 2.23, 'john', 70.200000000000003, 123, 'john']Python元組:
元組是類(lèi)似于列表中的序列數(shù)據(jù)類(lèi)型。一個(gè)元組由數(shù)個(gè)逗號(hào)分隔的值。不同于列表,不過(guò),元組圓括號(hào)括起來(lái)。
列表和元組之間的主要區(qū)別是:列表括在括號(hào)([])和它們的元素和大小是可以改變的,而元組在圓括號(hào)(),不能被更新。元組可以被認(rèn)為是只讀列表。例如:
#!/usr/bin/pythontuple = ( 'abcd', 786 , 2.23, 'john', 70.2 ) tinytuple = (123, 'john')print tuple # Prints complete list print tuple[0] # Prints first element of the list print tuple[1:3] # Prints elements starting from 2nd till 3rd print tuple[2:] # Prints elements starting from 3rd element print tinytuple * 2 # Prints list two times print tuple + tinytuple # Prints concatenated lists這將產(chǎn)生以下結(jié)果:
('abcd', 786, 2.23, 'john', 70.200000000000003) abcd (786, 2.23) (2.23, 'john', 70.200000000000003) (123, 'john', 123, 'john') ('abcd', 786, 2.23, 'john', 70.200000000000003, 123, 'john')以下是元組無(wú)效的,因?yàn)槲覀儑L試更新一個(gè)元組,這是不允許的。類(lèi)似的操作在列表中是可以的:
#!/usr/bin/pythontuple = ( 'abcd', 786 , 2.23, 'john', 70.2 ) list = [ 'abcd', 786 , 2.23, 'john', 70.2 ] tuple[2] = 1000 # Invalid syntax with tuple list[2] = 1000 # Valid syntax with listPython字典:
Python字典是一種哈希表型。他們像關(guān)聯(lián)數(shù)組或哈希在Perl中一樣,由鍵 - 值對(duì)組成。字典鍵幾乎可以是任何Python類(lèi)型,但通常是數(shù)字或字符串。值可以是任意Python的對(duì)象。
字典是由花括號(hào)括號(hào)({}),可分配值,并用方括號(hào)([])訪(fǎng)問(wèn)。例如:
#!/usr/bin/pythondict = {} dict['one'] = "This is one" dict[2] = "This is two"tinydict = {'name': 'john','code':6734, 'dept': 'sales'}print dict['one'] # Prints value for 'one' key print dict[2] # Prints value for 2 key print tinydict # Prints complete dictionary print tinydict.keys() # Prints all the keys print tinydict.values() # Prints all the values這將產(chǎn)生以下結(jié)果:
This is one This is two {'dept': 'sales', 'code': 6734, 'name': 'john'} ['dept', 'code', 'name'] ['sales', 6734, 'john']字典有元素順序的概念。它的元素是無(wú)序的。
數(shù)據(jù)類(lèi)型轉(zhuǎn)換:
有時(shí)候,可能需要執(zhí)行的內(nèi)置類(lèi)型之間的轉(zhuǎn)換。類(lèi)型之間的轉(zhuǎn)換,只需使用類(lèi)名作為函數(shù)。
有幾個(gè)內(nèi)置的功能,從一種數(shù)據(jù)類(lèi)型進(jìn)行轉(zhuǎn)換為另一種。這些函數(shù)返回一個(gè)表示轉(zhuǎn)換值的新對(duì)象。
| int(x [,base]) | 將x轉(zhuǎn)換為一個(gè)整數(shù)。基數(shù)指定為base,如果x是一個(gè)字符串。 |
| long(x [,base] ) | 將x轉(zhuǎn)換為一個(gè)長(zhǎng)整數(shù)。基數(shù)指定為base,如果x是一個(gè)字符串。 |
| float(x) | 將x轉(zhuǎn)換到一個(gè)浮點(diǎn)數(shù)。 |
| complex(real [,imag]) | 創(chuàng)建一個(gè)復(fù)數(shù)。 |
| str(x) | 轉(zhuǎn)換對(duì)象x為字符串表示形式。 |
| repr(x) | 對(duì)象x轉(zhuǎn)換為一個(gè)表達(dá)式字符串。 |
| eval(str) | 計(jì)算一個(gè)字符串,并返回一個(gè)對(duì)象。 |
| tuple(s) | 把s轉(zhuǎn)換為一個(gè)元組。 |
| list(s) | 把s轉(zhuǎn)換為一個(gè)列表。 |
| set(s) | 把s轉(zhuǎn)換為一個(gè)集合。 |
| dict(d) | 創(chuàng)建一個(gè)字典。 d必須的(鍵,值)元組序列。 |
| frozenset(s) | 把s轉(zhuǎn)換為凍結(jié)集。 |
| chr(x) | 整數(shù)轉(zhuǎn)換為一個(gè)字符。 |
| unichr(x) | 整數(shù)轉(zhuǎn)換為一個(gè)Unicode字符。 |
| ord(x) | 轉(zhuǎn)換單個(gè)字符為整數(shù)值。 |
| hex(x) | 將整數(shù)轉(zhuǎn)換為十六進(jìn)制字符串。 |
| oct(x) | 將整數(shù)轉(zhuǎn)換為以八進(jìn)制的字符串。 |
Python 3開(kāi)發(fā)網(wǎng)絡(luò)爬蟲(chóng)(一)
選擇Python版本
有2和3兩個(gè)版本, 3比較新, 聽(tīng)說(shuō)改動(dòng)大. 根據(jù)我在知乎上搜集的觀(guān)點(diǎn)來(lái)看, 我還是傾向于使用”在趨勢(shì)中將會(huì)越來(lái)越火”的版本, 而非”目前已經(jīng)很穩(wěn)定而且很成熟”的版本. 這是個(gè)人喜好, 而且預(yù)測(cè)不一定準(zhǔn)確. 但是如果Python3無(wú)法像Python2那么火, 那么整個(gè)Python語(yǔ)言就不可避免的隨著時(shí)間的推移越來(lái)越落后, 因此我想其實(shí)選哪個(gè)的最壞風(fēng)險(xiǎn)都一樣, 但是最好回報(bào)卻是Python3的大. 其實(shí)兩者區(qū)別也可以說(shuō)大也可以說(shuō)不大, 最終都不是什么大問(wèn)題. 我選擇的是Python 3.
?
選擇參考資料
由于我是一邊學(xué)一邊寫(xiě), 而不是我完全學(xué)會(huì)了之后才開(kāi)始很有條理的寫(xiě), 所以參考資料就很重要(本來(lái)應(yīng)該是個(gè)人開(kāi)發(fā)經(jīng)驗(yàn)很重要, 但我是零基礎(chǔ)).
- Python官方文檔
- 知乎相關(guān)資料(1)?這篇非常好, 通俗易懂的總覽整個(gè)Python學(xué)習(xí)框架.
- 知乎相關(guān)資料(2)
寫(xiě)到這里的時(shí)候, 上面第二第三個(gè)鏈接的票數(shù)第一的回答已經(jīng)看完了, 他們提到的有些部分(比如爬行的路線(xiàn)不能有回路)我就不寫(xiě)了。
?
一個(gè)簡(jiǎn)單的偽代碼
以下這個(gè)簡(jiǎn)單的偽代碼用到了set和queue這兩種經(jīng)典的數(shù)據(jù)結(jié)構(gòu), 集與隊(duì)列. 集的作用是記錄那些已經(jīng)訪(fǎng)問(wèn)過(guò)的頁(yè)面, 隊(duì)列的作用是進(jìn)行廣度優(yōu)先搜索.
queue Q set S StartPoint = "http://jecvay.com" Q.push(StartPoint) # 經(jīng)典的BFS開(kāi)頭 S.insert(StartPoint) # 訪(fǎng)問(wèn)一個(gè)頁(yè)面之前先標(biāo)記他為已訪(fǎng)問(wèn) while (Q.empty() == false) # BFS循環(huán)體T = Q.top() # 并且popfor point in PageUrl(T) # PageUrl(T)是指頁(yè)面T中所有url的集合, point是這個(gè)集合中的一個(gè)元素.if (point not in S)Q.push(point)S.insert(point)這個(gè)偽代碼不能執(zhí)行, ?我覺(jué)得我寫(xiě)的有的不倫不類(lèi), 不類(lèi)Python也不類(lèi)C++.. 但是我相信看懂是沒(méi)問(wèn)題的, 這就是個(gè)最簡(jiǎn)單的BFS結(jié)構(gòu). 我是看了知乎里面的那個(gè)偽代碼之后, 自己用我的風(fēng)格寫(xiě)了一遍. 你也需要用你的風(fēng)格寫(xiě)一遍.
這里用到的Set其內(nèi)部原理是采用了Hash表, 傳統(tǒng)的Hash對(duì)爬蟲(chóng)來(lái)說(shuō)占用空間太大, 因此有一種叫做Bloom Filter的數(shù)據(jù)結(jié)構(gòu)更適合用在這里替代Hash版本的set. 我打算以后再看這個(gè)數(shù)據(jù)結(jié)構(gòu)怎么使用, 現(xiàn)在先跳過(guò), 因?yàn)閷?duì)于零基礎(chǔ)的我來(lái)說(shuō), 這不是重點(diǎn).
代碼實(shí)現(xiàn)(一): 用Python抓取指定頁(yè)面
我使用的編輯器是Idle, 安裝好Python3后這個(gè)編輯器也安裝好了, 小巧輕便, 按一個(gè)F5就能運(yùn)行并顯示結(jié)果. 代碼如下:
#encoding:UTF-8 import urllib.requesturl = "http://www.baidu.com" data = urllib.request.urlopen(url).read() data = data.decode('UTF-8') print(data)
urllib.request是一個(gè)庫(kù), 隸屬u(mài)rllib.?點(diǎn)此打開(kāi)官方相關(guān)文檔. 官方文檔應(yīng)該怎么使用呢? 首先點(diǎn)剛剛提到的這個(gè)鏈接進(jìn)去的頁(yè)面有urllib的幾個(gè)子庫(kù), 我們暫時(shí)用到了request, 所以我們先看urllib.request部分. 首先看到的是一句話(huà)介紹這個(gè)庫(kù)是干什么用的:
The urllib.request module defines functions and classes which help in opening URLs (mostly HTTP) in a complex world — basic and digest authentication, redirections, cookies and more.
然后把我們代碼中用到的urlopen()函數(shù)部分閱讀完.
urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False)
重點(diǎn)部分是返回值, 這個(gè)函數(shù)返回一個(gè) http.client.HTTPResponse 對(duì)象, 這個(gè)對(duì)象又有各種方法, 比如我們用到的read()方法, 這些方法都可以根據(jù)官方文檔的鏈接鏈過(guò)去. 根據(jù)官方文檔所寫(xiě), 我用控制臺(tái)運(yùn)行完畢上面這個(gè)程序后, 又繼續(xù)運(yùn)行如下代碼, 以更熟悉這些亂七八糟的方法是干什么的.
>>> a = urllib.request.urlopen(full_url)
>>> type(a)
<class ‘http.client.HTTPResponse’>
>>> a.geturl()
‘http://www.baidu.com/s?word=Jecvay’
>>> a.info()
<http.client.HTTPMessage object at 0x03272250>
>>> a.getcode()
200
代碼實(shí)現(xiàn)(二): 用Python簡(jiǎn)單處理URL
如果要抓取百度上面搜索關(guān)鍵詞為Jecvay Notes的網(wǎng)頁(yè), 則代碼如下
import urllib import urllib.requestdata={} data['word']='Jecvay Notes'url_values=urllib.parse.urlencode(data) url="http://www.baidu.com/s?" full_url=url+url_valuesdata=urllib.request.urlopen(full_url).read() data=data.decode('UTF-8') print(data)data是一個(gè)字典, 然后通過(guò)urllib.parse.urlencode()來(lái)將data轉(zhuǎn)換為 ‘word=Jecvay+Notes’的字符串, 最后和url合并為full_url, 其余和上面那個(gè)最簡(jiǎn)單的例子相同. 關(guān)于urlencode(), 同樣通過(guò)官方文檔學(xué)習(xí)一下他是干什么的. 通過(guò)查看
Python 3開(kāi)發(fā)網(wǎng)絡(luò)爬蟲(chóng)(二)
上一回, 我學(xué)會(huì)了
這一回, 開(kāi)始用Python將偽代碼中的所有部分實(shí)現(xiàn). 由于文章的標(biāo)題就是”零基礎(chǔ)”, 因此會(huì)先把用到的兩種數(shù)據(jù)結(jié)構(gòu)隊(duì)列和集合介紹一下. 而對(duì)于”正則表達(dá)式“部分, 限于篇幅不能介紹, 但給出我比較喜歡的幾個(gè)參考資料.
Python的隊(duì)列
在爬蟲(chóng)程序中, 用到了廣度優(yōu)先搜索(BFS)算法. 這個(gè)算法用到的數(shù)據(jù)結(jié)構(gòu)就是隊(duì)列.
Python的List功能已經(jīng)足夠完成隊(duì)列的功能, 可以用 append() 來(lái)向隊(duì)尾添加元素, 可以用類(lèi)似數(shù)組的方式來(lái)獲取隊(duì)首元素, 可以用 pop(0) 來(lái)彈出隊(duì)首元素. 但是List用來(lái)完成隊(duì)列功能其實(shí)是低效率的, 因?yàn)長(zhǎng)ist在隊(duì)首使用 pop(0) 和 insert() 都是效率比較低的,?Python官方建議使用collection.deque來(lái)高效的完成隊(duì)列任務(wù).
from collections import deque queue = deque(["Eric", "John", "Michael"]) queue.append("Terry") # Terry 入隊(duì) queue.append("Graham") # Graham 入隊(duì) queue.popleft() # 隊(duì)首元素出隊(duì) #輸出: 'Eric' queue.popleft() # 隊(duì)首元素出隊(duì) #輸出: 'John' queue # 隊(duì)列中剩下的元素 #輸出: deque(['Michael', 'Terry', 'Graham'])(以上例子引用自官方文檔)
Python的集合
在爬蟲(chóng)程序中, 為了不重復(fù)爬那些已經(jīng)爬過(guò)的網(wǎng)站, 我們需要把爬過(guò)的頁(yè)面的url放進(jìn)集合中, 在每一次要爬某一個(gè)url之前, 先看看集合里面是否已經(jīng)存在. 如果已經(jīng)存在, 我們就跳過(guò)這個(gè)url; 如果不存在, 我們先把url放入集合中, 然后再去爬這個(gè)頁(yè)面.
Python提供了set這種數(shù)據(jù)結(jié)構(gòu). set是一種無(wú)序的, 不包含重復(fù)元素的結(jié)構(gòu). 一般用來(lái)測(cè)試是否已經(jīng)包含了某元素, 或者用來(lái)對(duì)眾多元素們?nèi)ブ? 與數(shù)學(xué)中的集合論同樣, 他支持的運(yùn)算有交, 并, 差, 對(duì)稱(chēng)差.
創(chuàng)建一個(gè)set可以用 set() 函數(shù)或者花括號(hào) {} . 但是創(chuàng)建一個(gè)空集是不能使用一個(gè)花括號(hào)的, 只能用 set() 函數(shù). 因?yàn)橐粋€(gè)空的花括號(hào)創(chuàng)建的是一個(gè)字典數(shù)據(jù)結(jié)構(gòu). 以下同樣是Python官網(wǎng)提供的示例.
>>> basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'} >>> print(basket) # 這里演示的是去重功能 {'orange', 'banana', 'pear', 'apple'} >>> 'orange' in basket # 快速判斷元素是否在集合內(nèi) True >>> 'crabgrass' in basket False>>> # 下面展示兩個(gè)集合間的運(yùn)算. ... >>> a = set('abracadabra') >>> b = set('alacazam') >>> a {'a', 'r', 'b', 'c', 'd'} >>> a - b # 集合a中包含元素 {'r', 'd', 'b'} >>> a | b # 集合a或b中包含的所有元素 {'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'} >>> a & b # 集合a和b中都包含了的元素 {'a', 'c'} >>> a ^ b # 不同時(shí)包含于a和b的元素 {'r', 'd', 'b', 'm', 'z', 'l'其實(shí)我們只是用到其中的快速判斷元素是否在集合內(nèi)的功能, 以及集合的并運(yùn)算.
Python的正則表達(dá)式
在爬蟲(chóng)程序中, 爬回來(lái)的數(shù)據(jù)是一個(gè)字符串, 字符串的內(nèi)容是頁(yè)面的html代碼. 我們要從字符串中, 提取出頁(yè)面提到過(guò)的所有url. 這就要求爬蟲(chóng)程序要有簡(jiǎn)單的字符串處理能力, 而正則表達(dá)式可以很輕松的完成這一任務(wù).
參考資料
- 正則表達(dá)式30分鐘入門(mén)教程
- w3cschool 的Python正則表達(dá)式部分
- Python正則表達(dá)式指南
雖然正則表達(dá)式功能異常強(qiáng)大, 很多實(shí)際上用的規(guī)則也非常巧妙, 真正熟練正則表達(dá)式需要比較長(zhǎng)的實(shí)踐鍛煉. 不過(guò)我們只需要掌握如何使用正則表達(dá)式在一個(gè)字符串中, 把所有的url都找出來(lái), 就可以了. 如果實(shí)在想要跳過(guò)這一部分, 可以在網(wǎng)上找到很多現(xiàn)成的匹配url的表達(dá)式, 拿來(lái)用即可.
?
Python網(wǎng)絡(luò)爬蟲(chóng)Ver 1.0 alpha
有了以上鋪墊, 終于可以開(kāi)始寫(xiě)真正的爬蟲(chóng)了. 我選擇的入口地址是Fenng叔的Startup News, 我想Fenng叔剛剛拿到7000萬(wàn)美金融資, 不會(huì)介意大家的爬蟲(chóng)去光臨他家的小站吧. 這個(gè)爬蟲(chóng)雖然可以勉強(qiáng)運(yùn)行起來(lái), 但是由于缺乏異常處理, 只能爬些靜態(tài)頁(yè)面, 也不會(huì)分辨什么是靜態(tài)什么是動(dòng)態(tài), 碰到什么情況應(yīng)該跳過(guò), 所以工作一會(huì)兒就要敗下陣來(lái).
import re import urllib.request import urllibfrom collections import dequequeue = deque() visited = set()url = 'http://news.dbanotes.net' # 入口頁(yè)面, 可以換成別的queue.append(url) cnt = 0while queue:url = queue.popleft() # 隊(duì)首元素出隊(duì)visited |= {url} # 標(biāo)記為已訪(fǎng)問(wèn)print('已經(jīng)抓取: ' + str(cnt) + ' 正在抓取 <--- ' + url)cnt += 1urlop = urllib.request.urlopen(url)if 'html' not in urlop.getheader('Content-Type'):continue# 避免程序異常中止, 用try..catch處理異常try:data = urlop.read().decode('utf-8')except:continue# 正則表達(dá)式提取頁(yè)面中所有隊(duì)列, 并判斷是否已經(jīng)訪(fǎng)問(wèn)過(guò), 然后加入待爬隊(duì)列l(wèi)inkre = re.compile('href=\"(.+?)\"')for x in linkre.findall(data):if 'http' in x and x not in visited:queue.append(x)print('加入隊(duì)列 ---> ' + x)這個(gè)版本的爬蟲(chóng)使用的正則表達(dá)式是
'href=\"(.+?)\"'所以會(huì)把那些.ico或者.jpg的鏈接都爬下來(lái). 這樣read()了之后碰上decode(‘utf-8′)就要拋出異常. 因此我們用getheader()函數(shù)來(lái)獲取抓取到的文件類(lèi)型, 是html再繼續(xù)分析其中的鏈接.
if 'html' not in urlop.getheader('Content-Type'):continue但是即使是這樣, 依然有些網(wǎng)站運(yùn)行decode()會(huì)異常. 因此我們把decode()函數(shù)用try..catch語(yǔ)句包圍住, 這樣他就不會(huì)導(dǎo)致程序中止. 程序運(yùn)行效果圖如下:
爬蟲(chóng)是可以工作了, 但是在碰到連不上的鏈接的時(shí)候, 它并不會(huì)超時(shí)跳過(guò). 而且爬到的內(nèi)容并沒(méi)有進(jìn)行處理, 沒(méi)有獲取對(duì)我們有價(jià)值的信息, 也沒(méi)有保存到本地. 下次我們可以完善這個(gè)alpha版本.
Python3網(wǎng)絡(luò)爬蟲(chóng)(三): 偽裝瀏覽器
上一次我自學(xué)爬蟲(chóng)的時(shí)候, 寫(xiě)了一個(gè)簡(jiǎn)陋的勉強(qiáng)能運(yùn)行的爬蟲(chóng)alpha. alpha版有很多問(wèn)題. 比如一個(gè)網(wǎng)站上不了, 爬蟲(chóng)卻一直在等待連接返回response, 不知道超時(shí)跳過(guò); 或者有的網(wǎng)站專(zhuān)門(mén)攔截爬蟲(chóng)程序, 我們的爬蟲(chóng)也不會(huì)偽裝自己成為瀏覽器正規(guī)部隊(duì); 并且抓取的內(nèi)容沒(méi)有保存到本地, 沒(méi)有什么作用. 這次我們一個(gè)個(gè)解決這些小問(wèn)題.
此外, 在我寫(xiě)這系列文章的第二篇的時(shí)候, 我還是一個(gè)對(duì)http的get和post以及response這些名詞一無(wú)所知的人, 但是我覺(jué)得這樣是寫(xiě)不好爬蟲(chóng)的. 于是我參考了 <<計(jì)算機(jī)網(wǎng)絡(luò)–自頂向下方法>> 這本書(shū)的第二章的大部分內(nèi)容. 如果你也一樣對(duì)http的機(jī)制一無(wú)所知, 我也推薦你找一找這方面的資料來(lái)看. 在看的過(guò)程中, 安裝一個(gè)叫做Fiddler的軟件, 邊學(xué)邊實(shí)踐, 觀(guān)察瀏覽器是如何訪(fǎng)問(wèn)一個(gè)網(wǎng)站的, 如何發(fā)出請(qǐng)求, 如何處理響應(yīng), 如何進(jìn)行跳轉(zhuǎn), 甚至如何通過(guò)登錄認(rèn)證. 有句老話(huà)說(shuō)得好, 越會(huì)用Fiddler, 就對(duì)理論理解更深刻; 越對(duì)理論理解深刻, Fiddler就用得越順手. 最后我們?cè)谟门老x(chóng)去做各種各樣的事情的時(shí)候, Fiddler總是最得力的助手之一.
添加超時(shí)跳過(guò)功能
首先, 我簡(jiǎn)單地將
urlop = urllib.request.urlopen(url)
改為
urlop = urllib.request.urlopen(url, timeout = 2)
運(yùn)行后發(fā)現(xiàn), 當(dāng)發(fā)生超時(shí), 程序因?yàn)閑xception中斷. 于是我把這一句也放在try .. except 結(jié)構(gòu)里, 問(wèn)題解決.
?
支持自動(dòng)跳轉(zhuǎn)
在爬 http://baidu.com 的時(shí)候, 爬回來(lái)一個(gè)沒(méi)有什么內(nèi)容的東西, 這個(gè)東西告訴我們應(yīng)該跳轉(zhuǎn)到 http://www.baidu.com . 但是我們的爬蟲(chóng)并不支持自動(dòng)跳轉(zhuǎn), 現(xiàn)在我們來(lái)加上這個(gè)功能, 讓爬蟲(chóng)在爬 baidu.com 的時(shí)候能夠抓取 www.baidu.com 的內(nèi)容.
首先我們要知道爬 http://baidu.com 的時(shí)候他返回的頁(yè)面是怎么樣的, 這個(gè)我們既可以用 Fiddler 看, 也可以寫(xiě)一個(gè)小爬蟲(chóng)來(lái)抓取. 這里我抓到的內(nèi)容如下, 你也應(yīng)該嘗試一下寫(xiě)幾行 python 來(lái)抓一抓.
<html>
<meta http-equiv=”refresh” content=”0;url=http://www.baidu.com/”>
</html>
看代碼我們知道這是一個(gè)利用 html 的 meta 來(lái)刷新與重定向的代碼, 其中的0是等待0秒后跳轉(zhuǎn), 也就是立即跳轉(zhuǎn). 這樣我們?cè)傧裆弦淮握f(shuō)的那樣用一個(gè)正則表達(dá)式把這個(gè)url提取出來(lái)就可以爬到正確的地方去了. 其實(shí)我們上一次寫(xiě)的爬蟲(chóng)已經(jīng)可以具有這個(gè)功能, 這里只是單獨(dú)拿出來(lái)說(shuō)明一下 http 的 meta 跳轉(zhuǎn).
偽裝瀏覽器正規(guī)軍
前面幾個(gè)小內(nèi)容都寫(xiě)的比較少. 現(xiàn)在詳細(xì)研究一下如何讓網(wǎng)站們把我們的Python爬蟲(chóng)當(dāng)成正規(guī)的瀏覽器來(lái)訪(fǎng). 因?yàn)槿绻贿@么偽裝自己, 有的網(wǎng)站就爬不回來(lái)了. 如果看過(guò)理論方面的知識(shí), 就知道我們是要在 GET 的時(shí)候?qū)?User-Agent 添加到header里.
如果沒(méi)有看過(guò)理論知識(shí), 按照以下關(guān)鍵字搜索學(xué)習(xí)吧 :D
- HTTP 報(bào)文分兩種:?請(qǐng)求報(bào)文和響應(yīng)報(bào)文
- 請(qǐng)求報(bào)文的請(qǐng)求行與首部行
- GET,?POST, HEAD, PUT, DELETE 方法
我用 IE 瀏覽器訪(fǎng)問(wèn)百度首頁(yè)的時(shí)候, 瀏覽器發(fā)出去的請(qǐng)求報(bào)文如下:
GET http://www.baidu.com/ HTTP/1.1
Accept: text/html, application/xhtml+xml, */*
Accept-Language: en-US,en;q=0.8,zh-Hans-CN;q=0.5,zh-Hans;q=0.3
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko
Accept-Encoding: gzip, deflate
Host: www.baidu.com
DNT: 1
Connection: Keep-Alive
Cookie: BAIDUID=57F4D171573A6B88A68789EF5DDFE87:FG=1; uc_login_unique=ccba6e8d978872d57c7654130e714abd; BD_UPN=11263145; BD
然后百度收到這個(gè)消息后, 返回給我的的響應(yīng)報(bào)文如下(有刪節(jié)):
HTTP/1.1 200 OK
Date: Mon, 29 Sep 2014 13:07:01 GMT
Content-Type: text/html; charset=utf-8
Connection: Keep-Alive
Vary: Accept-Encoding
Cache-Control: private
Cxy_all: baidu+8b13ba5a7289a37fb380e0324ad688e7
Expires: Mon, 29 Sep 2014 13:06:21 GMT
X-Powered-By: HPHP
Server: BWS/1.1
BDPAGETYPE: 1
BDQID: 0x8d15bb610001fe79
BDUSERID: 0
Set-Cookie: BDSVRTM=0; path=/
Set-Cookie: BD_HOME=0; path=/
Content-Length: 80137
<!DOCTYPE html><!–STATUS OK–><html><head><meta http-equiv=”content-type” content=”text/html;charset=utf-8″><meta http-equiv=”X-UA-Compatible” content=”IE=Edge”><link rel=”dns-prefetch” href=”//s1.bdstatic.com”/><link rel=”dns-prefetch” href=”//t1.baidu.com”/><link rel=”dns-prefetch” href=”//t2.baidu.com”/><link rel=”dns-prefetch” href=”//t3.baidu.com”/><link rel=”dns-prefetch” href=”//t10.baidu.com”/><link rel=”dns-prefetch” href=”//t11.baidu.com”/><link rel=”dns-prefetch” href=”//t12.baidu.com”/><link rel=”dns-prefetch” href=”//b1.bdstatic.com”/><title>百度一下,你就知道</title><style index=”index” > ……….這里省略?xún)扇f(wàn)字…………….?</script></body></html>
如果能夠看懂這段話(huà)的第一句就OK了, 別的可以以后再配合 Fiddler 慢慢研究. 所以我們要做的就是在 Python 爬蟲(chóng)向百度發(fā)起請(qǐng)求的時(shí)候, 順便在請(qǐng)求里面寫(xiě)上 User-Agent, 表明自己是瀏覽器君.
在 GET 的時(shí)候添加 header 有很多方法, 下面介紹兩種方法.
第一種方法比較簡(jiǎn)便直接, 但是不好擴(kuò)展功能, 代碼如下:
import urllib.requesturl = 'http://www.baidu.com/' req = urllib.request.Request(url, headers = {'Connection': 'Keep-Alive','Accept': 'text/html, application/xhtml+xml, */*','Accept-Language': 'en-US,en;q=0.8,zh-Hans-CN;q=0.5,zh-Hans;q=0.3','User-Agent': 'Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko' }) oper = urllib.request.urlopen(req) data = oper.read() print(data.decode())?
第二種方法使用了 build_opener 這個(gè)方法, 用來(lái)自定義 opener, 這種方法的好處是可以方便的拓展功能, 例如下面的代碼就拓展了自動(dòng)處理?Cookies 的功能.
import urllib.request import http.cookiejar# head: dict of header def makeMyOpener(head = {'Connection': 'Keep-Alive','Accept': 'text/html, application/xhtml+xml, */*','Accept-Language': 'en-US,en;q=0.8,zh-Hans-CN;q=0.5,zh-Hans;q=0.3','User-Agent': 'Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko' }):cj = http.cookiejar.CookieJar()opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))header = []for key, value in head.items():elem = (key, value)header.append(elem)opener.addheaders = headerreturn openeroper = makeMyOpener() uop = oper.open('http://www.baidu.com/', timeout = 1000) data = uop.read() print(data.decode())上述代碼運(yùn)行后通過(guò) Fiddler 抓到的 GET 報(bào)文如下所示:
GET http://www.baidu.com/ HTTP/1.1
Accept-Encoding: identity
Connection: close
Host: www.baidu.com
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko
Accept: text/html, application/xhtml+xml, */*
Accept-Language: en-US,en;q=0.8,zh-Hans-CN;q=0.5,zh-Hans;q=0.3
可見(jiàn)我們?cè)诖a里寫(xiě)的東西都添加到請(qǐng)求報(bào)文里面了.
保存抓回來(lái)的報(bào)文
順便說(shuō)說(shuō)文件操作. Python 的文件操作還是相當(dāng)方便的. 我們可以講抓回來(lái)的數(shù)據(jù) data 以二進(jìn)制形式保存, 也可以經(jīng)過(guò) decode() 處理成為字符串后以文本形式保存. 改動(dòng)一下打開(kāi)文件的方式就能用不同的姿勢(shì)保存文件了. 下面是參考代碼:
def saveFile(data):save_path = 'D:\\temp.out'f_obj = open(save_path, 'wb') # wb 表示打開(kāi)方式f_obj.write(data)f_obj.close()# 這里省略爬蟲(chóng)代碼 # ...# 爬到的數(shù)據(jù)放到 dat 變量里 # 將 dat 變量保存到 D 盤(pán)下 saveFile(dat)?
下回我們會(huì)用 Python 來(lái)爬那些需要登錄之后才能看到的信息. 在那之前, 我已經(jīng)對(duì) Fiddler 稍微熟悉了. 希望一起學(xué)習(xí)的也提前安裝個(gè)?Fiddler 玩一下.Python3網(wǎng)絡(luò)爬蟲(chóng)(四): 登錄
今天的工作很有意思, 我們用 Python 來(lái)登錄網(wǎng)站, 用Cookies記錄登錄信息, 然后就可以抓取登錄之后才能看到的信息. 今天我們拿知乎網(wǎng)來(lái)做示范. 為什么是知乎? 這個(gè)很難解釋, 但是肯定的是知乎這么大這么成功的網(wǎng)站完全不用我來(lái)幫他打廣告. 知乎網(wǎng)的登錄比較簡(jiǎn)單, 傳輸?shù)臅r(shí)候沒(méi)有對(duì)用戶(hù)名和密碼加密, 卻又不失代表性, 有一個(gè)必須從主頁(yè)跳轉(zhuǎn)登錄的過(guò)程.
不得不說(shuō)一下, Fiddler 這個(gè)軟件是?Tpircsboy?告訴我的. 感謝他給我?guī)?lái)這么好玩的東西.
第一步: 使用 Fiddler 觀(guān)察瀏覽器行為
在開(kāi)著 Fiddler 的條件下運(yùn)行瀏覽器, 輸入知乎網(wǎng)的網(wǎng)址 http://www.zhihu.com 回車(chē)后到 Fiddler 中就能看到捕捉到的連接信息. 在左邊選中一條 200 連接, 在右邊打開(kāi) Inspactors 透視圖, 上方是該條連接的請(qǐng)求報(bào)文信息, 下方是響應(yīng)報(bào)文信息.
其中 Raw 標(biāo)簽是顯示報(bào)文的原文. 下方的響應(yīng)報(bào)文很有可能是沒(méi)有經(jīng)過(guò)解壓或者解碼的, 這種情況他會(huì)在中間部位有一個(gè)小提示, 點(diǎn)擊一下就能解碼顯示出原文了.
?
以上這個(gè)截圖是在未登錄的時(shí)候進(jìn)入 http://www.zhihu.com 得到的. 現(xiàn)在我們來(lái)輸入用戶(hù)名和密碼登陸知乎網(wǎng), 再看看瀏覽器和知乎服務(wù)器之間發(fā)生了什么.
?
點(diǎn)擊登陸后, 回到 Fiddler 里查看新出現(xiàn)的一個(gè) 200 鏈接. 我們?yōu)g覽器攜帶者我的帳號(hào)密碼給知乎服務(wù)器發(fā)送了一個(gè) POST, 內(nèi)容如下:
POST http://www.zhihu.com/login HTTP/1.1
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Accept: */*
X-Requested-With: XMLHttpRequest
Referer: http://www.zhihu.com/#signin
Accept-Language: en-US,en;q=0.8,zh-Hans-CN;q=0.5,zh-Hans;q=0.3
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (Windows NT 6.4; WOW64; Trident/7.0; rv:11.0) like Gecko
Content-Length: 97
DNT: 1
Host: www.zhihu.com
Connection: Keep-Alive
Pragma: no-cache
Cookie: __utma=51854390.1539896551.1412320246.1412320246.1412320246.1; __utmb=51854390.6.10.1412320246; __utmc=51854390; __utmz=51854390.1412320246.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utmv=51854390.000–|3=entry_date=20141003=1
_xsrf=4b41f6c7a9668187ccd8a610065b9718&email=此處涂黑%40gmail.com&password=此處不可見(jiàn)&rememberme=y
截圖如下:
我的瀏覽器給 http://www.zhihu.com/login 這個(gè)網(wǎng)址(多了一個(gè)/login) 發(fā)送了一個(gè)POST, 內(nèi)容都已經(jīng)在上面列出來(lái)了, 有用戶(hù)名, 有密碼, 有一個(gè)”記住我”的 yes, 其中這個(gè) WebForms 標(biāo)簽下 Fiddler 能夠比較井井有條的列出來(lái) POST 的內(nèi)容. 所以我們用 Python 也發(fā)送相同的內(nèi)容就能登錄了. 但是這里出現(xiàn)了一個(gè) Name 為 _xsrf 的項(xiàng), 他的值是?4b41f6c7a9668187ccd8a610065b9718. 我們要先獲取這個(gè)值, 然后才能給他發(fā).
瀏覽器是如何獲取的呢, 我們剛剛是先訪(fǎng)問(wèn)了 http://www.zhihu.com/ 這個(gè)網(wǎng)址, 就是首頁(yè), 然后登錄的時(shí)候他卻給 http://www.zhihu.com/login 這個(gè)網(wǎng)址發(fā)信息. 所以用偵探一般的思維去思考這個(gè)問(wèn)題, 就會(huì)發(fā)現(xiàn)肯定是首頁(yè)把 _xsrf 生成發(fā)送給我們, 然后我們?cè)侔堰@個(gè) _xsrf 發(fā)送給 /login 這個(gè) url. 這樣一會(huì)兒過(guò)后我們就要從第一個(gè) GET 得到的響應(yīng)報(bào)文里面去尋找 _xsrf
截圖下方的方框說(shuō)明, 我們不僅登錄成功了, 而且服務(wù)器還告訴我們的瀏覽器如何保存它給出的 Cookies 信息. 所以我們也要用 Python 把這些 Cookies 信息記錄下來(lái).
這樣 Fiddler 的工作就基本結(jié)束了!
第二步: 解壓縮
簡(jiǎn)單的寫(xiě)一個(gè) GET 程序, 把知乎首頁(yè) GET 下來(lái), 然后 decode() 一下解碼, 結(jié)果報(bào)錯(cuò). 仔細(xì)一看, 發(fā)現(xiàn)知乎網(wǎng)傳給我們的是經(jīng)過(guò) gzip 壓縮之后的數(shù)據(jù). 這樣我們就需要先對(duì)數(shù)據(jù)解壓. Python 進(jìn)行 gzip 解壓很方便, 因?yàn)閮?nèi)置有庫(kù)可以用. 代碼片段如下:
import gzip def ungzip(data):try: # 嘗試解壓print('正在解壓.....')data = gzip.decompress(data)print('解壓完畢!')except:print('未經(jīng)壓縮, 無(wú)需解壓')return data通過(guò) opener.read() 讀取回來(lái)的數(shù)據(jù), 經(jīng)過(guò) ungzip 自動(dòng)處理后, 再來(lái)一遍 decode() 就可以得到解碼后的 str 了
第二步: 使用正則表達(dá)式獲取沙漠之舟
_xsrf 這個(gè)鍵的值在茫茫無(wú)際的互聯(lián)網(wǎng)沙漠之中指引我們用正確的姿勢(shì)來(lái)登錄知乎, 所以 _xsrf 可謂沙漠之舟. 如果沒(méi)有 _xsrf, 我們或許有用戶(hù)名和密碼也無(wú)法登錄知乎(我沒(méi)試過(guò), 不過(guò)我們學(xué)校的教務(wù)系統(tǒng)確實(shí)如此) 如上文所說(shuō), 我們?cè)诘谝槐?GET 的時(shí)候可以從響應(yīng)報(bào)文中的 HTML 代碼里面得到這個(gè)沙漠之舟. 如下函數(shù)實(shí)現(xiàn)了這個(gè)功能, 返回的 str 就是 _xsrf 的值.
import re def getXSRF(data):cer = re.compile('name=\"_xsrf\" value=\"(.*)\"', flags = 0)strlist = cer.findall(data)return strlist[0]?
第三步: 發(fā)射 POST !!
集齊 _xsrf, id, password 三大法寶, 我們可以發(fā)射 POST 了. 這個(gè) POST 一旦發(fā)射過(guò)去, 我們就登陸上了服務(wù)器, 服務(wù)器就會(huì)發(fā)給我們 Cookies. 本來(lái)處理 Cookies 是個(gè)麻煩的事情, 不過(guò) Python 的 http.cookiejar 庫(kù)給了我們很方便的解決方案, 只要在創(chuàng)建 opener 的時(shí)候?qū)⒁粋€(gè) HTTPCookieProcessor 放進(jìn)去, Cookies 的事情就不用我們管了. 下面的代碼體現(xiàn)了這一點(diǎn).
import http.cookiejar import urllib.request def getOpener(head):# deal with the Cookiescj = http.cookiejar.CookieJar()pro = urllib.request.HTTPCookieProcessor(cj)opener = urllib.request.build_opener(pro)header = []for key, value in head.items():elem = (key, value)header.append(elem)opener.addheaders = headerreturn openergetOpener 函數(shù)接收一個(gè) head 參數(shù), 這個(gè)參數(shù)是一個(gè)字典. 函數(shù)把字典轉(zhuǎn)換成元組集合, 放進(jìn) opener. 這樣我們建立的這個(gè) opener 就有兩大功能:
第四部: 正式運(yùn)行
正式運(yùn)行還差一點(diǎn)點(diǎn), 我們要把要 POST 的數(shù)據(jù)弄成 opener.open() 支持的格式. 所以還要 ?urllib.parse 庫(kù)里的 urlencode() 函數(shù). 這個(gè)函數(shù)可以把 字典 或者 元組集合 類(lèi)型的數(shù)據(jù)轉(zhuǎn)換成 & 連接的 str.
str 還不行, 還要通過(guò) encode() 來(lái)編碼, 才能當(dāng)作 opener.open() 或者 urlopen() 的 POST 數(shù)據(jù)參數(shù)來(lái)使用. 代碼如下:
url = 'http://www.zhihu.com/' opener = getOpener(header) op = opener.open(url) data = op.read() data = ungzip(data) # 解壓 _xsrf = getXSRF(data.decode())url += 'login' id = '這里填你的知乎帳號(hào)' password = '這里填你的知乎密碼' postDict = {'_xsrf':_xsrf,'email': id,'password': password,'rememberme': 'y' } postData = urllib.parse.urlencode(postDict).encode() op = opener.open(url, postData) data = op.read() data = ungzip(data)print(data.decode()) # 你可以根據(jù)你的喜歡來(lái)處理抓取回來(lái)的數(shù)據(jù)了!代碼運(yùn)行后, 我們發(fā)現(xiàn)自己關(guān)注的人的動(dòng)態(tài)(顯示在登陸后的知乎首頁(yè)的那些), 都被抓取回來(lái)了. 下一步做一個(gè)統(tǒng)計(jì)分析器, 或者自動(dòng)推送器, 或者內(nèi)容分級(jí)自動(dòng)分類(lèi)器, 都可以.
完整代碼如下:
import gzip import re import http.cookiejar import urllib.request import urllib.parsedef ungzip(data):try: # 嘗試解壓print('正在解壓.....')data = gzip.decompress(data)print('解壓完畢!')except:print('未經(jīng)壓縮, 無(wú)需解壓')return datadef getXSRF(data):cer = re.compile('name=\"_xsrf\" value=\"(.*)\"', flags = 0)strlist = cer.findall(data)return strlist[0]def getOpener(head):# deal with the Cookiescj = http.cookiejar.CookieJar()pro = urllib.request.HTTPCookieProcessor(cj)opener = urllib.request.build_opener(pro)header = []for key, value in head.items():elem = (key, value)header.append(elem)opener.addheaders = headerreturn openerheader = {'Connection': 'Keep-Alive','Accept': 'text/html, application/xhtml+xml, */*','Accept-Language': 'en-US,en;q=0.8,zh-Hans-CN;q=0.5,zh-Hans;q=0.3','User-Agent': 'Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko','Accept-Encoding': 'gzip, deflate','Host': 'www.zhihu.com','DNT': '1' }url = 'http://www.zhihu.com/' opener = getOpener(header) op = opener.open(url) data = op.read() data = ungzip(data) # 解壓 _xsrf = getXSRF(data.decode())url += 'login' id = '這里填你的知乎帳號(hào)' password = '這里填你的知乎密碼' postDict = {'_xsrf':_xsrf,'email': id,'password': password,'rememberme': 'y' } postData = urllib.parse.urlencode(postDict).encode() op = opener.open(url, postData) data = op.read() data = ungzip(data)print(data.decode())創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)
總結(jié)
以上是生活随笔為你收集整理的python 基础知识点整理 和具体应用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 摇滚手势(我爱你和rock手势区别)
- 下一篇: Python-matplotlib用法