Python爬蟲從入門到精通系列──第1課 基礎知識
本教程所有原始碼下載連結:https://share.weiyun.com/5xmFeUO 密碼:fzwh6g
本教程首發於GitOPEN's Home,轉載請徵求作者同意
基礎知識
環境搭建
Python安裝
平時能接觸到的作業系統非Windows、macOS、Linux莫屬。其中Windows是我們日常中最常用的OS,它軟體更多、辦公和遊戲可以兼得;macOS由於搭載其的電腦外表漂亮、螢幕優秀、效能均衡,而被很多設計者和程式設計師所喜愛;Linux在伺服器領域是無可匹敵,幾乎所有大型應用伺服器都部署於Linux系統,常用的Linux伺服器系統有CentOS、Ubuntu Server等,但是Linux桌面版也在程式設計師中應用較廣,便捷的終端、穩定的效能是程式設計的首選。
由於macOS和Ubuntu系統都自帶python環境,因此,我們只講解Windows下Python的安裝和配置。感興趣的同學,可以自己在虛擬機器中測試和熟悉Linux系統,推薦Ubuntu18.04。
Windows下安裝Python
熟悉一下Python的主頁:
下載。官方的最新版已經更新到了3.7.0,但是我們下載的版本是Python3.6.5,因此,我們點選View the full list of downloads。
只需要記住,不同架構的Windows系統,選擇不同的安裝包下載。
安裝。按圖示操作即可。
-
雙擊安裝包,選擇自定義安裝,方便以後使用。
-
直接下一步。
-
修改路徑,將路徑改為
c:\Python36
。 -
安裝成功
環境變數檢測與設定。
-
開啟cmd命令列。
-
輸入
python
,提示python版本等資訊表示環境變數設定成功。 -
如果輸入python後,提示不是內部命令或外部命令,則表示環境變數沒有配置好。
設定環境變數。
-
桌面右擊
計算機
?️,選擇屬性,然後,再次選擇高階系統設定。
-
在
高階
一欄中點選環境變數
,開啟環境變數
設定視窗。 -
點選
新建
,在變數名中輸入PATH
(大寫),在變數值中輸入C:\Python36\Scripts\;C:\Python36\
,C:\Python36\Scripts\
資料夾下有一些常用工具,例如pip
包管理工具,也加入到環境變數中,這樣方便以後使用;C:\Python36\
就是python的安裝目錄。 將cmd命令列都關閉,重新開啟cmd,再次輸入
python
進行驗證。
Python環境到這裡就安裝完畢了。
包管理工具pip
pip是Python的一款包管理工具,由於眾所周知的原因,用pip安裝庫的速度簡直是“是可忍孰不可忍”。因此,我們有必要加速pip包管理工具的下載速度。
pip的基本使用
Windows中,開啟cmd命令列,輸入pip
後,可以看到使用方法:
# 搜尋requests包
pip search requests
# 升級requests包
pip install requests --upgrade
# 解除安裝requests包
pip uninstall requests
# 檢視待更新包
pip list --outdate
升級pip包管理器
python -m pip install --upgrade pip
加速pip下載速度
在某程式設計師論壇上,有這樣一個軟笑話:《安裝scrapy快瘋了,一個下午沒了》?️
我們使用清華大學開源軟體映象站的pypi映象進行pip下載加速。
臨時加速
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple requests
注意,
simple
不能少,是https
而不是http
永久加速1
修改
~/.config/pip/pip.conf
(Linux),
%APPDATA%\pip\pip.ini
(Windows 10) ,
C:\Users\Administrator\AppData\Roaming\pip\pip.ini
(Windows7),
$HOME/Library/Application Support/pip/pip.conf
(macOS) (沒有就建立一個),
修改 index-url
至tuna,例如
[global]
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
pip 和 pip3 並存時,只需修改 ~/.pip/pip.conf
。
永久加速2
使用指令碼永久加速,只需用Python執行oh-my-tuna.py
檔案即可設定好映象站加速,
該指令碼在我們的原始碼中有提供,位置為CrawlerLessons/codes/lesson01/oh-my-tuna.py
,下載後,直接在命令列中執行即可:
python on-my-tuna.py
安裝IPython
ipython
是一個python
的互動式shell
,比預設的python shell
好用得多,支援變數自動補全,自動縮排,支援bash shell
命令,內建了許多很有用的功能和函式。學習ipython
將會讓我們以一種更高的效率來使用python
。同時它也是利用Python進行科學計算和互動視覺化的一個最佳的平臺。
使用pip
安裝IPython
:
pip install ipython
使用IPython
,再命令列中輸入ipython
即可進入互動式shell
:
╭─sunjiajia@Mac /Users/sunjiajia ‹system›
╰─$ ipython
Python 3.6.5 (default, Jul 2 2018, 18:32:34)
Type 'copyright', 'credits' or 'license' for more information
IPython 6.4.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]:
IDE 的選擇
在以後的程式設計中,我們使用PyCharm
這款享譽全球的IDE,開發、除錯、支援網頁開發和支援資料庫,可以滿足我們幾乎所有的開發需求。
PyCharm
是收費軟體,但也提供社群免費版本,雖然功能有所減少,但是也夠我們後續寫爬蟲了。
PyCharm
下載地址:官方網址。
PyCharm的基本使用
建立專案:
選擇專案路徑:
建立Python檔案,命名為test01.py
:
在test01.py
中輸入以下python程式碼,右擊空白處,選擇Run test01
,執行當前python檔案:
PyCharm常用設定項如圖所示:
HTML和CSS基礎知識
這一節我們學習網頁程式設計的基礎知識。這節課目標是,瞭解網頁的基本知識,在寫爬蟲的時候可以清晰的分析目標資料所在的結構,從而更輕鬆的拿到自己想要的資料。
無論是動態載入,還是延遲載入,無論是文字還是多媒體,最終在瀏覽器中展示給我們,都是以HTML語法來展示;無論是絢麗的動畫頁面效果,還是表格的樣式,都可以用CSS來進行定製。
下面來一個概念簡介,來自百度百科的內容:
HTML,即超文字標記語言(英語:HyperText Markup Language),是標準通用標記語言下的一個應用,也是一種規範,一種標準,它通過標記符號來標記要顯示的網頁中的各個部分。網頁檔案本身是一種文字檔案,通過在文字檔案中新增標記符,可以告訴瀏覽器如何顯示其中的內容(如:文字如何處理,畫面如何安排,圖片如何顯示等)。
CSS,即層疊樣式表(英文全稱:Cascading Style Sheets),是一種用來表現HTML或XML等檔案樣式的計算機語言。CSS不僅可以靜態地修飾網頁,還可以配合各種指令碼語言動態地對網頁各元素進行格式化。
HTML基本標籤
標籤名 | 含義 |
---|---|
<!--...--> |
註釋標籤用於在原始碼中插入註釋。註釋不會顯示在瀏覽器中。 |
<!DOCTYPE> |
<!DOCTYPE> 宣告必須是 HTML 文件的第一行,位於 <html> 標籤之前。<!DOCTYPE> 宣告不是 HTML 標籤;它是指示 web 瀏覽器關於頁面使用哪個 HTML 版本進行編寫的指令。在 HTML5 中只有一種寫法<!DOCTYPE html>
|
<html> |
<html> 與 </html> 標籤限定了文件的開始點和結束點,在它們之間是文件的頭部和主體。正如您所瞭解的那樣,文件的頭部由 <head> 標籤定義,而主體由<body> 標籤定義。 |
<head> |
用於定義文件的頭部,它是所有頭部元素的容器。<head> 中的元素可以引用指令碼、指示瀏覽器在哪裡找到樣式表、提供元資訊等等。 |
<meta> |
提供有關頁面的元資訊(meta-information),比如針對搜尋引擎和更新頻度的描述和關鍵詞。 |
<title> |
定義文件的標題。 |
<style> |
用於為 HTML 文件定義樣式資訊。type 屬性是必需的,定義 style 元素的內容。唯一可能的值是 "text/css" 。 |
<link> |
定義文件與外部資源的關係,最常見的用途是連結樣式表。 |
<body> |
body 元素定義文件的主體,包含文件的所有內容(比如文字、超連結、影象、表格和列表等等。) |
| |
HTML常用標籤
標籤名 | 含義 |
---|---|
<a href="http://news.baidu.com/" target="_blank">新聞</a> |
定義超連結 |
<img src="images/logo.png" alt="GitOPEN搜尋,最貼心搜尋"> |
插入圖片 |
<table border="1"><tr><th>Month</th><th>Savings</th></tr><tr><td>January</td> <td>$100</td></tr></table> |
表格 |
<div>我是div</div> |
可定義文件中的分割槽或節 |
<p><span>some text.</span>some other text.</p> |
被用來組合文件中的行內元素。 |
<ul><li>Coffee</li><li>Milk</li></ul> |
無序列表 |
<ol><li>Coffee</li><li>Milk</li></ol> |
有序列表 |
<input type="button" value="搜尋一下"/> |
用於蒐集使用者資訊。根據不同的 type 屬性值,輸入欄位可以是text 、核取方塊checkbox 、單選按鈕radio 、button 、submit 等等。 |
CSS語法
HTML整合CSS的方式一
直接將css寫在HTML檔案中,程式碼CrawlerLessons/codes/lesson01/HTMLDemo/demo01.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>我是GitOPEN</title>
<style>
#div01 {
background-color: #2d78f4;
}
.div02 {
background-color: cadetblue;
font-style: oblique;
font-weight: bold;
}
</style>
</head>
<body>
<div id="div01">
我是div01,我的樣式使用了id選擇器(div01)
</div>
<div class="div02">
我是div02,我的樣式使用了類選擇器(div02)
</div>
<div class="div02">
我是div03,我的樣式使用了類選擇器(div02)
</div>
</body>
</html>
HTML整合CSS的方式二
css寫在單獨的檔案中,程式碼CrawlerLessons/codes/lesson01/HTMLDemo/demo02.css
#div01 {
background-color: #2d78f4;
}
.div02 {
background-color: cadetblue;
font-style: oblique;
font-weight: bold;
}
html也是一個單獨的檔案,程式碼CrawlerLessons/codes/lesson01/HTMLDemo/demo02.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>我是GitOPEN</title>
<link rel="stylesheet" href="demo02.css">
</head>
<body>
<div id="div01">
我是div01,我的樣式使用了id選擇器(div01)
</div>
<div class="div02">
我是div02,我的樣式使用了類選擇器(div02)
</div>
<div class="div02">
我是div03,我的樣式使用了類選擇器(div02)
</div>
</body>
</html>
CSS常用屬性
屬性名 | 作用 |
---|---|
font-size | 字號大小 |
font-style | 字型格式 |
font-weight | 字型粗細 |
color | 文字顏色 |
text-decoration | 超連結設定。line-through新增刪除線;blink文字閃動;none不顯示上述任何效果 |
background-color | 背景顏色 |
backgroud-image | 背景圖片(地址) |
background-repeat | 是否重複。no-repeat不重複平鋪;repeat-x或者y:只在水平或者垂直方向上平鋪 |
text-align | 文字對齊。left左對齊;right右對齊;center居中對齊;justify:相對左右兩端對齊 |
display | 顯示樣式。block塊級元素,在物件前後都換行;inline在物件前後都不換行;list-item在物件前後都換行,增加了專案符號 |
Python必備知識點
基礎資料型別
變數及其型別的含義
Python中的變數不需要宣告,變數在使用前都必須賦值,在賦值以後,該變數才會被建立。
Python中的變數就是變數,它本身沒有型別,通常所說的“變數型別”,表示的意思是變數所指向的記憶體中物件的型別。
name = 'GitOPEN'
age = 18
salary = 99999.99
等號(=)叫做運算子,用來給變數name
、age
、salary
賦值,左邊是一個變數名,右邊是儲存在變數中的值。
在給變數賦值不同型別的物件,那麼,變數就有了型別。
name
是字串變數,age
是整型變數,salary
是浮點型變數。
多個變數賦值
Python中,可以同時為多個變數賦值:
aa = bb = cc = 11
這個例子的含義為,建立一個整型物件,值為11,從後向前賦值,3個變數都指向同一個記憶體地址。
再看一個例子:
dd, ee, ff = 22, 33, "GitOPEN"
這個例子中,將整型物件22
和33
分別分配給變數dd
和ee
,字串物件GitOPEN
分配給變數ff
。
標準資料型別
- Number(數字)── 不可變資料
- String(字串)──不可變資料
- List(列表)──可變資料
- Tuple(元組)──不可變資料
- Set(集合)──可變資料
- Dictionary(字典)──可變資料
Number(數字)
Python3中的支援int、float、bool、complex(複數)
,在Python3中,只有一種整數型別int
,表示為長整型,沒有python2中的Long。
示例:
In [3]: aa = 1111
In [4]: isinstance(aa, int)
Out[4]: True
數值運算
# 加法運算
In [5]: 11 + 11
Out[5]: 22
# 減法
In [6]: 5.21 - 5.20
Out[6]: 0.009999999999999787
# 減法
In [10]: 4.3 - 2
Out[10]: 2.3
# 取餘
In [11]: 18 % 4
Out[11]: 2
# 乘方
In [12]: 2 ** 5
Out[12]: 32
# 除法,得到一個浮點數
In [13]: 2 / 4
Out[13]: 0.5
# 除法,得到一個整數
In [14]: 2 // 4
Out[14]: 0
# 除法,得到一個整數
In [15]: 5 // 2
Out[15]: 2
- 注意:混合計算時,Python會把整型轉換成為浮點數。
數值型別例項
int | float | complex |
---|---|---|
10 | 0.0 | 3.14j |
100 | 15.20 | 45.j |
-786 | -21.9 | 9.322e-36j |
080 | 32.3e+18 | .876j |
-0490 | -90. | -.6545+0J |
-0x260 | -32.54e100 | 3e+26J |
0x69 | 70.2E-12 | 4.53e-7j |
浮點數誤差
先看一個例子:
In [24]: x = 4.20
In [25]: y = 2.10
In [26]: x + y
Out[26]: 6.300000000000001
In [27]: (x + y) == 6.3
Out[27]: False
In [28]: x = 1.2
In [29]: y = 2.3
In [30]: x + y
Out[30]: 3.5
In [31]: (x + y) == 3.5
Out[31]: True
產生上述問題的原因,就來自於浮點數計算精度問題。
浮點數在計算機中表達為二進位制(binary)小數,
例如,0.125
是1/10 + 2/100 + 5/100
的值;
又例如0.001
是0/2 + 0/4 + 1/8
的值。
這兩個數值相同。唯一的實質區別是第一個寫為十進位制小數記法,第二個是二進位制。
問題就來了,大多數十進位制小數不能完全用二進位制小數來表示,導致的結果是,一般情況下,你輸入的十進位制浮點數,由實際儲存在計算機中的近似的二進位制浮點數表示。
這個問題可以參見文件《浮點數演算法:爭議和限制》進行詳細瞭解。
浮點數誤差的解決方法
Python中的decimal模組可以解決浮點數誤差的煩惱。這個模組可以通過整數、字串、或者構建decimal.Decimal物件,來解決這個問題。如果是浮點數,因為浮點數本身存在誤差,在計算前需要先將浮點數轉化為字串。
示例:
In [32]: from decimal import Decimal
In [33]: from decimal import getcontext
In [34]: Decimal('4.20') + Decimal('2.10')
Out[34]: Decimal('6.30')
In [35]: x = 4.20
In [36]: y = 2.10
In [37]: z = Decimal(str(x)) + Decimal(str(y))
In [38]: z
Out[38]: Decimal('6.3')
# 設定精度
In [39]: getcontext().prec = 4
In [40]: Decimal('1.00') / Decimal('3.0')
Out[40]: Decimal('0.3333')
- 注意,精度提升的同時,會伴隨效能的損失。在對資料要求特別高的場景下,例如財務計算等,效能的損失是值得的。
String(字串)
在Python中,字串用單引號'
或者雙引號"
括起來,如果遇到特殊字元,可以用反斜槓\
進行轉義。
字串擷取的用法示例:
In [41]: aa = '我愛學習'
In [42]: bb = '我是張學友的粉絲'
In [44]: aa[1:3]
Out[44]: '愛學'
In [45]: aa[1:4]
Out[45]: '愛學習'
In [47]: bb[-6:-1]
Out[47]: '張學友的粉'
In [48]: bb[-7:-1]
Out[48]: '是張學友的粉'
加號+
是字串的連線符,星號*
表示複製當前字串多少次:
In [50]: aa + "," + bb
Out[50]: '我愛學習,我是張學友的粉絲'
In [51]: (aa + "," + bb + "。") * 10
Out[51]: '我愛學習,我是張學友的粉絲。我愛學習,我是張學友的粉絲。我愛學習,我是張學友的粉絲。我愛學習,我是張學友的粉絲。我愛學習,我是張學友的粉絲。我愛學習,我是張學友的粉絲。我愛學習,我是張學友的粉絲。我愛學習,我是張學友的粉絲。我愛學習,我是張學友的粉絲。我愛學習,我是張學友的粉絲。'
我們有這樣一個字串GitOPEN\niubi
,看一下下面的操作:
In [53]: cc = "GitOPEN\niubi"
In [54]: print(cc)
GitOPEN
iubi
In [55]: dd = r"GitOPEN\niubi"
In [56]: print(dd)
GitOPEN\niubi
如果字串本身有特殊字元,但是想讓字串中的特殊字元不轉義,那麼在字串前面加上r
,表示按照原始字串進行輸出。
List(列表)
List可以說是Python中使用最頻繁的資料型別。列表中的元素型別可以不相同,它支援數字,字串甚至可以列表巢狀。
下面是列表,列表擷取操作,列表排序操作:
In [57]: a_list = ['aa', 'bb', 'cc', 'dd', 'ee']
In [58]: b_list = [11, 22, 33.22, 44.05]
In [59]: print(a_list[1])
bb
In [60]: print(a_list[1:3])
['bb', 'cc']
In [61]: print(a_list[2:])
['cc', 'dd', 'ee']
In [62]: print(b_list)
[11, 22, 33.22, 44.05]
# reverse = False表示升序,這是預設值
In [64]: b_list.sort(reverse=False)
In [65]: print(b_list)
[11, 22, 33.22, 44.05]
# reverse = True表示降序
In [66]: b_list.sort(reverse=True)
In [67]: print(b_list)
[44.05, 33.22, 22, 11]
Tuple(元組)
Python中,元組是用()
括起來的,元素不能修改。
a_tup = ('鋤禾','日','當午')
b_tup = (1, 2, 3, 4, 5)
c_tup = "a", "b", "c", "d"
# 建立空元組
d_tup = ()
# 元組中只有一個元素時,需要在元素後面新增逗號
e_tup = (50,)
f_tup = a_tup + b_tup
print(f_tup)
# 刪除元組
del f_tup
print(f_tup)
元組內建函式
Python元組包含了以下內建函式:
序號 | 方法及描述 |
---|---|
1 |
cmp(tuple1, tuple2) 比較兩個元組元素。 |
2 |
len(tuple) 計算元組元素個數。 |
3 |
max(tuple) 返回元組中元素最大值。 |
4 |
min(tuple) 返回元組中元素最小值。 |
5 |
tuple(seq) 將列表轉換為元組。 |
Dictionary(字典)
Python中的字典另一種可變容器模型,可以儲存任意型別物件。
鍵值對的鍵和值用:
冒號分割,每個鍵值對用,
逗號分割;鍵是唯一的,值不需要唯一,如果鍵重複,那麼最後一個鍵值對會覆蓋前面的。
In [69]: a_dict = {'a':'1', 'b':'2', 'c':'3', 'b':'4'}
# 取值
In [70]: a_dict['b']
Out[70]: '4'
In [71]: a_dict
Out[71]: {'a': '1', 'b': '4', 'c': '3'}
# 更新值
In [72]: a_dict['a'] = 11
In [73]: a_dict
Out[73]: {'a': 11, 'b': '4', 'c': '3'}
# 刪除某個鍵對應的值
In [74]: del a_dict['c']
In [75]: a_dict
Out[75]: {'a': 11, 'b': '4'}
# 清空字典中所有的值
In [76]: a_dict.clear()
In [77]: a_dict
Out[77]: {}
# 刪除字典
In [78]: del a_dict
In [79]: a_dict
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-79-374973eefd04> in <module>()
----> 1 a_dict
NameError: name 'a_dict' is not defined
字典中鍵的特性
- 同一個鍵不允許出現兩次。建立時如果同一個鍵被賦值兩次,後一個值會被記住。
- 鍵必須是不可變資料型別,可以用數字、字串、元組,但是列表就不行。
字典的內建函式
序號 | 函式及描述 |
---|---|
1 |
cmp(dict1, dict2) 比較兩個字典元素。 |
2 |
len(dict) 計算字典元素個數,即鍵的總數。 |
3 |
str(dict) 輸出字典可列印的字串表示。 |
4 |
type(variable) 返回輸入的變數型別,如果變數是字典就返回字典型別。 |
字典的內建方法
序號 | 函式及描述 |
---|---|
1 |
dict.clear() 刪除字典內所有元素 |
2 |
dict.copy() 返回一個字典的淺複製 |
3 |
dict.fromkeys(seq[, val]) 建立一個新字典,以序列 seq 中元素做字典的鍵,val 為字典所有鍵對應的初始值 |
4 |
dict.get(key, default=None) 返回指定鍵的值,如果值不在字典中返回default值 |
5 |
dict.has_key(key) 如果鍵在字典dict裡返回true,否則返回false |
6 |
dict.items() 以列表返回可遍歷的(鍵, 值) 元組陣列 |
7 |
dict.keys() 以列表返回一個字典所有的鍵 |
8 |
dict.setdefault(key, default=None) 和get() 類似, 但如果鍵不存在於字典中,將會新增鍵並將值設為default |
9 |
dict.update(dict2) 把字典dict2的鍵/值對更新到dict裡 |
10 |
dict.values() 以列表返回字典中的所有值 |
11 |
pop(key[,default]) 刪除字典給定鍵 key 所對應的值,返回值為被刪除的值。key值必須給出。 否則,返回default值。 |
12 |
popitem() 隨機返回並刪除字典中的一對鍵和值。 |
函式
函式是組織好的,可重複使用的,用來實現單一或者相關功能的程式碼段。它能夠提高應用的模組性,以及程式碼的重複利用率。我們已經使用過很多內建函式,比如print()
,但是,也可以建立使用者自定義函式。
定義一個函式
定義一個函式非常簡單,它有幾個規則:
- 函式以
def
關鍵字開頭,後接函式名稱和():
- 傳入引數和自變數必須放在
()
內 - 函式程式碼塊的內部第一行可以使用文件字串進行函式說明
-
return [表示式]
用來結束函式,選擇是否返回值給呼叫者,不帶表示式的return
相當於返回None
示例:
def sayhello(text):
"""
這是一個說你好的函式
:param text: 打招呼內容
:return: 返回打招呼內容
"""
result = "你好," + text
return result
sayhelllo('世界')
引數
引數型別:
- 必備引數
- 關鍵字引數
- 預設引數
- 不定長引數
必備引數
必備引數必須以正確的順序傳入函式,呼叫的時候,數量必須和宣告的一樣。
def printtext(text):
print(text)
return;
printtext('你好,世界')
# 報錯 TypeError: printtext() missing 1 required positional argument: 'text'
printtext()
關鍵字引數
使用關鍵字引數允許函式在呼叫時引數的順序與宣告時不一致。
def printmsg(text1, text2):
print('text1是:', text1)
print('text2是:', text2)
return
printmsg(text2='世界', text1='你好')
預設引數
呼叫函式時,如果預設引數的值沒有傳入,那麼會使用預設值。
def printemployee(uid, name, salary=1000.00):
print('Uid:', uid)
print('Name:', name)
print('Salary:', salary)
return
printemployee('001', '張1', 2000.00)
printemployee('002', '張2')
不定長引數
有的時候,我們需要一個函式,它能夠處理比當初宣告時更多的引數,這些引數叫做不定長引數。加了星號(*)的變數名會存放所有未命名的變數引數。
def printinfo(arg1, *args):
print('輸出引數:')
print('arg1:', arg1)
for arg in args:
print('arg', arg)
return
printinfo(1, 2)
printinfo(3, 4, 5, 6)
匿名函式
建立匿名函式的方法是使用lambda
。
示例:
sum = lambda x, y: x + y
print(sum(1, 2))
全域性變數和區域性變數
定義在函式內部的是區域性變數,擁有區域性作用域;定義在函式外的變數是全域性變數,擁有全域性作用域。呼叫函式時,所有在函式內宣告的變數名稱都將被加入到作用域中。
示例:
# 全域性變數
total = 0
def sum(x, y):
total = x + y
print('函式內是區域性變數:', total)
return total
sum(11, 22)
print('函式外是全域性變數:', total)
名稱空間和作用域
變數就是一個名字(識別符號),它指向了物件。名稱空間是一個字典,它的鍵是變數名稱,對應的值是物件。
Python表示式可以訪問區域性名稱空間和全域性名稱空間裡面的變數。如果一個區域性變數和一個全域性變數重名,則區域性變數會覆蓋全域性變數。
每一個函式都有自己的名稱空間,類的方法的作用域的規則和一般的函式一樣。Python會智慧地猜測變數是區域性還是全域性的,並且假設在函式內賦值的變數都是區域性的。
物件導向程式設計
Python是一門物件導向語言,因此在Python中建立類和物件是輕而易舉的事情。
物件導向簡介
概念 | 含義 |
---|---|
類,Class | 類是一個集合,描述了具有相同的屬性和方法的物件 |
例項化 | 就是建立類的例項,類的具體物件 |
類變數 | 在例項化物件中,類變數是公用的;類變數定義在類內部並且在函式體之外 |
資料成員 | 類變數或者例項變數,用於處理類及其例項物件的相關的資料 |
繼承 | 派生類繼承基類(父類)的欄位和方法。允許把一個派生類物件作為父類物件對待。 |
方法重寫 | 子類從父類繼承過來的方法,不能滿足子類的需求,可以對其進行重寫(override) |
方法 | 類中的函式 |
物件 | 類的例項,包括兩個資料成員(類變數、例項變數)和方法 |
例項變數 | 定義在方法中的變數 |
建立類
示例:
class Employee:
count = 0
def __init__(self, name, age):
self.name = name
self.age = age
Employee.count += 1
def print_count(self):
print("員工總數為:{}".format(Employee.count))
def show_info(self):
print("Name:{},Age:{}".format(self.name, self.age))
def prt(self):
print(self)
print(self.__class__)
-
count
是一個類變數,它的值在這個類的例項物件之間共享。 -
__init__()
方法是一個特殊的方法,叫做類的建構函式或者初始化方法,當例項化該類的物件時就會呼叫這個方法 -
self
代表類的例項,在定義類的方法時是必須的,但在呼叫時不必傳入相應的引數 - 類的方法與普通的函式只有一個區別,它必須有一個額外的第一個引數名稱,按照習慣,它的名稱是
self
# 例項化物件
emp1 = Employee('張三', 18)
# 物件呼叫方法
emp1.print_count()
emp1.show_info()
emp2 = Employee('張四', 17)
emp2.print_count()
emp2.show_info()
# self是類的例項,代表當前物件的地址;self.__class__指向類。
emp1.prt()
列印的結果為:
員工總數為:1
Name:張三,Age:18
員工總數為:2
Name:張四,Age:17
<__main__.Employee object at 0x1120564a8>
<class '__main__.Employee'>
一些訪問屬性的函式:
函式 | 含義 |
---|---|
getattr(obj, name[,default]) |
訪問物件的屬性 |
hasattr(obj,name) |
檢查是否存在一個屬性 |
setattr(obj,name,value) |
設定一個屬性,如果屬性不存在,則建立一個新屬性 |
delattr(obj,name) |
刪除屬性 |
內建類屬性
名稱 | 含義 |
---|---|
__dict__ |
類的屬性,包含一個字典,由類的資料屬性組成 |
__doc__ |
類的文件字串 |
__name__ |
類名 |
__module__ |
類所在的模組,全名為__main__className
|
__bases__ |
類的所有父類構成元素,包含一個由所有父類組成的元組 |
示例:
print("Employee.__doc__:", Employee.__doc__)
print("Employee.__name__:", Employee.__name__)
print("Employee.__module__:", Employee.__module__)
print("Employee.__bases__:", Employee.__bases__)
print("Employee.__dict__:", Employee.__dict__)
輸出:
Employee.__doc__:
員工基類
Employee.__name__: Employee
Employee.__module__: __main__
Employee.__bases__: (<class 'object'>,)
Employee.__dict__: {'__module__': '__main__', '__doc__': '\n 員工基類\n ', 'count': 2, '__init__': <function Employee.__init__ at 0x105180268>, 'print_count': <function Employee.print_count at 0x1051802f0>, 'show_info': <function Employee.show_info at 0x105180378>, 'prt': <function Employee.prt at 0x105180400>, '__dict__': <attribute '__dict__' of 'Employee' objects>, '__weakref__': <attribute '__weakref__' of 'Employee' objects>}
類的繼承
程式碼重用是物件導向程式設計帶來的主要好處之一,實現重用的方法之一就是繼承機制。
示例:
class Parent:
parent_attr = 123
def __init__(self):
print("Parent建構函式")
def parentMethod(self):
print("Parent方法")
def setAttr(self, attr):
Parent.parent_attr = attr
def getAttr(self):
print("父類屬性:", Parent.parent_attr)
class Child(Parent):
def __init__(self):
print("子類建構函式")
def childMethod(self):
print("Child方法")
child1 = Child()
child1.childMethod()
child1.parentMethod()
child1.setAttr(456)
child1.getAttr()
輸出:
子類建構函式
Child方法
Parent方法
父類屬性: 456
方法過載
如果父類的方法的功能不能滿足你的需求,在子類中可以重寫父類的方法。
示例:
class A:
def myMethod(self):
print("父類方法")
class B(A):
def myMethod(self):
print("子類方法")
b = B()
b.myMethod()
time模組、datetime模組、json模組、csv模組使用方法
time 模組
在編寫Python程式時,轉換日期時間是一個常見的功能。時間間隔是以秒為單位的浮點小數。每個時間戳都以自從1970年1月1日午夜(曆元)經過了多長時間來表示。
獲取當前時間戳:
import time
ticks = time.time()
print("當前的時間戳為:{}".format(ticks))
時間元組
struct_time元組,具有如下屬性:
序號 | 欄位 | 屬性 | 值 |
---|---|---|---|
0 | 4位年 | tm_year | 2018 |
1 | 月 | tm_mon | 1到12 |
2 | 日 | tm_mday | 1到31 |
3 | 小時 | tm_hour | 0到23 |
4 | 分鐘 | tm_min | 0到59 |
5 | 秒 | tm_sec | 0到61(60或61是潤秒) |
6 | 一週的第幾日 | tm_wday | 0到6(0是週一) |
7 | 一年的第幾日 | tm_yday | 1到366 |
8 | 夏令時 | tm_isdst | -1, 0, 1, -1是決定是否為夏令時的旗幟 |
獲取當前時間
import time
localtime = time.localtime(time.time())
print("當前本地時間為:{}".format(localtime))
輸出為:
當前本地時間為:time.struct_time(tm_year=2018, tm_mon=8, tm_mday=13, tm_hour=21, tm_min=49, tm_sec=53, tm_wday=0, tm_yday=225, tm_isdst=0)
格式化時間
import time
localtime = time.asctime(time.localtime(time.time()))
print("格式化後的時間為:{}".format(localtime))
輸出:
格式化後的時間為:Mon Aug 13 21:52:20 2018
格式化日期
import time
# 格式化成2018-08-13 21:55:46形式
print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
# 格式化成Mon Aug 13 21:52:20 2018形式
print(time.strftime("%a %b %d %H:%M:%S %Y", time.localtime()))
# 將格式字串轉換為時間戳
a = "Mon Aug 13 21:52:20 2018"
print(time.mktime(time.strptime(a, "%a %b %d %H:%M:%S %Y")))
輸出:
2018-08-13 21:56:49
Mon Aug 13 21:56:49 2018
1534168340.0
datetime模組
import datetime
i = datetime.datetime.now()
print("當前的日期和時間是 %s" % i)
print("ISO格式的日期和時間是 %s" % i.isoformat())
print("當前的年份是 %s" % i.year)
print("當前的月份是 %s" % i.month)
print("當前的日期是 %s" % i.day)
print("dd/mm/yyyy 格式是 %s/%s/%s" % (i.day, i.month, i.year))
print("當前小時是 %s" % i.hour)
print("當前分鐘是 %s" % i.minute)
print("當前秒是 %s" % i.second)
json模組
在使用Python進行資料處理的過程中,我們經常和json資料打交道。
JSON(JavaScript Object Notation)是一種輕量級的資料交換格式。
json模組的兩個常用函式為:
函式名 | 含義 |
---|---|
json.dumps |
將Python物件編碼成JSON字串 |
json.loads |
將已編碼的JSON字串解碼為Python物件 |
json.dumps
示例:
將Python物件(陣列)編碼為JSON格式資料:
import json
data = [{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}]
json_str = json.dumps(data)
print(json_str)
print(type(json_str))
格式化輸出JSON資料:
data = {'name': 'GitOPEN', 'salary': 70000.01}
json_str = json.dumps(data, sort_keys=True, indent=4, separators=(', ', ': '))
print(json_str)
python 原始型別向 json 型別的轉化對照表:
Python | JSON |
---|---|
dict | object |
list, tuple | array |
str, unicode | string |
int, long, float | number |
True | true |
False | false |
None | null |
json.loads
用於解碼JSON資料,返回Python欄位的資料型別。
示例:
import json
json_str = '{"a":1,"b":2,"c":3,"d":4,"e":5}'
text = json.loads(json_str)
print(type(text))
print(text)
csv模組
csv庫可以幫助我們解決大多數CSV格式的資料讀寫問題。
讀資料
準備一個csv格式的檔案,命名為data.csv
:
Uid,Name,Age,Score
1000,"張1",18,99.99
1001,"張2",19,89.99
1002,"張3",20,79.99
1003,"張4",21,69.99
示例:將這個資料檔案讀取為一個元組序列:
import csv
with open('data.csv', 'r', encoding='utf-8') as f:
f_csv = csv.reader(f)
for row in f_csv:
print(row)
注意:data.csv和py檔案的編碼格式應當統一為utf-8。
輸出為:
['Uid', 'Name', 'Age', 'Score']
['1000', '張1', '18', '99.99']
['1001', '張2', '19', '89.99']
['1002', '張3', '20', '79.99']
['1003', '張4', '21', '69.99']
示例:將這個資料讀取為一個字典:
import csv
with open('data.csv', 'r', encoding='utf-8') as f:
f_csv = csv.DictReader(f)
for row in f_csv:
print(type(row))
print(row)
輸出:
<class 'collections.OrderedDict'>
OrderedDict([('Uid', '1000'), ('Name', '張1'), ('Age', '18'), ('Score', '99.99')])
<class 'collections.OrderedDict'>
OrderedDict([('Uid', '1001'), ('Name', '張2'), ('Age', '19'), ('Score', '89.99')])
<class 'collections.OrderedDict'>
OrderedDict([('Uid', '1002'), ('Name', '張3'), ('Age', '20'), ('Score', '79.99')])
<class 'collections.OrderedDict'>
OrderedDict([('Uid', '1003'), ('Name', '張4'), ('Age', '21'), ('Score', '69.99')])
寫資料
示例:
import csv
headers = ['Uid', 'Name', 'Age', 'Score']
rows = [
('1000', '張1', '18', '99.99'),
('1001', '張2', '19', '89.99'),
('1002', '張3', '20', '79.99'),
('1003', '張4', '21', '69.99')
]
with open('data1.csv', 'w', newline='') as f:
f_csv = csv.writer(f)
f_csv.writerow(headers)
f_csv.writerows(rows)
注意:
newline=''
這個引數,你會發現,如果不加,生成的csv檔案中每一行下面總是會多一行空白行。
示例:
寫入字典序列資料到csv檔案中。
import csv
headers = ['Uid', 'Name', 'Age', 'Score']
rows = [
{'Uid': 1000, 'Name': '張1', 'Age': 18, 'Score': 99.99},
{'Uid': 1001, 'Name': '張2', 'Age': 19, 'Score': 89.99},
{'Uid': 1002, 'Name': '張3', 'Age': 20, 'Score': 79.99},
{'Uid': 1003, 'Name': '張4', 'Age': 21, 'Score': 69.99}
]
with open('data2.csv', 'w', newline='') as f:
f_csv = csv.DictWriter(f, headers)
f_csv.writeheader()
f_csv.writerows(rows)
實戰──搜尋引擎首頁實戰
寫好的GitOPEN搜尋首頁如圖所示:
整個專案的結構如圖所示,專案原始碼位置CrawlerLessons/codes/lesson01/SearchDemo
:
index.html
原始碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>GitOPEN搜尋,最貼心搜尋</title>
<link rel="stylesheet" href="index.css">
</head>
<body>
<div id="root">
<div id="header">
<div id="links">
<a href="http://news.baidu.com/" target="_blank">新聞</a>
<a href="https://www.hao123.com/" target="_blank">hao123</a>
<a href="http://map.baidu.com/" target="_blank">地圖</a>
<a href="http://v.baidu.com/" target="_blank">視訊</a>
<a href="table.html" target="_blank">員工</a>
<a href="list.html" target="_blank">列表</a>
</div>
</div>
<div id="content">
<img src="images/logo.png" alt="GitOPEN搜尋,最貼心搜尋">
<br>
<form action="https://www.so.com/s?" method="get">
<input id="input_search" type="text" name="q">
<input id="btn_search" type="submit" value="搜尋一下"/>
</form>
</div>
<div id="footer">
Powered by GitOPEN ® Hosted by <a href="https://www.vultr.com/?ref=7147564" target="_blank">Vultr</a>
</div>
</div>
</body>
</html>
index.css
原始碼:
* {
margin: 0px;
padding: 0px;
}
html, body {
width: 100%;
height: 100%;
}
#root {
width: 100%;
height: 100%;
align-self: center;
}
#header {
height: fit-content;
text-align: right;
}
#header #links {
padding: 10px;
}
#header #links a {
color: black;
font-size: 16px;
font-weight: bold;
margin-right: 16px;
}
#content {
height: 70%;
text-align: center;
padding-top: 60px;
}
#content img {
width: 300px;
}
#content #btn_search {
height: 34px;
width: 80px;
padding: 5px;
border: 0px;
background-color: #3D5984;
font-size: 16px;
color: #FFFFFF;
}
#content #input_search {
height: 34px;
width: 500px;
font-size: 18px;
border-color: #3D5984;
}
#footer {
height: 20%;
text-align: center;
font-style: oblique;
}
list.html
原始碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>列表示例</title>
</head>
<body>
<h3>無序列表</h3>
<ul>
<li>張1</li>
<li>張2</li>
<li>張3</li>
<li>張4</li>
</ul>
<hr>
<h3>有序列表</h3>
<ol>
<li>張1</li>
<li>張2</li>
<li>張3</li>
<li>張4</li>
</ol>
</body>
</html>
table.html
原始碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>員工資訊</title>
<style>
table, th, td {
border: 1px #2d78f4 dashed;
border-collapse: collapse;
text-align: center;
}
table {
width: auto;
}
th, td {
width: 90px;
}
th {
color: crimson;
}
#total {
color: blueviolet;
}
</style>
</head>
<body>
<table>
<tr>
<th>編號</th>
<th>姓名</th>
<th>月薪</th>
</tr>
<tr>
<td>0001</td>
<td>張1</td>
<td>20000.00</td>
</tr>
<tr>
<td>0002</td>
<td>張2</td>
<td>10000.00</td>
</tr>
<tr>
<td>0003</td>
<td>張3</td>
<td>8000.00</td>
</tr>
<tr>
<td colspan="2">總計</td>
<td colspan="1" id="total">38000.00</td>
</tr>
</table>
</body>
</html>
實戰──簡易學生管理系統
這是一個玩具程式碼專案,用來練習剛剛學會的Python基礎知識。
這個實戰例子我們不再做程式碼演示,請大家自行執行程式碼,找出程式碼的不足之處,寫出自己的《簡易學生管理系統》,要求具有的功能如下圖所示:
參考程式碼位置:CrawlerLessons/codes/lesson01/StudentSystem
。
參考資料推薦
相關文章
- 爬蟲開發知識入門基礎(1)爬蟲
- Python基礎知識詳解 從入門到精通(六)檔案操作Python
- 【爬蟲】python爬蟲從入門到放棄爬蟲Python
- python 爬蟲基礎知識一Python爬蟲
- 爬蟲入門基礎-Python爬蟲Python
- Python分散式爬蟲(三) - 爬蟲基礎知識Python分散式爬蟲
- Python爬蟲之路-爬蟲基礎知識(理論)Python爬蟲
- 爬蟲(1) - 爬蟲基礎入門理論篇爬蟲
- 爬蟲基礎知識爬蟲
- Python爬蟲入門(2):爬蟲基礎瞭解Python爬蟲
- 零基礎入門學習Python爬蟲必備的知識點!Python爬蟲
- 【零基礎】PostgreSQL從入門到精通SQL
- Python 從入門到爬蟲極簡教程Python爬蟲
- Python從入門到精通Python
- vue+webpack 從入門到精通(基礎篇)VueWeb
- React從入門到精通系列之(1)安裝ReactReact
- 《HTMLCSSJavaScript網頁製作從入門到精通第3版》——第01章 HTML基礎HTMLCSSJavaScript網頁
- 【爬蟲系列】1. 無事,Python驗證碼識別入門爬蟲Python
- Python 爬蟲從入門到進階之路(十六)Python爬蟲
- Python 爬蟲從入門到進階之路(十七)Python爬蟲
- Python 爬蟲從入門到進階之路(十八)Python爬蟲
- Python 爬蟲從入門到進階之路(二)Python爬蟲
- Python 爬蟲從入門到進階之路(三)Python爬蟲
- Python 爬蟲從入門到進階之路(十二)Python爬蟲
- Python 爬蟲從入門到進階之路(十五)Python爬蟲
- Python 爬蟲從入門到進階之路(八)Python爬蟲
- Python 爬蟲從入門到進階之路(九)Python爬蟲
- Python 爬蟲從入門到進階之路(十)Python爬蟲
- Python 爬蟲從入門到進階之路(十一)Python爬蟲
- Python 爬蟲從入門到進階之路(六)Python爬蟲
- Python 爬蟲從入門到進階之路(七)Python爬蟲
- 學渣講爬蟲之Python爬蟲從入門到出門(第三講)爬蟲Python
- Python基礎知識入門(二)Python
- Python入門基礎知識(二)Python
- WebSocket系列之基礎知識入門篇Web
- python爬蟲之Beautiful Soup基礎知識+例項Python爬蟲
- Python入門必知的知識點!Python基礎入門Python
- Angular入門到精通系列教程(7)- 元件(@Component)基本知識Angular元件