《Python爬蟲開發與項目實戰》總結 第一章


一.內容框架:





二.概念:

IO在計算機中指的是Input/Output,也就是輸入輸出。

Stream(流)是一種重要的概念,分爲輸入流(Input Stream)和輸出流(Output Stream)。可以理解爲一個水管,數據相當於水管中的水只能單向流動。

打開文件是讀寫文件最常見的IO操作,爲了方便IO操作,文件讀寫之前需要打開文件,確定文件的讀寫模式。

文件模式是open函數中的mode參數,通過改變mode參數可以實現對文件的不同操作。

文件緩衝區是open函數中第三個參數buffering控制着文件的緩衝。

文件讀取主要分爲按字節讀取和按行進行讀取,經常用到的方法有read(),readlines(),close()。

文件寫入唯一的區別是在調用open方法時,傳入標識‘w’或者‘wb’標識寫入文本文件或者寫入二進制文件。

序列化是把內存中數據變成可存儲和可傳輸的過程。

反序列化是把變量內容從序列化對象重新讀取到內存中。

進程池可以提供指定數量的進程供用戶調用,默認大小事CPU的核數。

線程同步是多個線程共同對某個數據修改,則可能出現不可預料的結果,爲了保證數據的正確性,需要多個線程進行同步。

全局解釋器鎖(GIL):解釋執行Python代碼時,會產生互斥鎖來限制線程對共享資源的訪問,知道解釋器遇到I/O操作或者操作次數達到一定數目時纔會釋放GIL。

協程又稱爲微線程,纖程,是一種用戶級的輕量級線程。協程擁有自己的寄存器上下文和棧。協程調度切換時,將寄存器上下文和棧保存到其他地方,在切回來的時候,恢復先前保存的寄存器上下文和棧。

分佈式進程是將Process進程分佈到多臺機器上,充分利用多臺機器的性能完成複雜的任務。

本地隊列的網絡化是將分佈式進程進行封裝的過程。


連接到指定服務器進程的通信端口進行通信,所以網絡通信也可以看做兩個進程間的通信。

TCP編程:網絡編程一般包括兩部分,服務端和客戶端。TCP是一種面向連接的通信方式,主動發起連接的叫客戶端,被動響應連接的叫服務端。

UDP編程:只需要知道對方的IP地址和端口號,就可以直接發數據包,但是不關心是否能到達目的端。

三.方法

1.文件操作

文件打開

open()

文件寫入

Write()

文件讀取

read()

文件讀取/行讀取

readlines()

文件關閉

close()

1.2文件模式

功能描述

‘r’

讀模式

‘w’

寫模式

‘a’

追加模式

‘b’

二進制模式

‘+’

讀/寫模式

1.3文件緩衝區

參數

 

0

I/O操作是無緩衝的,直接寫到硬盤上。

1

I/O操作是有緩衝的,數據先寫到內存裏,只有使用flush和close函數纔會將數據更新到硬盤上。

大於1

大於1表示緩衝區的大小。

-1

代表使用默認緩衝區的大小。

1.4操作文件目錄

os.getcwd()

獲得當前Ptython腳本工作的目錄路徑

os.Listdir()

返回指定目錄下的所有文件和目錄名

os.remove(filepath)

刪除一個文件

os.removedirs()

刪除多個空目錄

os.path.isfiles(filepath)

檢驗給出的路徑是否是一個文件

os.path.isdir(filepath)

檢驗給出的路徑是否是一個目錄

os.path.isabs()

判斷是否是絕對路徑

os.path.exists()

檢驗路徑是否真的存在

os.path.split()

分離一個路徑的目錄名和文件名

os.path.splitext()

分離擴展名

os.path.dirname(filepath)

獲取路徑名

os.path.basename(filepath)

獲取文件名

os.getnv()或os.putnv()

設置環境變量

os.linesep

給出平臺使用的終止符

os.name

指示你正在使用的平臺

os.rename()

重命名文件或者目錄

os.makedirs()

創建多級目錄

os.mkdir()

創建多個目錄

os.stat()

獲取文件屬性

os.chmod()

修改文件權限與時間戳

ps.path.getsize()

獲取文件大小

shutil.copytree()

複製文件夾

shutil.copyfile()

複製文件

shutil.move()

移動文件

os.rmdir()

刪除目錄

 

 

1.4序列化操作

cPickle和pickle兩個模塊來實現序列化,前者由C語言編寫的,效率比後者高很多。

Pickle使用dumps方法將任意對象序列化成一個str。

1.5進程和線程

一種方法是使用os模塊中的fork方法,另一種方法是使用multiprocessing模塊。

getpid方法用於獲取當前進程的ID,getppid方法用於獲取父進程的ID。

start()方法啓動進程,用join()方法實現進程間的同步。

pool()可以提供指定數量的進程供用戶調用,默認大小是CPU的核數。

1.6進程間通信

Queue用在多個進程之間的數據傳遞。有兩個方法,put和get可以進行Queue操作。

 

blocked

timeout

 

Put

True

正值

該方法會阻塞timeout指定的時間,直到該隊列有剩餘的空間。如果超時會Queue.Full異常。

False

NA

Queue滿,Queue.Full異常

Get

True

正值

那麼在等待時間內沒有取得任何元素,會拋出Queue.Empty異常。

False

有值

則立即返回該值。

則立即拋出Queue.Empty異常。

Pipe的通信機制常用來在兩個進程間進行通信,兩個進程分別位於管道的兩端。

Pipe

Duplex

 

False

conn1只負責接收消息,conn2 只負責發送消息

True

管道是全雙工模式,也就是說conn1和conn2均可收發

1.7多線程

Threading模塊一般通過兩種方式創建多線程:第一種方式是把一個函數傳入並創建Thread實例,然後調用start方法開始執行;第二種方式是直接從threading.Thread繼承並創建線程類,然後重寫_init_方法和run方法。

1.8線程同步

Thread對象的Lock和RLock可以實現簡單的線程同步,這兩個對象都有acquire方法和release方法,對於每次只允許一個線程操作的數據,可以將其操作放到qcuqire和release方法之間。

1.9協程

Python通過yield和gevent庫是更好的選擇,提供了比較完善的協程支持。gevent中的spawn方法可以看做是用來形成協程,joinall方法就是添加這些協程任務,並且啓動運行。

2.0分佈式進程

Multiprocessing模塊不但支持多進程,其中managers子模塊還支持把多進程分佈到多臺機器上。

2.1網絡編程

Socket類型

套接字格式爲:socket(family,type[,protocal]),使用給定的地址族、套接字類型、協議編號創建套接字。

Socket.AF_UNIX

只能夠用於單一的Unix系統進程通信

Socket.AF_INET

服務器之間網絡通信

Socket.AF_INET6

IPv6

Socket.SOCK_STREAM

流式socket,用於TCP

Socket.SOCK_DGRAM

數據報式socket,用於UDP

Socket.SOCK_RAW

原始套接字,普通的套接字無法處理ICMP/IGMP等網絡報文,而SOCK_RAW可以;其次,SOCK_RAW也可以處理特殊的IPv4報文,此外,利用原始套接字,可以通過IP_HDRINCL套接字選項由用戶構造IP頭。

Socket.SOCK_SEQPACKET

可靠的連續數據包服務

創建TCP socket

S=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

創建UDP socket

S=socket.socket(socket.AF_INET,socket.SOCK_DGREAM)

Socket函數

Socket函數

描述

 

服務器socket函數

S.bind(address)

將套接字綁定到地址,在AF_INET下,以元組(host,port)的形式表示地址

s.listen(backlog)

開始監聽TCP傳入連接,backlog指定在拒絕連接之前,操作系統可以掛起的最大連接數量。該值至少爲1,大部分應用程序設爲5就可以了。

s.accept()

接受TCP連接並返回(conn,address),其中conn是新的套接字對象,可以用來接收和發送數據address是連接客戶端的地址。

 

客戶端

S.connect(address)

連接到address處的套接字。一般address的格式爲元組(hostname,port),如果連接出錯,返回socket.error錯誤

s.connect_ex(address)

功能與connect(address)相同,但是返回0,失敗返回errno的值。

 

公共socket函數

s.recv(bufsize[,flag])

接受TCP套接字的數據,數據以字符串形式返回,bufsize指定要接收的最大數據量。Flag提供有關消息的其他信息,通常可以忽略

s.send(string[,flag])

發送TCP數據。將string中的數據發送到連接的嵌套字。返回值是要發送的字節數量,該數量可能小於string的字節大小。

s.sendall(string[,flag])

完整發送TCP數據。將string中的 數據發送到連接的套接字,但在返回之前會嘗試發送所有的數據。但成功返回None,失敗則拋出異常。

s.recvfrom(bufsize[,flag])

接受UDP套接字的數據。將string中的數據發送到連接的套接字。返回值是(data,address)。其中data是包含接收數據的字符串,address是發送數據的套接字地址

s.sendto(string[,flag],address)

發送UDP數據。將數據發送到套接字,address是形式(ipaddr,port)的元組,指定遠程地址。返回值是發送的字節數。

s.close()

關閉套接字

s.getpeername()

返回連接套接字的遠程地址。返回值通常是元組(ipaddr,port)

s.getsockname()

返回套接字自己的地址。同常是一個元組(ipaddr,port)

s.setsockopt(level,optname,value)

設置給定套接字選項的值

s.getsockopt(level,optname,[.buflen])

返回套接字選項的值

s.settimeout(timeout)

設置套接字操作的超時期,timeout是一個浮點數,單位是秒。值爲None表示沒有超時期。一般超時期應該在剛創建套接字時設置,因爲它們可能會用於連接操作。

s.setblocking(flag)

如果flag爲0,則將套接字設爲非阻塞模式,否則將套接字設爲阻塞模式。非阻塞模式下,如果調用recv()沒有發現任何數據,或send()調用無法立即發送數據,將引起socket.error異常。

 

 

 

2.2 TCP編程

服務端

客戶端

1)創建Socket,綁定Socket到本地IP與端口

1)創建Socket,連接遠端地址。

2)開始監聽連接

2)連接後發送數據和接收數據

3)進入循環,不斷接收客戶端的連接請求

3)傳輸完畢後,關閉Socket

4)接收傳來的數據併發送給對方數據

 

5)傳輸完畢後,關閉Socket

 

 

 

UDP編程

1)創建Socket,綁定的IP和端口

1)創建Socket

2)直接發送數據和接收數據

 

3)關閉socket

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章