Python多任務(wù)爬蟲實(shí)現(xiàn)爬取圖片和GDP數(shù)據(jù)
一. 基于FastAPI之Web站點(diǎn)開發(fā)
1. 基于FastAPI搭建Web服務(wù)器
# 導(dǎo)入FastAPI模塊
from fastapi import FastAPI
# 導(dǎo)入響應(yīng)報(bào)文Response模塊
from fastapi import Response
# 導(dǎo)入服務(wù)器uvicorn模塊
import uvicorn
# 創(chuàng)建FastAPI框架對(duì)象
app = FastAPI()
# 通過@app路由裝飾器收發(fā)數(shù)據(jù)
# @app.get(參數(shù)) : 按照get方式接受請(qǐng)求數(shù)據(jù)
# 請(qǐng)求資源的 url 路徑
@app.get("/index.html")
def main():
with open("source/html/index.html", "rb") as f:
data = f.read()
# return 返回響應(yīng)數(shù)據(jù)
# Response(content=data, media_type="text/html"
# 參數(shù)1: 響應(yīng)數(shù)據(jù)
# 參數(shù)2: 數(shù)據(jù)格式
return Response(content=data, media_type="text/html")
# 運(yùn)行服務(wù)器
# 參數(shù)1: 框架對(duì)象
# 參數(shù)2: IP地址
# 參數(shù)3: 端口號(hào)
uvicorn.run(app, host="127.0.0.1", port=8000)

2. Web服務(wù)器和瀏覽器的通訊流程
實(shí)際上Web服務(wù)器和瀏覽器的通訊流程過程并不是一次性完成的, 這里html代碼中也會(huì)有訪問服務(wù)器的代碼, 比如請(qǐng)求圖片資源。
那像0.jpg、1.jpg、2.jpg、3.jpg、4.jpg、5.jpg、6.jpg這些訪問來自哪里呢
答:它們來自index.html
3. 瀏覽器訪問Web服務(wù)器的通訊流程

瀏覽器訪問Web服務(wù)器的通訊流程:
瀏覽器(127.0.0.1/index.html) ==> 向Web服務(wù)器請(qǐng)求index.htmlWeb服務(wù)器(返回index.html) ==>瀏覽器瀏覽器解析index.html發(fā)現(xiàn)需要0.jpg ==>發(fā)送請(qǐng)求給Web服務(wù)器請(qǐng)求0.jpgWeb服務(wù)器收到請(qǐng)求返回0.jpg ==>瀏覽器接受0.jpg
通訊過程能夠成功的前提:
瀏覽器發(fā)送的0.jpg請(qǐng)求, Web服務(wù)器可以做出響應(yīng), 也就是代碼如下
# 當(dāng)瀏覽器發(fā)出對(duì)圖片 0.jpg 的請(qǐng)求時(shí), 函數(shù)返回相應(yīng)資源
@app.get("/images/0.jpg")
def func_01():
with open("source/images/0.jpg", "rb") as f:
data = f.read()
print(data)
return Response(content=data, media_type="jpg")
4. 加載圖片資源代碼
# 導(dǎo)入FastAPI模塊
from fastapi import FastAPI
# 導(dǎo)入響應(yīng)報(bào)文Response模塊
from fastapi import Response
# 導(dǎo)入服務(wù)器uvicorn模塊
import uvicorn
# 創(chuàng)建FastAPI框架對(duì)象
app = FastAPI()
@app.get("/images/0.jpg")
def func_01():
with open("source/images/0.jpg", "rb") as f:
data = f.read()
print(data)
return Response(content=data, media_type="jpg")
@app.get("/images/1.jpg")
def func_02():
with open("source/images/1.jpg", "rb") as f:
data = f.read()
return Response(content=data, media_type="jpg")
@app.get("/images/2.jpg")
def func_03():
with open("source/images/2.jpg", "rb") as f:
data = f.read()
return Response(content=data, media_type="jpg")
@app.get("/images/3.jpg")
def func_04():
with open("source/images/3.jpg", "rb") as f:
data = f.read()
return Response(content=data, media_type="jpg")
@app.get("/images/4.jpg")
def func_05():
with open("source/images/4.jpg", "rb") as f:
data = f.read()
return Response(content=data, media_type="jpg")
@app.get("/images/5.jpg")
def func_06():
with open("source/images/5.jpg", "rb") as f:
data = f.read()
return Response(content=data, media_type="jpg")
@app.get("/images/6.jpg")
def func_07():
with open("source/images/6.jpg", "rb") as f:
data = f.read()
return Response(content=data, media_type="jpg")
@app.get("/index.html")
def main():
with open("source/html/index.html", "rb") as f:
data = f.read()
# return 返回響應(yīng)數(shù)據(jù)
# Response(content=data, media_type="text/source"
# 參數(shù)1: 響應(yīng)數(shù)據(jù)
# 參數(shù)2: 數(shù)據(jù)格式
return Response(content=data, media_type="text/html")
# 運(yùn)行服務(wù)器
# 參數(shù)1: 框架對(duì)象
# 參數(shù)2: IP地址
# 參數(shù)3: 端口號(hào)
uvicorn.run(app, host="127.0.0.1", port=8000)
二. 基于Web請(qǐng)求的FastAPI通用配置
1. 目前Web服務(wù)器存在問題
# 返回0.jpg
@app.get("/images/0.jpg")
def func_01():
with open("source/images/0.jpg", "rb") as f:
data = f.read()
print(data)
return Response(content=data, media_type="jpg")
# 返回1.jpg
@app.get("/images/1.jpg")
def func_02():
with open("source/images/1.jpg", "rb") as f:
data = f.read()
return Response(content=data, media_type="jpg")
# 返回2.jpg
@app.get("/images/2.jpg")
def func_03():
with open("source/images/2.jpg", "rb") as f:
data = f.read()
return Response(content=data, media_type="jpg")
對(duì)以上代碼觀察,會(huì)發(fā)現(xiàn)每一張圖片0.jpg、1.jpg、2.jpg就需要一個(gè)函數(shù)對(duì)應(yīng), 如果我們需要1000張圖片那就需要1000個(gè)函數(shù)對(duì)應(yīng), 顯然這樣做代碼的重復(fù)太多了.
2. 基于Web請(qǐng)求的FastAPI通用配置
# 當(dāng)請(qǐng)求為 /images/0.jpg 時(shí), path ==> 0.jpg
@app.get("/images/{path}")
# 注意這里的參數(shù)需要設(shè)置為 path
# path : str ==> 指定path為字符串類型的數(shù)據(jù)
def get_pic(path: str):
# 這里open()的路徑就是 ==> f"source/images/0.jpg"
with open(f"source/images/{path}", "rb") as f:
data = f.read()
# return 返回響應(yīng)數(shù)據(jù)
# Response(content=data, media_type="jpg")
# 參數(shù)1: 響應(yīng)數(shù)據(jù)
# 參數(shù)2: 數(shù)據(jù)格式
return Response(content=data, media_type="jpg")
完整代碼
# 導(dǎo)入FastAPI模塊
from fastapi import FastAPI
# 導(dǎo)入響應(yīng)報(bào)文Response模塊
from fastapi import Response
# 導(dǎo)入服務(wù)器uvicorn模塊
import uvicorn
# 創(chuàng)建FastAPI框架對(duì)象
app = FastAPI()
# 當(dāng)請(qǐng)求為 /images/0.jpg 時(shí), path ==> 0.jpg
@app.get("/images/{path}")
# 注意這里的參數(shù)需要設(shè)置為 path
# path : str ==> 指定path為字符串類型的數(shù)據(jù)
def get_pic(path: str):
# 這里open()的路徑就是 ==> f"source/images/0.jpg"
with open(f"source/images/{path}", "rb") as f:
data = f.read()
# return 返回響應(yīng)數(shù)據(jù)
# Response(content=data, media_type="jpg")
# 參數(shù)1: 響應(yīng)數(shù)據(jù)
# 參數(shù)2: 數(shù)據(jù)格式
return Response(content=data, media_type="jpg")
@app.get("/{path}")
def get_html(path: str):
with open(f"source/html/{path}", 'rb') as f:
data = f.read()
# return 返回響應(yīng)數(shù)據(jù)
# Response(content=data, media_type="text/source"
# 參數(shù)1: 響應(yīng)數(shù)據(jù)
# 參數(shù)2: 數(shù)據(jù)格式
return Response(content=data, media_type="text/html")
# 運(yùn)行服務(wù)器
# 參數(shù)1: 框架對(duì)象
# 參數(shù)2: IP地址
# 參數(shù)3: 端口號(hào)
uvicorn.run(app, host="127.0.0.1", port=8000)
運(yùn)行結(jié)果
三. Python爬蟲介紹
1. 什么是爬蟲
網(wǎng)絡(luò)爬蟲:
又被稱為網(wǎng)頁蜘蛛,網(wǎng)絡(luò)機(jī)器人,是一種按照一定的規(guī)則,自動(dòng)地抓取網(wǎng)絡(luò)信息的程序或者腳本,另外一些不常使用的名字還有螞蟻、自動(dòng)索引、模擬程序或者蠕蟲。
通俗理解:
簡單來講,爬蟲就是一個(gè)探測機(jī)器,它的基本操作就是模擬人的行為去各個(gè)網(wǎng)站溜達(dá),點(diǎn)點(diǎn)按鈕,查查數(shù)據(jù),或者把看到的信息背回來. 就像一只蟲子在一幢樓里不知疲倦地爬來爬去.
你可以簡單地想象: 每個(gè)爬蟲都是你的「分身」。就像孫悟空拔了一撮汗毛,吹出一堆猴子一樣
**百度:**其實(shí)就是利用了這種爬蟲技術(shù), 每天放出無數(shù)爬蟲到各個(gè)網(wǎng)站,把他們的信息抓回來,然后化好淡妝排著小隊(duì)等你來檢索。
有了這樣的特性, 對(duì)于一些自己公司數(shù)據(jù)量不足的小公司, 這個(gè)時(shí)候還想做數(shù)據(jù)分析就可以通過爬蟲獲取同行業(yè)的數(shù)據(jù)然后進(jìn)行分析, 進(jìn)而指導(dǎo)公司的策略指定。
2. 爬蟲的基本步驟
基本步驟:
起始URL地址
發(fā)出請(qǐng)求獲取響應(yīng)數(shù)據(jù)
對(duì)響應(yīng)數(shù)據(jù)解析
數(shù)據(jù)入庫
3. 安裝requests模塊
- requests : 可以模擬瀏覽器的請(qǐng)求
- 官方文檔 :http://cn.python-requests.org/zh_CN/latest/
- 安裝 :pip install requests
快速入門(requests三步走):
# 導(dǎo)入模塊
import requests
# 通過requests.get()發(fā)送請(qǐng)求
# data保存返回的響應(yīng)數(shù)據(jù)(這里的響應(yīng)數(shù)據(jù)不是單純的html,需要通過content獲取html代碼)
data = requests.get("http://www.baidu.com")
# 通過data.content獲取html代碼
data = data.content.decode("utf-8")
4. 爬取照片
① 查看index.html

② 爬取照片步驟
- 獲取index.html代碼
- 解析index.html代碼獲取圖片url
- 通過圖片url獲取圖片
③ 獲取index.html代碼
# 通過爬蟲向index.html發(fā)送請(qǐng)求
# requests.get(網(wǎng)址): 向一個(gè)網(wǎng)址發(fā)送請(qǐng)求,和在瀏覽器中輸入網(wǎng)址是一樣的
data = requests.get("http://127.0.0.1:8000/index.html")
# content可以把requests.get()獲取的返回值中的html內(nèi)容獲取到
data = data.content.decode("utf-8")
④ 解析index.html代碼獲取圖片url
# 獲取圖片的請(qǐng)求url
def get_pic_url():
# 通過爬蟲向index.html發(fā)送請(qǐng)求
# requests.get(網(wǎng)址): 向一個(gè)網(wǎng)址發(fā)送請(qǐng)求,和在瀏覽器中輸入網(wǎng)址是一樣的
data = requests.get("http://127.0.0.1:8000/index.html")
# content可以把requests.get()獲取的返回值中的html內(nèi)容獲取到
data = data.content.decode("utf-8")
# html每一行都有"
", 對(duì)html進(jìn)行分割獲得一個(gè)列表
data = data.split("
")
# 創(chuàng)建一個(gè)列表存儲(chǔ)所有圖片的url地址(也就是圖片網(wǎng)址)
url_list = []
for url in data:
# 通過正則解析出所有的圖片url
result = re.match('.*src="(.*)" width.*', url)
if result is not None:
# 把解析出來的圖片url添加到url_list中
url_list.append(result.group(1))
return url_list
⑤ 通過圖片url獲取圖片
# 把爬取到的圖片保存到本地
def save_pic(url_list):
# 通過num給照片起名字 例如:0.jpg 1.jpg 2.jpg
num = 0
for url in url_list:
# 通過requests.get()獲取每一張圖片
pic = requests.get(f"http://127.0.0.1:8000{url[1:]}")
# 保存每一張圖片
with open(f"./source/spyder/{num}.jpg", "wb") as f:
f.write(pic.content)
num += 1
完整代碼
# 把爬取到的圖片保存到本地
def save_pic(url_list):
# 通過num給照片起名字 例如:0.jpg 1.jpg 2.jpg
num = 0
for url in url_list:
# 通過requests.get()獲取每一張圖片
pic = requests.get(f"http://127.0.0.1:8000{url[1:]}")
# 保存每一張圖片
with open(f"./source/spyder/{num}.jpg", "wb") as f:
f.write(pic.content)
num += 1
四. 使用Python爬取GDP數(shù)據(jù)
1. gdp.html

通過訪問 http://127.0.0.1:8080/gdp.html 可以獲取2020年世界GDP排名. 在這里我們通過和爬取照片一樣的流程步驟獲取GDP數(shù)據(jù)。
2. zip函數(shù)的使用
zip() 函數(shù): 用于將可迭代的對(duì)象作為參數(shù),將對(duì)象中對(duì)應(yīng)的元素打包成一個(gè)個(gè)元組,然后返回由這些元組組成的列表.
a = [1, 2, 3] b = [4, 5, 6] c = [4, 5, 6, 7, 8] # 打包為元組的列表 zipped = zip(a, b) # 注意使用的時(shí)候需要list轉(zhuǎn)化 print(list(zipped)) >>> [(1, 4), (2, 5), (3, 6)] # 元素個(gè)數(shù)與最短的列表一致 zipped = zip(a, c) # 注意使用的時(shí)候需要list轉(zhuǎn)化 print(list(zipped)) >>> [(1, 4), (2, 5), (3, 6)]
3.爬取GDP數(shù)據(jù)
import requests
import re
# 存儲(chǔ)爬取到的國家的名字
country_list = []
# 存儲(chǔ)爬取到的國家gdp的數(shù)據(jù)
gdp_list = []
# 獲取gdp數(shù)據(jù)
def get_gdp_data():
global country_list
global gdp_list
# 獲取gdp的html數(shù)據(jù)
data = requests.get("http://localhost:8000/gdp.html")
# 對(duì)獲取數(shù)據(jù)進(jìn)行解碼
data = data.content.decode("utf8")
# 對(duì)gdp的html數(shù)據(jù)進(jìn)行按行分割
data_list = data.split("
")
for i in data_list:
# 對(duì)html進(jìn)行解析獲取<國家名字>
country_result = re.match('.*<a href=""><font>(.*)</font></a>', i)
# 匹配成功就存放到列表中
if country_result is not None:
country_list.append(country_result.group(1))
# 對(duì)html進(jìn)行解析獲取<gdp數(shù)據(jù)>
gdp_result = re.match(".*¥(.*)億元", i)
# 匹配成功就存儲(chǔ)到列表中
if gdp_result is not None:
gdp_list.append(gdp_result.group(1))
# 把兩個(gè)列表融合成一個(gè)列表
gdp_data = list(zip(country_list, gdp_list))
print(gdp_data)
if __name__ == '__main__':
get_gdp_data()
五. 多任務(wù)爬蟲實(shí)現(xiàn)
1. 為什么用多任務(wù)
在我們的案例中, 我們只是爬取了2個(gè)非常簡單的頁面, 這兩個(gè)頁面的數(shù)據(jù)爬取并不會(huì)使用太多的時(shí)間, 所以我們也沒有太多的考慮效率問題.
但是在真正的工作環(huán)境中, 我們爬取的數(shù)據(jù)可能非常的多, 如果還是使用單任務(wù)實(shí)現(xiàn), 這時(shí)候就會(huì)讓我們爬取數(shù)據(jù)的時(shí)間很長, 那么顯然使用多任務(wù)可以大大提升我們爬取數(shù)據(jù)的效率
2. 多任務(wù)爬取數(shù)據(jù)
實(shí)際上實(shí)現(xiàn)多任務(wù)并不難, 只需要使用多任務(wù)就可以了
3. 多任務(wù)代碼實(shí)現(xiàn)
# 獲取gdp
def get_gdp_data():
pass
# 獲取照片
def get_pic():
pass
if __name__ == '__main__':
p1 = multiprocessing.Process(target=get_pic
p2 = multiprocessing.Process(target=get_gdp_data)
p1.start()
p2.start()
六. 數(shù)據(jù)可視化
1. 什么是數(shù)據(jù)可視化

數(shù)據(jù)可視化:顧名思義就是讓數(shù)據(jù)看的到, 他的作用也很明顯, 讓人們不用再去閱讀枯燥無味的數(shù)據(jù), 一眼看去就可以明白數(shù)據(jù)是什么, 數(shù)據(jù)間的關(guān)系是什么, 更好的讓我們通過數(shù)據(jù)發(fā)現(xiàn)潛在的規(guī)律進(jìn)而進(jìn)行商業(yè)決策。
2. pyecharts模塊

概況 :
Echarts 是個(gè)由百度開源的數(shù)據(jù)可視化,憑借著良好的交互性,精巧的圖表設(shè)計(jì),得到了眾多開發(fā)者的認(rèn)可. 而 Python 是門富有表達(dá)力的語言,很適合用于數(shù)據(jù)處理. 當(dāng)數(shù)據(jù)分析遇上數(shù)據(jù)可視化時(shí)pyecharts 誕生了.
特性 :
- 簡潔的API設(shè)計(jì),使用如絲滑般流暢,支持鏈?zhǔn)秸{(diào)用
- 囊括了**30+**種常見圖表,應(yīng)有盡有
- 支持主流Notebook 環(huán)境,Jupyter Notebook 和JupyterLab
- 可輕松集成至Flask, Django等主流Web框架
- 高度靈活的配置項(xiàng),可輕松搭配出精美的圖表
- 詳細(xì)的文檔和示例,幫助開發(fā)者更快的上手項(xiàng)目
- 多達(dá)400+地圖文件以及原生的百度地圖,為地理數(shù)據(jù)可視化提供強(qiáng)有力的支持
3. 通過pyecharts模塊創(chuàng)建餅狀圖
導(dǎo)入模塊
# 導(dǎo)入餅圖模塊 from pyecharts.charts import Pie # 導(dǎo)入配置選項(xiàng)模塊 import pyecharts.options as opts
初始化餅狀圖:
Pie()函數(shù): 創(chuàng)建餅圖
opts.InitOpts參數(shù): Pie(init_opts=opts.InitOpts(width=“1400px”, height=“800px”))
init_opts: 指定參數(shù)名
opts.InitOpts: 配置選項(xiàng)
**width=“1400px” height=“800px” *界面的寬度和高度
# 創(chuàng)建餅圖并設(shè)置這個(gè)界面的長和高 # px:像素單位 pie = Pie(init_opts=opts.InitOpts(width="1400px", height="800px"))
給餅圖添加數(shù)據(jù):
add()函數(shù):
參數(shù)1: 名稱
參數(shù)2: 具體數(shù)據(jù), 數(shù)據(jù)類型為==>[(a,b),(a,b),(a,b)]==>a為數(shù)據(jù)名稱,b為數(shù)據(jù)大小
參數(shù)3: 標(biāo)簽設(shè)置 label_opts=opts.LabelOpts(formatter=‘:wppm3vysvbp%’) 符合百分比的形式
# 給餅圖添加數(shù)據(jù) pie.add( "GDP", data, label_opts=opts.LabelOpts(formatter=':wppm3vysvbp%') )
給餅圖添設(shè)置標(biāo)題:
set_global_opts()函數(shù) :
title_opts=opts.TitleOpts : 設(shè)置標(biāo)題
title=“2020年世界GDP排名”, subtitle=“美元” : 設(shè)置主標(biāo)題和副標(biāo)題
# 給餅圖設(shè)置標(biāo)題 pie.set_global_opts(title_opts=opts.TitleOpts(title="2020年世界GDP排名", subtitle="美元"))
保存數(shù)據(jù):
# 保存結(jié)果 pie.render()
4. 完整代碼
import requests
import re
# 導(dǎo)入餅圖模塊
from pyecharts.charts import Pie
# 導(dǎo)入配置選項(xiàng)模塊
import pyecharts.options as opts
# 存儲(chǔ)爬取到的國家的名字
country_list = []
# 春初爬取到的國家gdp的數(shù)據(jù)
gdp_list = []
def get_gdp_data():
global country_list
global gdp_list
# 獲取gdp的html數(shù)據(jù)
data = requests.get("http://localhost:8000/gdp.html")
# 對(duì)獲取數(shù)據(jù)進(jìn)行解碼
data = data.content.decode("utf8")
# 對(duì)gdp的html數(shù)據(jù)進(jìn)行按行分割
data_list = data.split("
")
for i in data_list:
# 對(duì)html進(jìn)行解析獲取<國家名字>
country_result = re.match('.*<a href=""><font>(.*)</font></a>', i)
# 匹配成功就存放到列表中
if country_result is not None:
country_list.append(country_result.group(1))
# 對(duì)html進(jìn)行解析獲取<gdp數(shù)據(jù)>
gdp_result = re.match(".*¥(.*)億元", i)
# 匹配成功就存儲(chǔ)到列表中
if gdp_result is not None:
gdp_list.append(gdp_result.group(1))
# 創(chuàng)建一個(gè)餅狀圖顯示GDP前十的國家
def data_view_pie():
# 獲取前十的過的GDP數(shù)據(jù), 同時(shí)讓數(shù)據(jù)符合[(),()...]的形式
data = list(zip(country_list[:10], gdp_list[:10]))
# 創(chuàng)建餅圖
pie = Pie(init_opts=opts.InitOpts(width="1400px", height="800px"))
# 給餅圖添加數(shù)據(jù)
pie.add(
"GDP",
data,
label_opts=opts.LabelOpts(formatter=':wppm3vysvbp%')
)
# 給餅圖設(shè)置標(biāo)題
pie.set_global_opts(title_opts=opts.TitleOpts(title="2020年世界GDP排名", subtitle="美元"))
# 保存結(jié)果
pie.render()
if __name__ == '__main__':
# 獲取GDP數(shù)據(jù)
get_gdp_data()
# 生成可視化餅圖
data_view_pie()
5. 小結(jié)
可視化
- Pie()函數(shù) : 創(chuàng)建餅圖
- add()函數(shù) : 添加數(shù)據(jù)
- set_global_opts()函數(shù) : 設(shè)置標(biāo)題
- render()函數(shù) : 保存數(shù)據(jù)
七. Logging日志模塊
1. logging日志的介紹
在現(xiàn)實(shí)生活中,記錄日志非常重要,比如:銀行轉(zhuǎn)賬時(shí)會(huì)有轉(zhuǎn)賬記錄;飛機(jī)飛行過程中,會(huì)有個(gè)黑盒子(飛行數(shù)據(jù)記錄器)記錄著飛機(jī)的飛行過程,那在咱們python程序中想要記錄程序在運(yùn)行時(shí)所產(chǎn)生的日志信息,怎么做呢
可以使用 logging 這個(gè)包來完成
記錄程序日志信息的目的是:
- 可以很方便的了解程序的運(yùn)行情況
- 可以分析用戶的操作行為、喜好等信息
- 方便開發(fā)人員檢查bug
2. logging日志級(jí)別介紹
日志等級(jí)可以分為5個(gè),從低到高分別是:
- DEBUG
- INFO
- WARNING
- ERROR
- CRITICAL
日志等級(jí)說明:
- DEBUG:程序調(diào)試bug時(shí)使用
- INFO:程序正常運(yùn)行時(shí)使用
- WARNING:程序未按預(yù)期運(yùn)行時(shí)使用,但并不是錯(cuò)誤,如:用戶登錄密碼錯(cuò)誤
- ERROR:程序出錯(cuò)誤時(shí)使用,如:IO操作失敗
- CRITICAL:特別嚴(yán)重的問題,導(dǎo)致程序不能再繼續(xù)運(yùn)行時(shí)使用,如:磁盤空間為空,一般很少使用
- 默認(rèn)的是WARNING等級(jí),當(dāng)在WARNING或WARNING之上等級(jí)的才記錄日志信息。
- 日志等級(jí)從低到高的順序是: DEBUG < INFO < WARNING < ERROR < CRITICAL
3. logging日志的使用
在 logging 包中記錄日志的方式有兩種:
- 輸出到控制臺(tái)
- 保存到日志文件
日志信息輸出到控制臺(tái)的示例代碼:
import logging
logging.debug('這是一個(gè)debug級(jí)別的日志信息')
logging.info('這是一個(gè)info級(jí)別的日志信息')
logging.warning('這是一個(gè)warning級(jí)別的日志信息')
logging.error('這是一個(gè)error級(jí)別的日志信息')
logging.critical('這是一個(gè)critical級(jí)別的日志信息')
運(yùn)行結(jié)果:
WARNING:root:這是一個(gè)warning級(jí)別的日志信息 ERROR:root:這是一個(gè)error級(jí)別的日志信息 CRITICAL:root:這是一個(gè)critical級(jí)別的日志信息
說明:
日志信息只顯示了大于等于WARNING級(jí)別的日志,這說明默認(rèn)的日志級(jí)別設(shè)置為WARNING
logging日志等級(jí)和輸出格式的設(shè)置:import logging
設(shè)置日志等級(jí)和輸出日志格式
logging.basicConfig(level=logging.DEBUG,
format=‘%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s’)logging.debug(‘這是一個(gè)debug級(jí)別的日志信息’)
logging.info(‘這是一個(gè)info級(jí)別的日志信息’)
logging.warning(‘這是一個(gè)warning級(jí)別的日志信息’)
logging.error(‘這是一個(gè)error級(jí)別的日志信息’)
logging.critical(‘這是一個(gè)critical級(jí)別的日志信息’)
運(yùn)行結(jié)果:
2019-02-13 20:41:33,080 - hello.py[line:6] - DEBUG: 這是一個(gè)debug級(jí)別的日志信息 2019-02-13 20:41:33,080 - hello.py[line:7] - INFO: 這是一個(gè)info級(jí)別的日志信息 2019-02-13 20:41:33,080 - hello.py[line:8] - WARNING: 這是一個(gè)warning級(jí)別的日志信息 2019-02-13 20:41:33,080 - hello.py[line:9] - ERROR: 這是一個(gè)error級(jí)別的日志信息 2019-02-13 20:41:33,080 - hello.py[line:10] - CRITICAL: 這是一個(gè)critical級(jí)別的日志信息
代碼說明:
- level 表示設(shè)置的日志等級(jí)
- format 表示日志的輸出格式, 參數(shù)說明:
- %(levelname)s: 打印日志級(jí)別名稱
- %(filename)s: 打印當(dāng)前執(zhí)行程序名
- %(lineno)d: 打印日志的當(dāng)前行號(hào)
- %(asctime)s: 打印日志的時(shí)間
- %(message)s: 打印日志信息
日志信息保存到日志文件的示例代碼:
import logging
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s',
filename="log.txt",
filemode="w")
logging.debug('這是一個(gè)debug級(jí)別的日志信息')
logging.info('這是一個(gè)info級(jí)別的日志信息')
logging.warning('這是一個(gè)warning級(jí)別的日志信息')
logging.error('這是一個(gè)error級(jí)別的日志信息')
logging.critical('這是一個(gè)critical級(jí)別的日志信息')
運(yùn)行結(jié)果:
4. logging日志在Web項(xiàng)目中應(yīng)用
使用logging日志示例:
程序入口模塊設(shè)置logging日志的設(shè)置
導(dǎo)入FastAPI模塊
from fastapi import FastAPI
導(dǎo)入響應(yīng)報(bào)文Response模塊
from fastapi import Response
導(dǎo)入服務(wù)器uvicorn模塊
import uvicorn
導(dǎo)入日志模塊
import logging
配置日志
logging.basicConfig(level=logging.INFO,
format=‘%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s’,
filename=“log.txt”,
filemode=“w”)訪問index.html時(shí)進(jìn)行日志輸出,示例代碼:
當(dāng)請(qǐng)求為 /images/0.jpg 時(shí), path ==> 0.jpg
@app.get(“/images/{path}”)
注意這里的參數(shù)需要設(shè)置為 path
path : str ==> 指定path為字符串類型的數(shù)據(jù)
def get_pic(path: str):
# 這里open()的路徑就是 ==> f"source/images/0.jpg"
with open(f"source/images/{path}", “rb”) as f:
data = f.read()
# 打log
logging.info(“訪問了” + path)
# return 返回響應(yīng)數(shù)據(jù)
# Response(content=data, media_type=“jpg”)
# 參數(shù)1: 響應(yīng)數(shù)據(jù)
# 參數(shù)2: 數(shù)據(jù)格式
return Response(content=data, media_type=“jpg”)訪問gdp.html時(shí)進(jìn)行日志輸出,示例代碼:
@app.get(“/{path}”)
def get_html(path: str):
with open(f"source/html/{path}") as f:
data = f.read()
# 打log
logging.info(“訪問了” + path)
# return 返回響應(yīng)數(shù)據(jù)
# Response(content=data, media_type=“text/source”
# 參數(shù)1: 響應(yīng)數(shù)據(jù)
# 參數(shù)2: 數(shù)據(jù)格式
return Response(content=data, media_type=“text/html”)
logging日志:
通過日志信息我們得知, index.html被訪問了2次, gdp.html被訪問了2次.
說明:
- logging日志配置信息在程序入口模塊設(shè)置一次,整個(gè)程序都可以生效。
- logging.basicConfig 表示 logging 日志配置操作
5. 小結(jié)
- 記錄python程序中日志信息使用 logging 包來完成
- logging日志等級(jí)有5個(gè):
- DEBUG
- INFO
- WARNING
- ERROR
- CRITICAL
- 打印(記錄)日志的函數(shù)有5個(gè):
- logging.debug函數(shù), 表示: 打印(記錄)DEBUG級(jí)別的日志信息
- logging.info函數(shù), 表示: 打印(記錄)INFO級(jí)別的日志信息
- logging.warning函數(shù), 表示: 打印(記錄)WARNING級(jí)別的日志信息
- logging.error函數(shù), 表示: 打印(記錄)ERROR級(jí)別的日志信息
- logging.critical函數(shù), 表示: 打印(記錄)CRITICAL級(jí)別的日志信息
總結(jié)
到此這篇關(guān)于Python多任務(wù)爬蟲實(shí)現(xiàn)爬取圖片和GDP數(shù)據(jù)的文章就介紹到這了,更多相關(guān)Python多任務(wù)爬蟲圖片和GDP數(shù)據(jù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Keras構(gòu)建神經(jīng)網(wǎng)絡(luò)踩坑(解決model.predict預(yù)測值全為0.0的問題)
這篇文章主要介紹了Keras構(gòu)建神經(jīng)網(wǎng)絡(luò)踩坑(解決model.predict預(yù)測值全為0.0的問題),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-07-07
Python+Sklearn實(shí)現(xiàn)英文文本關(guān)鍵詞提取的完整代碼
在自然語言處理(NLP)的文本分析領(lǐng)域,TF-IDF 是實(shí)現(xiàn)關(guān)鍵詞提取的經(jīng)典加權(quán)算法,能精準(zhǔn)篩選出文本中兼具單篇高頻和語料庫低頻的核心詞匯,本文將基于Python+Sklearn,針對(duì)英文文本實(shí)現(xiàn) TF-IDF 的全流程實(shí)戰(zhàn),需要的朋友可以參考下2026-03-03
如何利用python實(shí)現(xiàn)kmeans聚類
K-Means是聚類算法的一種,以距離來判斷數(shù)據(jù)點(diǎn)間的相似度并對(duì)數(shù)據(jù)進(jìn)行聚類,下面這篇文章主要給大家介紹了關(guān)于如何利用python實(shí)現(xiàn)kmeans聚類的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-05-05
Python實(shí)現(xiàn)批量將圖像png格式轉(zhuǎn)為npy格式
在進(jìn)行深度學(xué)習(xí)處理時(shí),有些的代碼處理的數(shù)據(jù)格式為npy,但是常常有的數(shù)據(jù)格式為png,因此本文就來介紹一下Python如何實(shí)現(xiàn)圖像批量png格式轉(zhuǎn)為npy格式,需要的可以參考下2023-12-12
python RabbitMQ 使用詳細(xì)介紹(小結(jié))
這篇文章主要介紹了python RabbitMQ 使用詳細(xì)介紹(小結(jié)),詳細(xì)的介紹了RabbitMQ的概念以及使用,對(duì)學(xué)習(xí)RabbitMQ有一定的幫助,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2018-11-11
Python 多繼承中的一個(gè)詭異現(xiàn)象 既是 Father又是grandfather
我們知道,在面向?qū)ο缶幊汤锩?,繼承是一個(gè)很重要的概念。子類可以使用父類的方法和屬性,接下來小編將用舉例的方式為大家講解Python 多繼承中的一個(gè)詭異現(xiàn)象 其即是爸爸又是爺爺?shù)钠孑猬F(xiàn)象,感興趣的小伙伴可以看下面文章具體了解2021-09-09
python GUI庫圖形界面開發(fā)之PyQt5中QMainWindow, QWidget以及QDialog的區(qū)別和選擇
這篇文章主要介紹了python GUI庫圖形界面開發(fā)之PyQt5中QMainWindow, QWidget以及QDialog的區(qū)別和選擇,需要的朋友可以參考下2020-02-02
在Python的Django框架中實(shí)現(xiàn)Hacker News的一些功能
這篇文章主要介紹了在Python的Django框架中實(shí)現(xiàn)Hacker News的一些功能,包括投票“頂”評(píng)論等功能,需要的朋友可以參考下2015-04-04
Python 輸出時(shí)去掉列表元組外面的方括號(hào)與圓括號(hào)的方法
今天小編就為大家分享一篇Python 輸出時(shí)去掉列表元組外面的方括號(hào)與圓括號(hào)的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-12-12

