跳到主要内容Python 网络爬虫基础:FastAPI 与数据可视化 | 极客日志Python算法
Python 网络爬虫基础:FastAPI 与数据可视化
本文介绍 Python 网络爬虫的基础知识与应用。内容包括基于 FastAPI 搭建 Web 服务器及通用配置,讲解爬虫基本步骤(请求、解析、入库),演示使用 requests 模块爬取图片和 GDP 数据。此外,还涉及多任务爬虫实现以提升效率,利用 pyecharts 进行数据可视化展示,以及 logging 日志模块在 Web 项目中的应用与配置。通过实际代码示例,帮助读者掌握从数据采集到可视化的完整流程。
一、基于 FastAPI 之 Web 站点开发
1. 基于 FastAPI 搭建 Web 服务器
from fastapi import FastAPI
from fastapi import Response
import uvicorn
app = FastAPI()
():
(, ) f:
data = f.read()
Response(content=data, media_type=)
uvicorn.run(app, host=, port=)
@app.get("/index.html")
def
main
with
open
"source/html/index.html"
"rb"
as
return
"text/html"
"127.0.0.1"
8000
2. Web 服务器和浏览器的通讯流程
实际上 Web 服务器和浏览器的通讯流程过程并不是一次性完成的,这里 html 代码中也会有访问服务器的代码,比如请求图片资源。
那像 0.jpg、1.jpg、2.jpg 这些访问来自哪里呢?答:它们来自 index.html。
3. 浏览器访问 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
浏览器 发送的 0.jpg 请求,Web 服务器 可以做出响应,也就是代码如下:
@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. 加载图片资源代码
from fastapi import FastAPI
from fastapi import Response
import uvicorn
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 Response(content=data, media_type="text/html")
uvicorn.run(app, host="127.0.0.1", port=8000)
二、基于 Web 请求的 FastAPI 通用配置
1. 目前 Web 服务器存在问题
@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")
对以上代码观察,会发现每一张图片 0.jpg、1.jpg、2.jpg 就需要一个函数对应,如果我们需要 1000 张图片那就需要 1000 个函数对应,显然这样做代码的重复太多了。
2. 基于 Web 请求的 FastAPI 通用配置
@app.get("/images/{path}")
def get_pic(path: str):
with open(f"source/images/{path}", "rb") as f:
data = f.read()
return Response(content=data, media_type="jpg")
from fastapi import FastAPI
from fastapi import Response
import uvicorn
app = FastAPI()
@app.get("/images/{path}")
def get_pic(path: str):
with open(f"source/images/{path}", "rb") as f:
data = f.read()
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/html")
uvicorn.run(app, host="127.0.0.1", port=8000)
三、Python 爬虫介绍
1. 什么是爬虫
网络爬虫:
又被称为网页蜘蛛,网络机器人,是一种按照一定的规则,自动地抓取网络信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁、自动索引、模拟程序或者蠕虫。
通俗理解:
简单来讲,爬虫就是一个探测机器,它的基本操作就是模拟人的行为去各个网站溜达,点点按钮,查查数据,或者把看到的信息背回来。就像一只虫子在一幢楼里不知疲倦地爬来爬去。
你可以简单地想象:每个爬虫都是你的「分身」。就像孙悟空拔了一撮汗毛,吹出一堆猴子一样。
百度其实就是利用了这种爬虫技术,每天放出无数爬虫到各个网站,把他们的信息抓回来,然后化好淡妆排着小队等你来检索。
有了这样的特性,对于一些自己公司数据量不足的小公司,这个时候还想做数据分析就可以通过爬虫获取同行业的数据然后进行分析,进而指导公司的策略制定。
2. 爬虫的基本步骤
- 起始 URL 地址
- 发出请求获取响应数据
- 对响应数据解析
- 数据入库
3. 安装 requests 模块
import requests
data = requests.get("http://www.baidu.com")
data = data.content.decode("utf-8")
4. 爬取照片
① 查看 index.html
② 爬取照片步骤
- 获取 index.html 代码
- 解析 index.html 代码获取图片 url
- 通过图片 url 获取图片
③ 获取 index.html 代码
data = requests.get("http://127.0.0.1:8000/index.html")
data = data.content.decode("utf-8")
④ 解析 index.html 代码获取图片 url
import re
def get_pic_url():
data = requests.get("http://127.0.0.1:8000/index.html")
data = data.content.decode("utf-8")
data = data.split(" ")
url_list = []
for url in data:
result = re.match('.*src="(.*)" width.*', url)
if result is not None:
url_list.append(result.group(1))
return url_list
⑤ 通过图片 url 获取图片
def save_pic(url_list):
num = 0
for url in url_list:
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 数据
1. gdp.html
2. zip 函数的使用
zip() 函数:用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
a = [1, 2, 3]
b = [4, 5, 6]
c = [4, 5, 6, 7, 8]
zipped = zip(a, b)
print(list(zipped))
zipped = zip(a, c)
print(list(zipped))
3. 爬取 GDP 数据
import requests
import re
country_list = []
gdp_list = []
def get_gdp_data():
global country_list
global gdp_list
data = requests.get("http://localhost:8000/gdp.html")
data = data.content.decode("utf8")
data_list = data.split(" ")
for i in data_list:
country_result = re.match('.*<a><font>(.*)</font></a>', i)
if country_result is not None:
country_list.append(country_result.group(1))
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()
五、多任务爬虫实现
1. 为什么用多任务
在我们的案例中,我们只是爬取了 2 个非常简单的页面,这两个页面的数据爬取并不会使用太多的时间,所以我们也没有太多的考虑效率问题。
但是在真正的工作环境中,我们爬取的数据可能非常的多,如果还是使用单任务实现,这时候就会让我们爬取数据的时间很长,那么显然使用多任务可以大大提升我们爬取数据的效率。
2. 多任务爬取数据
实际上实现多任务并不难,只需要使用多进程就可以了。
3. 多任务代码实现
import multiprocessing
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()
六、数据可视化
1. 什么是数据可视化
数据可视化:顾名思义就是让数据看的到,他的作用也很明显,让人们不用再去阅读枯燥无味的数据,一眼看去就可以明白数据是什么,数据间的关系是什么,更好的让我们通过数据发现潜在的规律进而进行商业决策。
2. pyecharts 模块
概况:
Echarts 是个由百度开源的数据可视化,凭借着良好的交互性,精巧的图表设计,得到了众多开发者的认可。而 Python 是门富有表达力的语言,很适合用于数据处理。当数据分析遇上数据可视化时 pyecharts 诞生了。
- 简洁的 API 设计,使用如丝滑般流畅,支持链式调用
- 囊括了 30+ 种常见图表,应有尽有
- 支持主流 Notebook 环境,JupyterNotebook 和 JupyterLab
- 可轻松集成至 Flask, Django 等主流 Web 框架
- 高度灵活的配置项,可轻松搭配出精美的图表
- 详细的文档和示例,帮助开发者更快的上手项目
- 多达 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":界面的宽度和高度
pie = Pie(init_opts=opts.InitOpts(width="1400px",))
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="美元"))
4. 完整代码
import requests
import re
from pyecharts.charts import Pie
import pyecharts.options as opts
country_list = []
gdp_list = []
def get_gdp_data():
global country_list
global gdp_list
data = requests.get("http://localhost:8000/gdp.html")
data = data.content.decode("utf8")
data_list = data.split(" ")
for i in data_list:
country_result = re.match('.*<a><font>(.*)</font></a>', i)
if country_result is not None:
country_list.append(country_result.group(1))
gdp_result = re.match(".*¥(.*)亿元", i)
if gdp_result is not None:
gdp_list.append(gdp_result.group(1))
def data_view_pie():
data = list(zip(country_list[:10], gdp_list[:10]))
pie = Pie(init_opts=opts.InitOpts(width="1400px",))
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__':
get_gdp_data()
data_view_pie()
5. 小结
- Pie() 函数:创建饼图
- add() 函数:添加数据
- set_global_opts() 函数:设置标题
- render() 函数:保存数据
七、Logging 日志模块
1. logging 日志的介绍
在现实生活中,记录日志非常重要,比如:银行转账时会有转账记录;飞机飞行过程中,会有个黑盒子(飞行数据记录器)记录着飞机的飞行过程,那在咱们 python 程序中想要记录程序在运行时所产生的日志信息,怎么做呢?
- 可以很方便的了解程序的运行情况
- 可以分析用户的操作行为、喜好等信息
- 方便开发人员检查 bug
2. logging 日志级别介绍
- DEBUG
- INFO
- WARNING
- ERROR
- CRITICAL
- DEBUG:程序调试 bug 时使用
- INFO:程序正常运行时使用
- WARNING:程序未按预期运行时使用,但并不是错误,如:用户登录密码错误
- ERROR:程序出错误时使用,如:IO 操作失败
- CRITICAL:特别严重的问题,导致程序不能再继续运行时使用,如:磁盘空间为空,一般很少使用
- 默认的是 WARNING 等级,当在 WARNING 或 WARNING 之上等级的才记录日志信息。
- 日志等级从低到高的顺序是:DEBUG < INFO < WARNING < ERROR < CRITICAL
3. logging 日志的使用
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。
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 项目中应用
- 访问 gdp.html 时进行日志输出,示例代码:
@app.get("/{path}")
def get_html(path: str):
with open(f"source/html/{path}") as f:
data = f.read()
logging.info("访问了" + path)
return Response(content=data, media_type="text/html")
访问 index.html 时进行日志输出,示例代码:
@app.get("/images/{path}")
def get_pic(path: str):
with open(f"source/images/{path}", "rb") as f:
data = f.read()
logging.info("访问了" + path)
return Response(content=data, media_type="jpg")
from fastapi import FastAPI
from fastapi import Response
import uvicorn
import logging
app = FastAPI()
logging.basicConfig(level=logging.INFO,
format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s',
filename="log.txt",
filemode="w")
通过日志信息我们得知,index.html 被访问了 2 次,gdp.html 被访问了 2 次。
- logging 日志配置信息在程序入口模块设置一次,整个程序都可以生效。
- logging.basicConfig 表示 logging 日志配置操作
5. 小结
- 记录 python 程序中日志信息使用 logging 包来完成
- logging 日志等级有 5 个:
- DEBUG
- INFO
- WARNING
- ERROR
- CRITICAL
- 打印 (记录) 日志的函数有 5 个:
- logging.debug 函数,表示:打印 (记录) DEBUG 级别的日志信息
- logging.info 函数,表示:打印 (记录) INFO 级别的日志信息
- logging.warning 函数,表示:打印 (记录) WARNING 级别的日志信息
- logging.error 函数,表示:打印 (记录) ERROR 级别的日志信息
- logging.critical 函数,表示:打印 (记录) CRITICAL 级别的日志信息
微信扫一扫,关注极客日志
微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
相关免费在线工具
- 加密/解密文本
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
- curl 转代码
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
- Markdown 转 HTML
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML 转 Markdown 互为补充。 在线工具,Markdown 转 HTML在线工具,online
- HTML 转 Markdown
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML 转 Markdown在线工具,online