当前位置: 首页 > news >正文

Python简单爬虫实践案例

学习目标

  • 能够知道Web开发流程

  • 能够掌握FastAPI实现访问多个指定网页

  • 知道通过requests模块爬取图片

  • 知道通过requests模块爬取GDP数据

  • 能够用pyecharts实现饼图

  • 能够知道logging日志的使用

一、基于FastAPI之Web站点开发

1、基于FastAPI搭建Web服务器

# 导入FastAPI模块
from fastapi import FastAPI
# 导入响应报文Response模块
from fastapi import Response
# 导入服务器uvicorn模块
import uvicorn
​
# 创建FastAPI框架对象
app = FastAPI()
​
​
# 通过@app路由装饰器收发数据
# @app.get(参数) : 按照get方式接受请求数据
# 请求资源的 url 路径
@app.get("/index.html")
def main():with open("source/html/index.html") as f:data = f.read()# return 返回响应数据# Response(content=data, media_type="text/html"# 参数1: 响应数据# 参数2: 数据格式return Response(content=data, media_type="text/html")
​
​
# 运行服务器
# 参数1: 框架对象
# 参数2: IP地址
# 参数3: 端口号
uvicorn.run(app, host="127.0.0.1", port=8000)

运行结果:

2、Web服务器和浏览器的通讯流程

实际上Web服务器和浏览器的通讯流程过程并不是一次性完成的, 这里html代码中也会有访问服务器的代码, 比如请求图片资源。

那像0.jpg、1.jpg、2.jpg、3.jpg、4.jpg、5.jpg、6.jpg这些访问来自哪里呢 ?

答:它们来自index.html

3、浏览器访问Web服务器的通讯流程

浏览器访问Web服务器的通讯流程

  1. 浏览器 (127.0.0.1/index.html) ==> 向Web服务器请求index.html

  2. Web服务器 (返回index.html) ==> 浏览器

  3. 浏览器解析index.html发现需要0.jpg ==>发送请求给 Web服务器请求0.jpg

  4. Web服务器 收到请求返回0.jpg ==> 浏览器 接受0.jpg

通讯过程能够成功的前提

浏览器发送的0.jpg请求, Web服务器可以做出响应, 也就是代码如下

# 当浏览器发出对图片 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")

4、加载图片资源代码

# 导入FastAPI模块
from fastapi import FastAPI
# 导入响应报文Response模块
from fastapi import Response
# 导入服务器uvicorn模块
import uvicorn
​
# 创建FastAPI框架对象
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("/gdp.html")
def func_08():with open("source/html/gdp.html") as f:data = f.read()return Response(content=data, media_type="text/source")
​
​
@app.get("/index.html")
def main():with open("source/html/index.html") as f:data = f.read()# return 返回响应数据# Response(content=data, media_type="text/source"# 参数1: 响应数据# 参数2: 数据格式return Response(content=data, media_type="text/html")
​
​
# 运行服务器
# 参数1: 框架对象
# 参数2: IP地址
# 参数3: 端口号
uvicorn.run(app, host="127.0.0.1", port=8000)

5、小结

  • 浏览器访问Web服务器的通讯流程:

    • 浏览器 (127.0.0.1/index.html) ==> 向Web服务器请求index.html

    • Web服务器 (返回index.html) ==> 浏览器

    • 浏览器解析index.html发现需要0.jpg ==>发送请求给 Web服务器请求0.jpg

    • Web服务器 收到请求返回0.jpg ==> 浏览器 接受0.jpg

二、基于Web请求的FastAPI通用配置

1、目前Web服务器存在问题

# 返回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")

对以上代码观察,会发现每一张图片0.jpg、1.jpg、2.jpg就需要一个函数对应, 如果我们需要1000张图片那就需要1000个函数对应, 显然这样做代码的重复太多了.

2、基于Web请求的FastAPI通用配置

# 当请求为 /images/0.jpg 时, path ==> 0.jpg
@app.get("/images/{path}")
# 注意这里的参数需要设置为 path
# path : str ==> 指定path为字符串类型的数据
def get_pic(path: str):# 这里open()的路径就是 ==> f"source/images/0.jpg"with open(f"source/images/{path}", "rb") as f:data = f.read()# return 返回响应数据# Response(content=data, media_type="jpg")# 参数1: 响应数据# 参数2: 数据格式return Response(content=data, media_type="jpg")

完整代码:

# 导入FastAPI模块
from fastapi import FastAPI
# 导入响应报文Response模块
from fastapi import Response
# 导入服务器uvicorn模块
import uvicorn
​
# 创建FastAPI框架对象
app = FastAPI()
​
​
# 当请求为 /images/0.jpg 时, path ==> 0.jpg
@app.get("/images/{path}")
# 注意这里的参数需要设置为 path
# path : str ==> 指定path为字符串类型的数据
def get_pic(path: str):# 这里open()的路径就是 ==> f"source/images/0.jpg"with open(f"source/images/{path}", "rb") as f:data = f.read()# return 返回响应数据# Response(content=data, media_type="jpg")# 参数1: 响应数据# 参数2: 数据格式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 返回响应数据# Response(content=data, media_type="text/source"# 参数1: 响应数据# 参数2: 数据格式return Response(content=data, media_type="text/html")
​
​
# 运行服务器
# 参数1: 框架对象
# 参数2: IP地址
# 参数3: 端口号
uvicorn.run(app, host="127.0.0.1", port=8000)

运行结果:

3、小结

通用配置代码:

# 当请求为 /images/0.jpg 时, path ==> 0.jpg
@app.get("/images/{path}")
# 注意这里的参数需要设置为 path
# path : str ==> 指定path为字符串类型的数据
def get_pic(path: str):# 这里open()的路径就是 ==> f"source/images/0.jpg"with open(f"source/images/{path}", "rb") as f:data = f.read()# return 返回响应数据# Response(content=data, media_type="jpg")# 参数1: 响应数据# 参数2: 数据格式return Response(content=data, media_type="jpg")

三、Python爬虫介绍

1、什么是爬虫

网络爬虫:

又被称为网页蜘蛛,网络机器人,是一种按照一定的规则,自动地抓取网络信息的程序或者脚本,另外一些不常使用的名字还有蚂蚁、自动索引、模拟程序或者蠕虫。

通俗理解:

简单来讲,爬虫就是一个探测机器,它的基本操作就是模拟人的行为去各个网站溜达,点点按钮,查查数据,或者把看到的信息背回来. 就像一只虫子在一幢楼里不知疲倦地爬来爬去.

你可以简单地想象 每个爬虫都是你的「分身」。就像孙悟空拔了一撮汗毛,吹出一堆猴子一样

百度:其实就是利用了这种爬虫技术, 每天放出无数爬虫到各个网站,把他们的信息抓回来,然后化好淡妆排着小队等你来检索。

有了这样的特性, 对于一些自己公司数据量不足的小公司, 这个时候还想做数据分析就可以通过爬虫获取同行业的数据然后进行分析, 进而指导公司的策略指定。

2、爬虫的基本步骤

基本步骤:

  • 起始URL地址

  • 发出请求获取响应数据

  • 对响应数据解析

  • 数据入库

3、安装requests模块

  • requests : 可以模拟浏览器的请求

  • 官方文档 :Requests: 让 HTTP 服务人类 — Requests 2.18.1 文档

  • 安装 :pip install requests

快速入门(requests三步走):

# 导入模块
import requests
# 通过requests.get()发送请求
# data保存返回的响应数据(这里的响应数据不是单纯的html,需要通过content获取html代码)
data = requests.get("http://www.baidu.com")
# 通过data.content获取html代码
data = data.content.decode("utf-8")

4、小结

requests三步走:

# 导入模块
import requests
# 通过requests.get()发送请求
# data保存返回的响应数据(这里的响应数据不是单纯的html,需要通过content获取html代码)
data = requests.get("http://www.baidu.com")
# 通过data.content获取html代码
data = data.content.decode("utf-8")

5、爬取照片

☆ 查看index.html

☆ 爬取照片的步骤

  1. 获取index.html代码

  2. 解析index.html代码获取图片url

  3. 通过图片url获取图片

☆ 获取index.html代码

# 通过爬虫向index.html发送请求
# requests.get(网址): 向一个网址发送请求,和在浏览器中输入网址是一样的
data = requests.get("http://127.0.0.1:8000/index.html")
# content可以把requests.get()获取的返回值中的html内容获取到
data = data.content.decode("utf-8")

☆ 解析index.html代码获取图片url

# 获取图片的请求url
def get_pic_url():# 通过爬虫向index.html发送请求# requests.get(网址): 向一个网址发送请求,和在浏览器中输入网址是一样的data = requests.get("http://127.0.0.1:8000/index.html")# content可以把requests.get()获取的返回值中的html内容获取到data = data.content.decode("utf-8")# html每一行都有"\n", 对html进行分割获得一个列表data = data.split("\n")# 创建一个列表存储所有图片的url地址(也就是图片网址)url_list = []for url in data:# 通过正则解析出所有的图片urlresult = 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.jpgnum = 0for 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

完整代码:

import requests
import re
​
​
# 获取图片的请求url
def get_pic_url():# 通过爬虫向index.html发送请求# requests.get(网址): 向一个网址发送请求,和在浏览器中输入网址是一样的data = requests.get("http://127.0.0.1:8000/index.html")# content可以把requests.get()获取的返回值中的html内容获取到data = data.content.decode("utf8")# html每一行都有"\n", 对html进行分割获得一个列表data = data.split("\n")# 创建一个列表存储所有图片的url地址(也就是图片网址)url_list = []for url in data:# 通过正则解析出所有的图片urlresult = re.match('.*src="(.*)" width.*', url)if result is not None:# 把解析出来的图片url添加到url_list中url_list.append(result.group(1))
​return url_list
​
​
# 把爬取到的图片保存到本地
def save_pic(url_list):# 通过num给照片起名字 例如:0.jpg 1.jpg 2.jpgnum = 0for 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
​
​
if __name__ == '__main__':url_list = get_pic_url()save_pic(url_list)

☆ 小结

  • 爬取照片的步骤

    • 获取index.html代码

    • 解析index.html代码获取图片url

    • 通过图片url获取图片

四、使用Python爬取GDP数据

1、gdp.html

通过访问 http://127.0.0.1:8080/gdp.html 可以获取2020年世界GDP排名. 在这里我们通过和爬取照片一样的流程步骤获取GDP数据。

2、zip函数的使用

zip() 函数: 用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表.

a = [1, 2, 3]
b = [4, 5, 6]
c = [4, 5, 6, 7, 8]
# 打包为元组的列表
zipped = zip(a, b)
# 注意使用的时候需要list转化
print(list(zipped))
>>> [(1, 4), (2, 5), (3, 6)]
​
# 元素个数与最短的列表一致
zipped = zip(a, c)
# 注意使用的时候需要list转化
print(list(zipped))
>>> [(1, 4), (2, 5), (3, 6)]

3、爬取GDP数据

import requests
import re
​
# 存储爬取到的国家的名字
country_list = []
# 存储爬取到的国家gdp的数据
gdp_list = []
​
​
# 获取gdp数据
def get_gdp_data():global country_listglobal gdp_list
​# 获取gdp的html数据data = requests.get("http://localhost:8000/gdp.html")# 对获取数据进行解码data = data.content.decode("utf8")# 对gdp的html数据进行按行分割data_list = data.split("\n")
​for i in data_list:# 对html进行解析获取<国家名字>country_result = re.match('.*<a href=""><font>(.*)</font></a>', i)# 匹配成功就存放到列表中if country_result is not None:country_list.append(country_result.group(1))# 对html进行解析获取<gdp数据>gdp_result = re.match(".*¥(.*)亿元", i)# 匹配成功就存储到列表中if gdp_result is not None:gdp_list.append(gdp_result.group(1))# 把两个列表融合成一个列表gdp_data = list(zip(country_list, gdp_list))print(gdp_data)
​
​
if __name__ == '__main__':get_gdp_data()

4、小结

  • 爬取gdp的步骤

    • 获取gdp.html代码

    • 解析gdp.html代码获取gdp数据

五、多任务爬虫实现

1、为什么用多任务

在我们的案例中, 我们只是爬取了2个非常简单的页面, 这两个页面的数据爬取并不会使用太多的时间, 所以我们也没有太多的考虑效率问题.

但是在真正的工作环境中, 我们爬取的数据可能非常的多, 如果还是使用单任务实现, 这时候就会让我们爬取数据的时间很长, 那么显然使用多任务可以大大提升我们爬取数据的效率

2、多任务爬取数据

实际上实现多任务并不难, 只需要使用我们之前讲过的多任务就可以了

3、多任务代码实现

# 获取gdp
def get_gdp_data():pass
​
​
# 获取照片
def get_pic():pass
​
​
if __name__ == '__main__':p1 = multiprocessing.Process(target=get_picp2 = multiprocessing.Process(target=get_gdp_data)
​p1.start()p2.start()

4、小结

  • 多任务

    1. 导入模块

    2. 创建多进程或者多线程

    3. 启动多任务

六、数据可视化

1、 什么是数据可视化

数据可视化:顾名思义就是让数据看的到, 他的作用也很明显, 让人们不用再去阅读枯燥无味的数据, 一眼看去就可以明白数据是什么, 数据间的关系是什么, 更好的让我们通过数据发现潜在的规律进而进行商业决策。

2、pyecharts模块

概况 :

Echarts 是个由百度开源的数据可视化,凭借着良好的交互性,精巧的图表设计,得到了众多开发者的认可. 而 Python 是门富有表达力的语言,很适合用于数据处理. 当数据分析遇上数据可视化时pyecharts 诞生了.

特性 :

  1. 简洁的API设计,使用如丝滑般流畅,支持链式调用

  2. 囊括了30+种常见图表,应有尽有

  3. 支持主流Notebook 环境,Jupyter NotebookJupyterLab

  4. 可轻松集成至Flask, Django等主流Web框架

  5. 高度灵活的配置项,可轻松搭配出精美的图表

  6. 详细的文档和示例,帮助开发者更快的上手项目

  7. 多达400+地图文件以及原生的百度地图,为地理数据可视化提供强有力的支持

3、通过pyecharts模块创建饼状图

导入模块

# 导入饼图模块
from pyecharts.charts import Pie
# 导入配置选项模块
import pyecharts.options as opts

初始化饼状图:

Pie()函数: 创建饼图

opts.InitOpts参数: Pie(init_opts=opts.InitOpts(width="1400px", height="800px"))

init_opts: 指定参数名

opts.InitOpts: 配置选项

width="1400px" height="800px" :界面的宽度和高度

# 创建饼图并设置这个界面的长和高 
# px:像素单位
pie = Pie(init_opts=opts.InitOpts(width="1400px", height="800px"))

给饼图添加数据:

add()函数:

参数1: 名称

参数2: 具体数据, 数据类型为==>[(a,b),(a,b),(a,b)]==>a为数据名称,b为数据大小

参数3: 标签设置 label_opts=opts.LabelOpts(formatter='{b}:{d}%') 符合百分比的形式

# 给饼图添加数据
pie.add("GDP",data,label_opts=opts.LabelOpts(formatter='{b}:{d}%')
)

给饼图添设置标题:

set_global_opts()函数 :

title_opts=opts.TitleOpts : 设置标题

title="2020年世界GDP排名", subtitle="美元" : 设置主标题和副标题

# 给饼图设置标题
pie.set_global_opts(title_opts=opts.TitleOpts(title="2020年世界GDP排名", subtitle="美元"))

保存数据:

# 保存结果
pie.render()

4、完整代码

import requests
import re
# 导入饼图模块
from pyecharts.charts import Pie
# 导入配置选项模块
import pyecharts.options as opts
​
# 存储爬取到的国家的名字
country_list = []
# 春初爬取到的国家gdp的数据
gdp_list = []
​
​
def get_gdp_data():global country_listglobal gdp_list
​# 获取gdp的html数据data = requests.get("http://localhost:8000/gdp.html")# 对获取数据进行解码data = data.content.decode("utf8")# 对gdp的html数据进行按行分割data_list = data.split("\n")
​for i in data_list:# 对html进行解析获取<国家名字>country_result = re.match('.*<a href=""><font>(.*)</font></a>', i)# 匹配成功就存放到列表中if country_result is not None:country_list.append(country_result.group(1))# 对html进行解析获取<gdp数据>gdp_result = re.match(".*¥(.*)亿元", i)# 匹配成功就存储到列表中if gdp_result is not None:gdp_list.append(gdp_result.group(1))
​
​
# 创建一个饼状图显示GDP前十的国家
def data_view_pie():# 获取前十的过的GDP数据, 同时让数据符合[(),()...]的形式data = list(zip(country_list[:10], gdp_list[:10]))# 创建饼图pie = Pie(init_opts=opts.InitOpts(width="1400px", height="800px"))# 给饼图添加数据pie.add("GDP",data,label_opts=opts.LabelOpts(formatter='{b}:{d}%'))# 给饼图设置标题pie.set_global_opts(title_opts=opts.TitleOpts(title="2020年世界GDP排名", subtitle="美元"))# 保存结果pie.render()
​
​
if __name__ == '__main__':# 获取GDP数据get_gdp_data()# 生成可视化饼图data_view_pie()

5、小结

  • 可视化

    • Pie()函数 : 创建饼图

    • add()函数 : 添加数据

    • set_global_opts()函数 : 设置标题

    • render()函数 : 保存数据

七、Logging日志模块

1、logging日志的介绍

在现实生活中,记录日志非常重要,比如:银行转账时会有转账记录;飞机飞行过程中,会有个黑盒子(飞行数据记录器)记录着飞机的飞行过程,那在咱们python程序中想要记录程序在运行时所产生的日志信息,怎么做呢?

可以使用 logging 这个包来完成

记录程序日志信息的目的是:

  1. 可以很方便的了解程序的运行情况

  2. 可以分析用户的操作行为、喜好等信息

  3. 方便开发人员检查bug

2、logging日志级别介绍

日志等级可以分为5个,从低到高分别是:

  1. DEBUG

  2. INFO

  3. WARNING

  4. ERROR

  5. CRITICAL

日志等级说明:

  • DEBUG:程序调试bug时使用

  • INFO:程序正常运行时使用

  • WARNING:程序未按预期运行时使用,但并不是错误,如:用户登录密码错误

  • ERROR:程序出错误时使用,如:IO操作失败

  • CRITICAL:特别严重的问题,导致程序不能再继续运行时使用,如:磁盘空间为空,一般很少使用

  • 默认的是WARNING等级,当在WARNING或WARNING之上等级的才记录日志信息。

  • 日志等级从低到高的顺序是: DEBUG < INFO < WARNING < ERROR < CRITICAL

3、logging日志的使用

在 logging 包中记录日志的方式有两种:

  1. 输出到控制台

  2. 保存到日志文件

日志信息输出到控制台的示例代码:

import logging
​
logging.debug('这是一个debug级别的日志信息')
logging.info('这是一个info级别的日志信息')
logging.warning('这是一个warning级别的日志信息')
logging.error('这是一个error级别的日志信息')
logging.critical('这是一个critical级别的日志信息')

运行结果:

WARNING:root:这是一个warning级别的日志信息
ERROR:root:这是一个error级别的日志信息
CRITICAL:root:这是一个critical级别的日志信息

说明:

  • 日志信息只显示了大于等于WARNING级别的日志,这说明默认的日志级别设置为WARNING

logging日志等级和输出格式的设置:

import logging
​
# 设置日志等级和输出日志格式
logging.basicConfig(level=logging.DEBUG,format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s')
​
logging.debug('这是一个debug级别的日志信息')
logging.info('这是一个info级别的日志信息')
logging.warning('这是一个warning级别的日志信息')
logging.error('这是一个error级别的日志信息')
logging.critical('这是一个critical级别的日志信息')

运行结果:

2019-02-13 20:41:33,080 - hello.py[line:6] - DEBUG: 这是一个debug级别的日志信息
2019-02-13 20:41:33,080 - hello.py[line:7] - INFO: 这是一个info级别的日志信息
2019-02-13 20:41:33,080 - hello.py[line:8] - WARNING: 这是一个warning级别的日志信息
2019-02-13 20:41:33,080 - hello.py[line:9] - ERROR: 这是一个error级别的日志信息
2019-02-13 20:41:33,080 - hello.py[line:10] - CRITICAL: 这是一个critical级别的日志信息

代码说明:

  • level 表示设置的日志等级

  • format 表示日志的输出格式, 参数说明:

    • %(levelname)s: 打印日志级别名称

    • %(filename)s: 打印当前执行程序名

    • %(lineno)d: 打印日志的当前行号

    • %(asctime)s: 打印日志的时间

    • %(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('这是一个debug级别的日志信息')
logging.info('这是一个info级别的日志信息')
logging.warning('这是一个warning级别的日志信息')
logging.error('这是一个error级别的日志信息')
logging.critical('这是一个critical级别的日志信息')

运行结果:

4、logging日志在Web项目中应用

使用logging日志示例:

  1. 程序入口模块设置logging日志的设置

    # 导入FastAPI模块from fastapi import FastAPI# 导入响应报文Response模块from fastapi import Response# 导入服务器uvicorn模块import uvicorn# 导入日志模块import logging
    ​# 配置日志logging.basicConfig(level=logging.INFO,format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s',filename="log.txt",filemode="w")

  2. 访问index.html时进行日志输出,示例代码:

    # 当请求为 /images/0.jpg 时, path ==> 0.jpg
    @app.get("/images/{path}")
    # 注意这里的参数需要设置为 path
    # path : str ==> 指定path为字符串类型的数据
    def get_pic(path: str):# 这里open()的路径就是 ==> f"source/images/0.jpg"with open(f"source/images/{path}", "rb") as f:data = f.read()# 打loglogging.info("访问了" + path)# return 返回响应数据# Response(content=data, media_type="jpg")# 参数1: 响应数据# 参数2: 数据格式return Response(content=data, media_type="jpg")

  3. 访问gdp.html时进行日志输出,示例代码:

    @app.get("/{path}")
    def get_html(path: str):with open(f"source/html/{path}") as f:data = f.read()# 打loglogging.info("访问了" + path)# return 返回响应数据# Response(content=data, media_type="text/source"# 参数1: 响应数据# 参数2: 数据格式return Response(content=data, media_type="text/html")

logging日志:

通过日志信息我们得知, index.html被访问了2次, gdp.html被访问了2次.

说明:

  • logging日志配置信息在程序入口模块设置一次,整个程序都可以生效。

    • logging.basicConfig 表示 logging 日志配置操作

5、小结

  • 记录python程序中日志信息使用 logging 包来完成

  • logging日志等级有5个:

    1. DEBUG

    2. INFO

    3. WARNING

    4. ERROR

    5. CRITICAL

  • 打印(记录)日志的函数有5个:

    1. logging.debug函数, 表示: 打印(记录)DEBUG级别的日志信息

    2. logging.info函数, 表示: 打印(记录)INFO级别的日志信息

    3. logging.warning函数, 表示: 打印(记录)WARNING级别的日志信息

    4. logging.error函数, 表示: 打印(记录)ERROR级别的日志信息

    5. logging.critical函数, 表示: 打印(记录)CRITICAL级别的日志信息

八、扩展:数据埋点

具体参考讲义

相关文章:

Python简单爬虫实践案例

学习目标 能够知道Web开发流程 能够掌握FastAPI实现访问多个指定网页 知道通过requests模块爬取图片 知道通过requests模块爬取GDP数据 能够用pyecharts实现饼图 能够知道logging日志的使用 一、基于FastAPI之Web站点开发 1、基于FastAPI搭建Web服务器 # 导入FastAPI模…...

统信UOS中使用Vscode编程

写在前面&#xff1a;统信UOS其实就是套壳的Linux系统&#xff0c;所以有问题如果搜不到解决方法&#xff0c;可以参考Linux下的解决方法。 1.环境配置 Vscode : 1.85.0 Vscode就直接下载安装就行&#xff0c;然后安装插件&#xff1a;Volar、中文汉化包 node&#xff1a;18…...

C#从入门到精通(1)

目录 第一章 C#与VS介绍 第二章 第一个C#程序 &#xff08;1&#xff09;C#程序基本组成 1.命名空间 2.类 3.Main方法 4.注释 5.语句 6.标识符及关键字 &#xff08;2&#xff09;程序编写规范 1.代码编写规则 2.程序命名方法 3.元素命名规范 第三章 变量 &…...

openharmony中hilog实证记录说明(3.1和5.0版本)

每次用这个工具hilog都有一些小用法记不清&#xff0c;需要花一些时间去查去分析使用方法&#xff0c;为了给丰富多彩的生活留出更多的时间&#xff0c;所以汇总整理共享来了&#xff0c;它来了它来了~~~~~~~~~ 开始是想通过3.1来汇总的&#xff0c;但实际测试发现openharmony…...

飞书 设计智能字段:通过“字段类型”添加AI功能列

在飞书多维表格中&#xff0c;通过“字段类型”添加AI功能列的核心逻辑是将AI模型能力与结构化数据结合&#xff0c;实现自动化内容生成与信息处理。以下是具体操作步骤及关键要点&#xff0c;结合实际应用场景说明&#xff1a; 一、基础操作步骤 创建多维表格 登录飞书&#x…...

Cannot find module @rollup/rollup-win32-x64-msvc

方法1 在package.json中添加postinstall: "scripts": {"postinstall": "node -e \"const { platform } process; if (platform win32) { require(child_process).execSync(npm install rollup/rollup-win32-x64-msvc, { stdio: inherit });…...

Docker和Dify学习笔记

文章目录 1 docker学习1.1 基本命令使用1.1.1 docker ps查看当前正在运行的镜像1.1.2 docker stop停止容器1.1.3 docker compose容器编排1.1.4 docker网络[1] 进入到容器里面敲命令[2] docker network ls[3] brige网络模式下容器访问宿主机的方式 2 Dify的安装和基础使用2.1 下…...

【AIGC】Win10系统极速部署Docker+Ragflow+Dify

【AIGC】WIN10仅3步部署DockerRagflowDify 一、 Docker快速部署1.F2进入bios界面&#xff0c;按F7设置开启VMX虚拟化技术。保存并退出。2.打开控制面板配置开启服务3.到官网下载docker安装包&#xff0c;一键安装&#xff08;全部默认勾选&#xff09; 二、 RagFlow快速部署1.确…...

Oracle ASM 磁盘组冗余策略

Oracle ASM 磁盘组冗余策略 1. 外部冗余&#xff08;External Redundancy&#xff09;2. 普通冗余&#xff08;Normal Redundancy&#xff09;3. 高冗余&#xff08;High Redundancy&#xff09;关键注意事项如何选择合适的策略&#xff1f; Oracle ASM&#xff08;Automatic S…...

C++ 数据结构

C++ 数据结构 概述 C++作为一种强大的编程语言,在软件开发领域有着广泛的应用。数据结构作为C++编程中不可或缺的一部分,它决定了程序的性能和效率。本文将详细介绍C++中的常见数据结构,包括其定义、特点以及在实际应用中的使用方法。 常见数据结构 1. 数组 数组是一种…...

Unity NodeCanvas AI使用笔记

扩展: 1. 输入输出参数限制&#xff0c;增加描述&#xff0c;根据接口判断类型限制 2.选择节点&#xff0c;遍历节点&#xff0c;行为节点 3.行为节点 行为执行的时候有互斥关系&#xff0c;加入一个queue&#xff0c;最后执行 4.NodeCanvas的参数传参可以由上个节点传到下个节…...

(* IOB = “FORCE“ *) 的使用分享

在Xilinx FPGA设计中&#xff0c;IOBFORCE是一个与输入输出块&#xff08;IOB&#xff09;相关的属性设置。这个设置主要用于控制逻辑是否被推入到IOB&#xff08;Input/Output Block&#xff09;中&#xff0c;即FPGA芯片边缘的I/O引脚附近的专用硬件资源。使用IOB属性可以帮助…...

【大语言模型_7】利用ragas框架评测rag系统指标

一、介绍 ragas是一个用来评估RAG系统的框架&#xff0c;允许不在依赖人工注释的情况下&#xff0c;通过一套指标评估检索模块和生成模块的性能及其质量。 二、准备 数据准备&#xff1a;需要准备评估数据集&#xff0c;数据集格式如下 [{"question": "安全智…...

adb常用的命令

1. 查看adb版本 adb version 2. 将apk安装包安装到手机/模拟器上 adb install apk路径 3. 获取apk包名和界面名 包名&#xff08;package&#xff09;&#xff1a;决定程序的唯一性 界面名&#xff08;activity&#xff09;&#xff1a;一个界面界面名&#xff0c;对应一个界面…...

手动集成sqlite的方法

注意到sqlite有backup方法&#xff08;https://www.sqlite.org/backup.html&#xff09;。 也注意到android中sysroot下&#xff0c;没有sqlite3的库&#xff0c;也没有相关头文件。 如果要使用 sqlite 的backup&#xff0c;那么就需要手动集成sqlite代码到项目中。可以如下操…...

自然语言处理(NLP)技术

人工智能&#xff08;Artificial Intelligence&#xff0c;AI&#xff09;是一种模拟人类智能思维过程的技术&#xff0c;它在现代科技中的应用非常广泛&#xff0c;涉及诸多领域&#xff0c;如自然语言处理、计算机视觉、机器学习、数据分析等。以下是人工智能在现代科技中的应…...

【GPT入门】第25课 掌握 LangChain:链式调用的奥秘、特性与使用示例

【GPT入门】第25课 掌握 LangChain&#xff1a;链式调用的奥秘、特性与使用示例 语法解释各部分性质链式调用的性质调用方式注意事项 语法解释 你给出的代码 is_duplicated_chain (check_duplicated | model | parser) 运用了 LangChain 里的链式调用语法。在 LangChain 中&a…...

机器学习之DBSCAN算法详解

文章目录 引言1. DBSCAN算法概述2.DBSCAN算法的基本概念2.1 ε-邻域2.2 核心点&#xff08;Core Point&#xff09;2.3 边界点&#xff08;Border Point&#xff09;2.4 噪声点&#xff08;Noise Point&#xff09;2.5 直接密度可达&#xff08;Directly Density-Reachable&…...

借助vite来优化前端性能

Vite 是一个现代化的前端构建工具&#xff0c;凭借其基于原生 ES 模块的开发服务器和高效的构建能力&#xff0c;可以显著优化前端性能。 一、开发环境优化 1.快速启动与热更新 Vite 利用浏览器对 ES 模块的原生支持&#xff0c;在开发环境中无需打包&#xff0c;直接按需加载…...

[工控机安全] 使用DriverView快速排查不可信第三方驱动(附详细图文教程)

导语&#xff1a; 在工业控制领域&#xff0c;设备驱动程序的安全性至关重要。第三方驱动可能存在兼容性问题、安全漏洞甚至恶意代码&#xff0c;威胁设备稳定运行。本文将手把手教你使用 DriverView工具&#xff0c;高效完成工控机驱动安全检查&#xff0c;精准识别可疑驱动&a…...

Execution failed for task ‘:path_provider_android:compileDebugJavaWithJavac‘.

What went wrong: Execution failed for task ‘:path_provider_android:compileDebugJavaWithJavac’. Could not resolve all files for configuration ‘:path_provider_android:androidJdkImage’. Failed to transform core-for-system-modules.jar to match attributes {…...

基于SpringBoot的社区/物业管理系统

项目介绍 平台采用B/S结构&#xff0c;后端采用主流的SpringBoot语言进行开发&#xff0c;前端采用主流的Vue.js进行开发。是一个综合的社区/物业管理系统。 整个平台包括前台和后台两个部分。 - 前台功能包括&#xff1a;小区信息、社区论坛、社区公告、社区留言板、个人中心。…...

vmware下linux无法上网解决方法

首先&#xff0c;打开打开"编辑" “虚拟网络编辑器”,并将"桥接"方式的网卡选择为主机上网的网卡。 虚拟机中&#xff0c;设置IP地址为主机网卡同样子网下的ip地址&#xff1a; 并且要选择桥接模式&#xff01;注意如下图&#xff0c;"复制物理连接状…...

【数据库备份】docker中数据库备份脚本——MySql备份脚本

docker中数据库备份脚本——MySql备份脚本 #!/bin/bash# MySQL数据库信息 DB_USER"root" DB_PASSWORD"你的密码"# 备份保存主目录 BACKUP_ROOT"/data/data_backup/mysql"# 最多保留的备份日期文件夹数 MAX_DATE_FOLDERS15# 数组包含要备份的数据…...

SpringBoot 第二课(Ⅰ) 整合springmvc(详解)

目录 一、SpringBoot对静态资源的映射规则 1. WebJars 资源访问 2. 静态资源访问 3. 欢迎页配置 二、SpringBoot整合springmvc 概述 Spring MVC组件的自动配置 中央转发器&#xff08;DispatcherServlet&#xff09; 控制器&#xff08;Controller&#xff09; 视图解…...

centos家用笔记

改用阿里云yum源 因CentOS7已经停止维护&#xff0c;原有的yum源也无法使用&#xff0c;在国内&#xff0c;改用阿里云yum源是个方便的选择。 cd /etc/yum.repos.d/ mkdir backup mv Cent* backup wget http://mirrors.aliyun.com/repo/Centos-7.repo mv Centos-7.repo Cen…...

数据可视化(matplotlib)-------辅助图标的设置

目录 一、认识图表常用的辅助元素 坐标轴 二、设置坐标轴的标签、刻度范围和刻度标签 &#xff08;一&#xff09;、设置坐标轴的标签 1、xlabel()------设置x轴标签 2、ylabel()------设置y轴标签 &#xff08;二) 、设置刻度范围和刻度标签 1、xlim()和ylim()函数分别可…...

15-双链表-双链表基本操作

题目 来源 827. 双链表 - AcWing题库 思路 此题我只想说&#xff0c;千万千万别漏了头结点和尾结点&#xff0c;不然根本查不出来是哪里出了问题&#xff0c;因为传入的k会有问题&#xff1b;最左边插入&#xff0c;相当于是在头结点的右边插入&#xff08;也就是0号节点的右…...

HTTP和RPC的区别

RPC和 HTTP是两种常见的通信方式&#xff0c;它们在设计目标、使用场景和技术实现上有显著区别。以下是它们的详细对比&#xff1a; 1. 定义与核心思想 特性RPCHTTPRemote Procedure Call远程过程调用HyperText Transfer Protocol超文本传输协议定义一种协议或框架&#xff0…...

【Linux内核系列】:动静态库详解

&#x1f525; 本文专栏&#xff1a;Linux &#x1f338;作者主页&#xff1a;努力努力再努力wz &#x1f4aa; 今日博客励志语录&#xff1a; 有些鸟儿是注定是关不住的&#xff0c;因为它们的每一片羽翼都沾满了自由的光辉 ★★★ 本文前置知识&#xff1a; 编译与链接的过程…...

【IROS 2025】CMU提出路径规划器PIPE:机器人探索效率提升14.6%,地图准确率提高9.3%!

在自主机器人探索未知环境的研究中&#xff0c;如何高效地规划路径、最大化信息获取&#xff0c;一直是一个核心问题。传统的方法往往仅在离散的路径点上计算信息增益&#xff0c;而缺乏对整个路径信息获取的综合考量&#xff0c;从而可能导致探索低效甚至错误的规划决策。近日…...

《笔记》Android 获取第三方应用及查看应用信息、apk大小、缓存、存储,以及第三方清除缓存

获取应用相关信息&#xff1a; PS:manifest标签中设置以下属性表示系统应用 android:process"system" android:sharedUserId"android.uid.system" //获取所有应用&#xff08;非系统apk&#xff0c;有些应用获取不到&#xff09; List<ApplicationInf…...

npm 安装 pnpm 的详细步骤及注意事项

一、安装步骤 1.全局安装 pnpm npm install -g pnpm2.验证安装 pnpm -v输出版本号即表示安装成功。 二、升级 pnpm 若已安装旧版本&#xff0c;可通过以下命令升级&#xff1a; npm install -g pnpmlatest三、配置镜像加速 设置淘宝镜像 pnpm config set registry http…...

大白话详细解读React框架的diffing算法

1. Diffing 算法是什么&#xff1f; Diffing 算法是 React 用来比较虚拟 DOM&#xff08;Virtual DOM&#xff09;树的一种算法。它的作用是找出前后两次渲染之间的差异&#xff08;diff&#xff09;&#xff0c;然后只更新这些差异部分&#xff0c;而不是重新渲染整个页面。 …...

【架构】单体架构 vs 微服务架构:如何选择最适合你的技术方案?

文章目录 ⭐前言⭐一、架构设计的本质差异&#x1f31f;1、代码与数据结构的对比&#x1f31f;2、技术栈的灵活性 ⭐二、开发与维护的成本博弈&#x1f31f;1、开发效率的阶段性差异&#x1f31f;2、维护成本的隐形陷阱 ⭐三、部署与扩展的实战策略&#x1f31f;1、部署模式的本…...

面试redis常被问到的面试题含答案

什么是Redis&#xff1f;它的特点是什么&#xff1f; Redis是一个开源的内存数据库&#xff0c;用于存储数据并支持多种数据结构&#xff08;如字符串、哈希、列表、集合、有序集合等&#xff09;。其特点包括高性能、支持持久化、数据结构丰富、原子性操作、支持事务等。 Red…...

Asp.net Core API 本地化

本文是一个demo&#xff0c;演示了如何根据用户接口查询字段(正常放header中),设置当前culture&#xff0c;并获取当前culture的key value给用户提示 创建Resources文件夹&#xff0c;添加以下三个文件 其中ExceptionUnuse 是一个空的类&#xff0c;供IStringLocalizer使用&a…...

使用Java实现Oracle表结构转换为PostgreSQL的示例方案(AI)

核心代码 import java.sql.*; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map;public class OracleToPGConverter {// 类型映射表private static final Map<String, String> TYPE_MAPPING new HashMap<>()…...

win32汇编环境,网络编程入门之八

;在上一教程里&#xff0c;我们学习了简单的处理服务器返回的数据 ;在这一教程里&#xff0c;我们了解一下&#xff0c;当连接上网站后&#xff0c;应该发送什么数据过去的问题 ;这里有个简单的方式学习&#xff0c;以下是一个示例 ;我们上网的时候可以用谷歌浏览器&#xff0c…...

Java EE 进阶:MyBatis

MyBatis是一个优秀的持久化框架&#xff0c;用于简化JDBC的开发。 持久层就是持久化访问的层&#xff0c;就是数据访问层&#xff08;Dao&#xff09;&#xff0c;用于访问数据库的。 MyBatis使用的准备工作 创建项目&#xff0c;导入mybatis的启动依赖&#xff0c;mysql的驱…...

Linux驱动开发基础(can)

目录 1.can的介绍 2.can的硬件连接 2.1 CPU自带can控制器 2.2 CPU没有can控制器 3.电气属性 4.can的特点 5.can协议 5.1 can的种类 5.2 数据帧 5.2.1 标准数据帧格式 5.3.1 扩展数据帧格式 5.3 遥控帧 5.4 错误帧 5.5 过载帧 5.6 帧间隔 5.7 位填充 5.8 位时…...

Linux 命令行整理(完善中)

文件类 查看文件类 cat 用于连接文件并打印到标准输出设备上&#xff0c;可用于查看文件内容.(短文件) use:cat example.txtmore 分页的形式显示文件内容&#xff0c;适合查看较长的文件&#xff08;长&#xff09; use: more example.txtless 也是分页查看文件内容&#xff…...

回调方法传值汇总

<template v-slot"scope"><el-switch v-model"scope.row.open" change"(p1) > changeOpen(p1, scope.row)"></el-switch></template>公域流量 多选 selection-change“val > multipleSelection val”...

分享一个精灵图生成和拆分的实现

概述 精灵图&#xff08;Sprite&#xff09;是一种将多个小图像合并到单个图像文件中的技术&#xff0c;广泛应用于网页开发、游戏开发和UI设计中。在MapboxGL中&#xff0c;跟之配套的还有一个json文件用来记录图标的大小和位置。本文分享基于Node和sharp库实现精灵图的合并与…...

python中的min函数的key的用法 - abs绝对值

前言 继续上一章节提及的 Python 中 min() 函数的用法&#xff0c;包括其基本语法、处理列表、接收多个参数 这个章节将补充一些新的知识点例如: min函数中key的另一种用法abs绝对值 min(iterable, *iterables, keyNone, defaultNone) 知识点 key 参数 key 是一个可选参数…...

我开发的PDF转WORD免费工具

ZhouShengHuan 欢迎小伙伴使用&#xff5e;...

kubernetes高级实战

一、模拟企业环境进行一个实战部署 [rootmaster node]# kubectl apply -f pod-tomcat.yaml pod/tomcat-test created [rootmaster node]# kubectl get pods NAME READY STATUS RESTARTS AGE tomcat-test 2/2 Running 0 2s [rootmaster node]…...

IntelliJ 配置文件plugin.xml

在 IntelliJ IDEA 插件开发中&#xff0c;plugin.xml 是插件的配置文件&#xff0c;它包含了关于插件的所有基本信息、扩展点、依赖关系等。该文件使用 XML 格式进行定义。以下是 plugin.xml 中常见的元素及其用途&#xff1a; <idea-plugin><!-- 插件的基本信息 --&…...

《心理学与生活》2025最新网课答案

《心理学与生活》2025最新网课答案 文章目录 《心理学与生活》2025最新网课答案发展与教育单元测试情绪与情感单元测验人格与动机单元测试感知与记忆单元测试文化与社会单元测试 发展与教育单元测试 题数 20 棉花糖实验中哪些小孩长大后的表现更好&#xff08;&#xff09;。 …...

11 python 数据容器-字符串

一、什么是数据容器 举个例子&#xff0c;一个办公室里有一群牛马&#xff0c;他们都有自己的名字&#xff0c;如果没有容器的概念&#xff0c;那么我们用变量来存放他们的名字&#xff0c;比如&#xff1a; name1 "翠花" name2 "玛丽" name3 "二…...