一、HTTP協議簡介
1. 什么是URL
URL的全稱是統一資源定位符
通過一個URL可以找到互聯網上唯一的一個資源
URL就是資源的地址、位置,互聯網上的每個資源都有一個唯一的URL
URL的基本格式 = 協議://主機地址/路徑
協議
: 不同的協議,代表著不同的資源查找方式、資源傳輸方式
主機地址
: 存放資源的主機(服務器)的IP地址(域名)
路徑
: 資源在主機(服務器)中的具體位置
2. 什么是HTTP
HTTP的全稱是Hypertext Transfer Protocol,超文本傳輸協議訪問的是遠程的網絡資源,格式是http://
http協議是在網絡開發中最常用的協議(其它:file(本地)、mailto(郵件)、FTP(共享))
特點
:簡單,靈活,非持續連接
HTTP協議規定客戶端和服務處之間的數據傳輸方式
讓客戶端和服務器能有效地進行數據溝通
二、Python中HTTP協議的使用
python中有一個第三方庫requests,提供了所有和http協議相關的函數
1. get請求
get(url, params=None)
發送請求獲取服務器返回的相應
url
: 請求地址,字符串
params
: 請求參數,字典
# 只適用于get請求
# url = 'https://www.apiopen.top/satinApi?type=1&page=1'
# response = requests.get(url)
# print(response) # <Response [200]>
# 既適用于get也適用于post
url = 'https://www.apiopen.top/satinApi'
params = {'type': 1, 'page': 2}
response = requests.get(url, params)
print(response) # <Response [200]>
2. 獲取請求結果
1) 響應頭
print(response.headers)
2) 響應體(數據)
a. 獲取二進制對應的原數據
content = response.content
print(type(content)) # <class 'bytes'>
b. 獲取字符串類型的數據
text = response.text
print(type(text)) # <class 'str'>
c. 獲取json數據(json轉換為python對應的數據)
json1 = response.json()
print(type(json1)) # <class 'dict'>
三、多線程基礎
1. 進程
進程指的是在系統中正在運行的一個應用程序
特點
:每個進程之間是相互獨立的,每個進程均運行在其專有且受保護的內存空間內
2. 線程
1) 什么是線程
程序運行的最小單元,一個進程(程序)的所有任務都在線程中執行
2)線程的串行
1個線程中任務的執行是串行的,同一時間1個線程只能執行1個任務
3)進程與線程的比較
a. 線程是CPU調度的最小單位
b. 進程是CPU分配資源和調用的單位
c. 一個程序可以對應多個進程,一個進程可以對應多個線程,但至少有一個線程
d. 同一個進程內的線程共享進程的資源
3. 多線程
1) 什么是多線程
1個進程中可以開啟多條線程,每條線程可以并行(同時)執行不同的任務
多線程可以提高程序的執行效率
2)原理
實際上,在同一時間,CPU只能處理1條線程,即只有1條線程在工作(執行)
多線程并發執行,原理上是CPU快速地在多條線程之間調度(切換)
四、Python多線程的基礎使用
1. 線程
每個進程中默認都有一條線程,即主線程;其它線程稱為子線程
threading模塊中Thread的對象就是線程對象,當程序中需要子線程時通過創建Thread對象即可
2. 多線程
1. 創建線程對象
Thread(target=None, args=()) : 創建并返回一個子線程對象
target
: 函數類型(function),在線程啟動時這個函數會在子線程中執行
args
: 元組,元組中的元素是target對應的函數在子線程中調用的實參
2. 啟動線程
線程對象.start() : 讓線程去執行線程中的任務
def download(film_name: str):
print(film_name, threading.current_thread().name)
print('{}\t開始下載\t{}'.format(film_name, datetime.now()))
sleep(3)
print('{}\t下載結束\t{}'.format(film_name, datetime.now()))
def main():
# 單線程
# download('魔童降世')
# download('掃毒2')
# download('怦然心動')
pass
if __name__ == '__main__':
main()
# 多線程
# 1. 創建線程對象
"""
Thread(target=None, args=()) : 創建并返回一個子線程對象
target : 函數類型(function),在線程啟動時這個函數會在子線程中執行
args : 元組,元組中的元素是target對應的函數在子線程中調用的實參
"""
t1 = threading.Thread(target=download, args=('魔童降世',))
t2 = threading.Thread(target=download, args=('掃毒2',))
t3 = threading.Thread(target=download, args=('怦然心動',))
# 2. 啟動線程
"""
線程對象.start() : 讓線程去執行線程中的任務
target(*args)
"""
t1.start()
t2.start()
t3.start()
3. 多線程2
1) 聲明一個類繼承Thread
2) 實現類中的run()方法,run()中的代碼就是需要在子線程中執行的代碼
3) 需要子線程時創建自己聲明的線程類對象,并且不需要傳任何參數
class DownloadThread(Thread):
def __init__(self, file_name):
super().__init__()
self.file_name = file_name
def run(self) -> None:
print(current_thread().name)
start = datetime.now()
print('{}\t開始下載\t{}'.format(self.file_name, start))
sleep(3)
end = datetime.now()
print('{}\t下載結束\t{}\t總用時:{}'.format(self.file_name, end, end - start))
def main():
t1 = DownloadThread('魔童降世')
t2 = DownloadThread('掃毒2')
t1.start()
t2.start()
if __name__ == '__main__':
main()
4. 程序結束
線程中的任務執行完成線程就結束;程序出現異常結束的是線程,而不是進程
進程中的所有線程都結束進程才結束
5. join()
線程對象.join() : 當前線程對象任務直線完成后才能直線后面的代碼
def download(film_name: str) -> None:
start = time()
print('{}:{}\t開始下載'.format(current_thread().name, film_name))
sleep(randint(3, 6))
end = time()
print('{}\t下載結束\t總用時:{}s'.format(film_name, end - start))
def main():
# 1. join
"""
線程對象.join() : 當前線程對象任務直線完成后才能直線后面的代碼
"""
t1 = Thread(target=download, args=('魔童降世',))
t2 = Thread(target=download, args=('掃毒2',))
t3 = Thread(target=download, args=('怦然心動',))
# 情況一:計算三部電影總用時
# start = time()
# t1.start()
# t2.start()
# t3.start()
# t1.join()
# t2.join()
# t3.join()
# end = time()
# print('三部電影總用時:{}s'.format(end - start))
# 情況二:電影1下載完成后才開始同時下載電影2和3
t1.start()
t1.join()
t2.start()
t3.start()
if __name__ == '__main__':
main()