Python爬蟲從入門到精通─第1課 基礎知識

本教程全部源碼下載連接:share.weiyun.com/5xmFeUO 密碼:fzwh6g
本教程首發於GitOPEN's Home,轉載請徵求做者贊成css

基礎知識

環境搭建

Python安裝

平時能接觸到的操做系統非Windows、macOS、Linux莫屬。其中Windows是咱們平常中最經常使用的OS,它軟件更多、辦公和遊戲能夠兼得;macOS因爲搭載其的電腦外表漂亮、屏幕優秀、性能均衡,而被不少設計者和程序員所喜好;Linux在服務器領域是無可匹敵,幾乎全部大型應用服務器都部署於Linux系統,經常使用的Linux服務器系統有CentOS、Ubuntu Server等,可是Linux桌面版也在程序員中應用較廣,便捷的終端、穩定的性能是編程的首選。html

因爲macOS和Ubuntu系統都自帶python環境,所以,咱們只講解Windows下Python的安裝和配置。感興趣的同窗,能夠本身在虛擬機中測試和熟悉Linux系統,推薦Ubuntu18.04。python

Windows下安裝Python

熟悉一下Python的主頁程序員

下載。官方的最新版已經更新到了3.7.0,可是咱們下載的版本是Python3.6.5,所以,咱們點擊View the full list of downloadsweb

只須要記住,不一樣架構的Windows系統,選擇不一樣的安裝包下載。算法

安裝。按圖示操做便可。shell

  • 雙擊安裝包,選擇自定義安裝,方便之後使用。數據庫

  • 直接下一步。編程

  • 修改路徑,將路徑改成c:\Python36json

  • 安裝成功

環境變量檢測與設置。

  • 打開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、單選按鈕radiobuttonsubmit等等。

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
複製代碼

等號(=)叫作運算符,用來給變量nameagesalary賦值,左邊是一個變量名,右邊是存儲在變量中的值。

在給變量賦值不一樣類型的對象,那麼,變量就有了類型。

name是字符串變量,age是整型變量,salary是浮點型變量。

多個變量賦值

Python中,能夠同時爲多個變量賦值:

aa = bb = cc = 11
複製代碼

這個例子的含義爲,建立一個整型對象,值爲11,從後向前賦值,3個變量都指向同一個內存地址。

再看一個例子:

dd, ee, ff = 22, 33, "GitOPEN"
複製代碼

這個例子中,將整型對象2233分別分配給變量ddee,字符串對象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.1251/10 + 2/100 + 5/100的值;

又例如0.0010/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

參考資料推薦

相關文章
相關標籤/搜索