Pyhton学习笔记一(数据分析)

笔记本安装Linux+Windows10双系统

Python爬虫+数据分析

使用环境:

PyCharm

Windows 10 HOME x64

Python基础

Python 是一门解释型, 面向对象的高级编程语言

开源, 支持交互式, 可跨平台移植的脚本语言

1991年第一个编译器诞生

使用Python3.5以上

PyCharm

基础语法

注释

# 内容代表注释

多行注释:

1
2
3
4
5
'''

Multiple Line comments

'''

变量

不可以用数字开头

标识符和关键字

  • 什么是关键字

    python一些具有特殊功能的标示符,这就是所谓的关键字
    关键字,是python已经使用的了,所以不允许开发者自己定义和关键字相同的名字的标示符

  • 查看关键字

    1
    2
    >>> import keyword
    >>> keyword.kwlist

输出

1
print('hello world')

格式化输出

标准输出:

1
2
pirnt("我今年10岁")
pirnt("我今年11岁")

格式化输出:

1
2
3
4
5
6
7
age = 10
print("我今年%d岁"%age)
age += 1
print("我今年%d岁"%age)
age = 18
name = "xiaohua"
print("我的姓名是%s,年龄是%d"%(name,age))

%就是代表格式化操作符,可以在字符串中相当于占位符,之后再赋值

%d代表digital,有符号的十进制整数

%s代表字符串, 使用str()

还有很多格式化占位符, 具体可以参考官方文档

输出中也可以插入分隔符

1
print("hello", "world", "end" sep=".")

输入

1
2
password = input("please enter your password")
print("Your just entered:" , password)

判断和循环

判断语句

标准语法:

1
2
3
4
5
6
if: 
...
elif:
...
else:
...

逻辑字符

andor

1
if score > 90 and score < 100
1
if score == 90 or score == 80

循环语句

while循环基本语法

1
2
3
4
5
i = 0
while i<5:
print("当前是第%d次执行循环"%(i+1))
print("i=%d"%i)
i+=1

for循环基础语法

1
2
3
for 临时变量 in 列表或者字符串等:
...
循环满足条件时执行的代码
1
2
3
name = 'chengdu'
for x in name:
print(x)
1
for i in range(0,100,10)

break, continue, pass

  • break 可以跳出循环
  • continue跳过当前循环
  • pass是空语句, 一般用作占用语句, 不做任何是事情

字符串

\代表转义字符

1
2
3
print("...'...")
my_str = 'I\'m a student'
print(my_str)

三个双引号可以输入段落

1
2
3
4
5
6
7
8
"""

this
is
a
paragraph

"""

字符串的截取和连接

1
2
3
4
5
6
7
8
9
10
11
12
13
str='chengdu'
print(str) # 输出字符串
print(str[0:-1]) # 输出第一个到倒数第二个的所有字符
print(str[0]) # 输出字符串第一个字符
print(str[2:5]) # 输出从第三个开始到第五个的字符
print(str[2:]) # 输出从第三个开始后的所有字符
print(str * 2) # 输出字符串两次
print(str + '你好') # 连接字符串
print(str[:5]) # 输出第五个字母前的所有字符
print(str[0:7:2]) # [起始:终止:步长]
print('------------------------------')
print('hello\nchengdu') # 使用反斜杠(\)+n转义特殊字符
print(r'hello\npython') # 在字符串前面添加一个 r,表示原始字符串,不会发生转义

字符串有很多常用方法, 具体参考官方文档

列表

类似其他语言的数组

格式:

1
2
namesList = ['xiaoWang','xiaoZhang','xiaoHua']
testList = [1, 'a']

打印列表:

1
2
3
4
namesList = ['xiaoWang','xiaoZhang','xiaoHua']
print(namesList[0])
print(namesList[1])
print(namesList[2])

常用列表操作

  • append()
  • list[2:2:2]
  • insert(1, 3)
  • pop()
  • sort()
  • reverse()

元组

元组类似列表

但是元组不能修改

1
tup1 = () # 空元组
1
2
3
4
5
tup1 = (50) # 不加逗号,类型为整型
print(type(tup1)) #输出<class 'int'>

tup1 = (50,) # 加逗号,类型为元组
print(type(tup1)) #输出<class 'tuple'>
1
2
3
4
tup1 = ('Google', 'baidu', 2000, 2020)
tup2 = (1, 2, 3, 4, 5, 6, 7 )
print ("tup1[0]: ", tup1[0])
print ("tup2[1:5]: ", tup2[1:5])

元组中的元素值是不允许修改的,但我们可以对元组进行连接组合

1
2
3
4
5
6
7
tup1 = (12, 34.56)
tup2 = ('abc', 'xyz')
# 以下修改元组元素操作是非法的。
# tup1[0] = 100
# 创建一个新的元组
tup3 = tup1 + tup2
print (tup3)
  • 删除元组后,再次访问会报错
1
2
3
4
5
tup = ('Google', 'baidu', 2000, 2020)
print (tup)
del tup
print ("删除后的元组 tup : ")
print (tup)

字典

  • 变量info为字典类型:
1
info = {'name':'班长', 'id':100, 'sex':'f', 'address':'地球亚洲中国北京'}
  • 访问值
1
2
3
4
info = {'name':'吴彦祖','age':18}
print(info['age']) # 获取年龄
# print(info['sex']) # 获取不存在的key,会发生异常
print(info.get('sex')) # 获取不存在的key,获取到空的内容,不会出现异常
  • 还可以设置默认值:
1
2
3
>>> age = info.get('age', 18) # 若info中不存在'age'这个键,就返回默认值18
>>> age
18

增删改查方法

  • add()
  • update()
  • remove()
  • get()
  • keys()
  • values()
  • items() —每个键值对是一个元组

for遍历所有键值对

1
2
for key, value in info.items():
print("key=%s, value=%s"%(key, value))

使用枚举

同时拿到下标和元素内容

1
2
3
myList = ["a","b","c","d"]
for i,x in enumerate(myList):
print(i,x)

集合

Set, 类似字典的key值, 不可重复, 无序的

一样拥有差不多的增删改查方法

函数

可以自定义返回值, 和返回值的数量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 打印一条线
def print_line():
print("-----------")

# 打印指定数量的线
def print_lines(num):
for i in range(0,num):
print_line()

# 返回三个数的和
def three_num_sum(a,b,c):
return a+b+c

# 返回三个数的平均值
def three_num_avg(a,b,c):
return (three_num_sum(a,b,c))/3

全局变量和局部变量

可以用global 修饰符, 声明全局变量

1
2
global a
a = 100

文件操作

文件的打开和关闭

1
2
f = open("test.txt","w")  #w 代表访问符(读写)
f.close()

写入数据

1
2
f.write('hello,world')

读取数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
f.read()
print(content)
print("-"*30)
content = f.read()
print(content)

# 或者整行一起读
content = f.readlines()
print(type(content))
i=1
for temp in content:
print("%d:%s"%(i, temp))
i+=1


content = f.readline()
print("1:%s"%content)
content = f.readline()
print("2:%s"%content)

文件相关操作

  • 重命名
1
2
import os
os.rename("毕业论文.txt", "毕业论文-最终版.txt")
  • 删除
1
2
import os
os.remove("毕业论文.txt")
  • 创建文件夹
1
2
import os
os.mkdir("张三")
  • 获取当前目录
1
2
import os
os.getcwd()
  • 改变默认目录
1
2
import os
os.chdir("../")
  • 获取目录列表
1
2
import os
os.listdir("./")
  • 删除文件夹
1
2
import os
os.rmdir("张三")

异常处理

捕获异常

1
2
3
4
5
6
try:
print('-----test--1---')
open('123.txt','r')
print('-----test--2---')
except IOError:
pass

捕获多个异常

1
2
3
4
5
6
7
8
9
#coding=utf-8
try:
print('-----test--1---')
open('123.txt','r') # 如果123.txt文件不存在,那么会产生 IOError 异常
print('-----test--2---')
print(num)# 如果num变量没有定义,那么会产生 NameError 异常

except (IOError,NameError):
#如果想通过一次except捕获到多个异常可以用一个元组的方式

捕获所有异常

1
2
3
4
try: 
...
except (IOError,NameError):
...

try…finally…

demo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import time
try:
f = open('test.txt')
try:
while True:
content = f.readline()
if len(content) == 0:
break
time.sleep(2)
print(content)
except:
#如果在读取文件的过程中,产生了异常,那么就会捕获到
#比如 按下了 ctrl+c
pass
finally:
f.close()
print('关闭文件')
except:
print("没有这个文件")

test.txt文件中每一行数据打印,但是我有意在每打印一行之前用time.sleep方法暂停2秒钟。这样
做的原因是让程序运行得慢一些。在程序运行的时候,按Ctrl+c中断(取消)程序。
我们可以观察到KeyboardInterrupt异常被触发,程序退出。但是在程序退出之前,finally从句仍
然被执行,把文件关闭。

网络爬虫

正片开始^^

任务

实现案例, 爬取豆瓣电影Top250的基本信息, 包括电影名称, 评分, 评价数量, 电影概况, 电影链接等等

豆瓣Top250电影榜单

基础爬虫知识

  • 爬虫就是按照一定规则, 自动抓取互联网程序或者脚本
  • 可以爬取图片, 视频, 能通过浏览器访问的数据都可以用爬虫获取
  • 爬虫的本质就是模拟浏览器打开网页, 获取我们需要的数据

流程

需要HTML、CSS、JS的基础知识

  • 爬取网页
  • 解析数据
  • 保存数据

引入模块

1
2
3
4
5
6
# 引入自定义模块
from directory import t1
# 引入官方模块
import os
# 引入第三方模块
import bs4

此案例需要的模块

1
2
3
4
5
import bs4          #网页解析
import re #正则表达式
import urllib.request,urllib.error #指定URL 获取网页数据
import xlwt #进行excel操作
import sqlite3 #数据库

程序框架准备

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
def main():
baseurl = "https://movie.douban.com/top250?start="
# 爬取网页
# 解析数据
datalist = getData(baseurl)
savepath = ".\\豆瓣电影Top250.xls"

# 保存数据
saveData(savepath)


def getData(baseurl):
datalist = []
# 解析数据
return datalist


def saveData(savepath):
# 保存数据
print("...")


if __name__ == '__main__':
# 程序执行时 调用函数
main()

urllib库附加内容

get请求

1
2
3
4
import urllib.request
# 获取get请求
response = urllib.request.urlopen("http://www.baidu.com")
print(response.read().decode('utf-8'))

post请求

http://httpbin.org/是一个测试http的网站

1
2
3
4
import urllib.parse
data = bytes(urllib.parse.urlencode({"hello":"world"}),encoding = "utf-8")
response = urllib.request.urlopen("http://httpbin.org/post", data)
print(response.read().decode('utf-8'))

可以对请求加上超时时间

1
2
3
4
5
try: 
response = urllib.request.urlopen("http://httpbin.org/get", timeout = 0.01)
print(response.read().decode('utf-8'))
except urllib.error.URLError as e:
print("time out!!")

response 里面还包含很多信息

  • getheader()

修改请求头

1
2
3
4
5
6
7
8
9
10
url = "http://httpbin.org/post"
data = bytes(urllib.parse.urlencode({'name':'eric'}),encoding = "utf-8")

headers = {
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36"
}
req = urllib.request.Request(url=url, data=data, headers=headers, method="POST")

response = urllib.request.urlopen(req)
print(response.read().decode("utf-8"))
试着访问豆瓣
1
2
3
4
5
6
7
url = "http://www.douban.com"
headers = {
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36"
}
req = urllib.request.Request(url=url, headers=headers)
response = urllib.request.urlopen(req)
print(response.read().decode("utf-8"))

获取数据

对网页进行访问并获取页面信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 得到指定url的网页内容
def askURL(url):
headers = { # 模拟头部信息
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36"
}
# 用户代理

req = urllib.request.Request(url=url, headers=headers)
html = ""
try:
response = urllib.request.urlopen(req)
html = response.read().decode('utf-8')
except urllib.error.URLError as e:
if hasattr(e,"code"):
print(e.code)
if hasattr(e, "reason"):
print(e.reason)

return html

用for循环分别获取10页信息

1
2
3
4
5
baseurl = "https://movie.douban.com/top250?start="
...
for i in range(0, 10): # 调用获取页面的信息函数, 共10次
url = baseurl + str(i*25)
html = askURL(url)

Beautiful Soup 补充内容

Beautiful Soup 4 将复杂的文档转换成树形结构, 每个节点都是python对象, 所有对象可以归纳为一下四种:
  • Tag - 标签
  • NavigableString - 标签里的内容
  • BeautifulSoup - 整个文档
  • Comment - 注释
1
2
3
4
5
6
7
print(bs.title)
print(bs.a)
print(bs.title.string)
print(bs.a.attrs)

print(bs.name)
print(bs.a.string) # 不包含注释的标签符号

文档遍历

1
print(bs.head.contents[1])

文档搜索

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 字符串过滤, 查找与字符串完全匹配的内容
t_list = bs.findAll("a")

# 正则表达式 使用search()
t_list = bs.findAll(re.compile("a"))

# 函数
def name_is_exists(tag):
return tag.has_attr("name")

t_list = bs.find_all(name_is_exists)

# 参数
t_list = bs.find_all(id="head")
t_list = bs.find_all(class_=True)

# 文本参数
t_list = bs.find_all(text = "hao123")

# limit 参数
t_list = bs.find_all("a",limit=3)
css选择器
1
2
3
4
5
6
7
8
9
10
# css 选择器
t_list = bs.select('title')

t_list = bs.select('#head')

t_list = bs.select("a[class='bri']")

t_list = bs.select("head > title")

t_list = bs.select(".mnav ~ .bri")

re正则表达式补充

操作符 说明
. 表示任何单个字符
[] 字符集, 对单个字符给出取值范围
[^ ] 排除范围
* 0或者多个
+ 1个或者多个
? 0或者1
| 左右表达式任意一个
{m} 表示m次
{m,n} m到n次
^ 开头
$ 结尾
() 分组
\d 数字
\w 字符, 数字和字母

贪婪匹配
默认情况下,正则表达式使用最长匹配原则(也叫贪婪匹配原则)。
例如:要将”zoom”中匹配”zo?”的部 分替换成”r”,替换的的结果是”rom”。如果要将”zoom”中匹配”zo*” 的部分替换成”r”,替换后的结果是”rm”。

非贪婪匹配
当字符?紧随其他限定符(*、+、?、{n}、{n,}、{n,m})之后时,匹配模式变成了最短匹配原则(也 叫非贪婪匹配原则)。
例如:在字符串”fooood”中,”fo+?”只匹配”fo”部分,而”fo+”匹配”foooo部分。

正则表达式语法

re库

  • search
  • match()
  • findall()
  • split()
  • finditer()
  • sub()

还有一些修饰符

  • re.l
  • re.L
  • re.M
  • re.S
  • re.U
  • re.X

使用

1
2
pat = re.compile("AA") # AA是正则表达式
m = pat.search("CAAA") # 被校验的内容
1
print(re.findall("a","ASDaDFGAa"))

用第二个参数替换第一个参数

1
print(re.sub("a","A","abcdaaacga"))

正则表达式提取

提取链接

1
2
3
findLink = re.compile(r'<a href="(.*?)">')    # 创建正则表达式对象, 表示规则(字符串模式), 非贪婪模式
link = re.findall(findLink, item)[0]
data.append(link)

用类似逻辑提取所有需要的元素

对应正则:
1
2
3
4
5
6
7
findLink = re.compile(r'<a href="(.*?)">')  # 创建正则表达式对象, 表示规则(字符串模式), 非贪婪模式
findImgSrc = re.compile(r'<img alt=".*src="(.*?)"', re.S) # re.S 让换行符包含再字符中
findTitle = re.compile(r'<span class="title">(.*?)</span>')
findRating = re.compile(r'<span class="rating_num" property="v:average">(.*?)</span>')
findJudge = re.compile(r'<span>(\d*)人评价</span>')
findInq = re.compile(r'<span class="inq">(.*?)</span>')
findBd = re.compile(r'<p class="">(.*?)</p>', re.S)
提取:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
for item in soup.find_all('div', class_="item"):  # 查找符合要求的字符串, 形成列表
# 拿到了class属性为item的内容
# print(item)
data = [] # 一部电影的所有信息
item = str(item)

# 找链接
data.append(findElement(findLink, item))
data.append(findElement(findImgSrc, item))

titles = re.findall(findTitle, item)
if(len(titles)==2):
ctitle = titles[0]
data.append(ctitle)
otitle = titles[1].replace("/", "")
data.append(otitle)
else:
data.append(titles[0])
data.append(' ')
data.append(findElement(findRating, item))
data.append(findElement(findJudge, item))
inq = re.findall(findInq, item)
if(len(inq) != 0):
inq = inq[0].replace("。", "")
data.append(inq)
else:
data.append(" ")
bd = findElement(findBd, item)
bd = re.sub('<br(\s+)?/>(\s+)?', " ", bd) # 去掉<br/>
bd = re.sub('/', " ", bd) # 替换/
data.append(bd.strip()) # 去掉前后空格


datalist.append(data)

保存到Excel表格

使用xlwt库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def saveData(datalist,savepath):
# 保存数据
book = xlwt.Workbook(encoding='utf-8')
sheet = book.add_sheet('豆瓣电影Top250',cell_overwrite_ok=True)
col = ("电影详情链接", "图片链接","影片中文名","影片外文名","评分","评价数","概况","相关信息")
for i in range(0,8):
sheet.write(0,i,col[i])
for i in range(0,250):
print("第%d条"%(i+1))
data = datalist[i]
for j in range(0,8):
sheet.write(i+1,j,data[j])

book.save(savepath)
print("End")

到此为止, excel表格的保存方式结束

SQLite补充

建表非常简单:

1
2
3
4
5
import sqlite3

conn = sqlite3.connect("test.db")
print("Opened database successfully")
c = conn.cursor()

建表语句

1
2
3
4
5
6
7
8
9
10
11
12
sql = '''
create table company
(id int primary key not null,
name text not null,
age int not null,
address char(50),
salary real);
'''

cursor.execute(sql)
conn.commit()
conn.close()

查询数据

1
2
3
4
5
6
7
8
9
10
11
12
sql = '''
select * from company
'''
c.execute(sql)

for row in c:
print("id = ", row[0])
print("name = ",row[1])
print("address = ",row[2])
print("salary = ",row[3])
conn.close()
print("Create table correctly")

SQLite实践

首先也是建表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def init_db(dbpath):
sql = '''
create table movie250
(
id integer primary key autoincrement,
info_link text,
pic_link text,
cname varchar,
ename varchar,
score numeric,
rated numeric,
introduction text,
info text
)
'''
conn = sqlite3.connect(dbpath)
cursor = conn.cursor()
cursor.execute(sql)
conn.commit()
conn.close()

然后将数据遍历并插入进数据库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def saveData2DB(datalist, dbpath):
conn = sqlite3.connect(dbpath)
cursor = conn.cursor()

for data in datalist:
for index in range(len(data)):
data[index] = '"'+data[index]+'"'
sql = '''
insert into movie250(
info_link, pic_link, cname, ename, score, rated, introduction, info)
values (%s)
'''%",".join(data)
cursor.execute(sql)
conn.commit()
conn.close()

数据可视化

Flask入门

Flask是一个Web框架, Python中最出名的是Django框架, 因为其内容非常全面

Flask的核心是路由转发和页面渲染, Werkzeug和Jinja2

Flask基础

Helloworld

1
2
3
@app.route('/')
def hello_world(): # put application's code here
return 'Hello World!'
1
2
3
@app.route('/user/<name>')
def welcome(name):
return 'Hello World!'+name
1
2
3
@app.route('/user/<int:id>') # 定义整形, 还支持float类型
def welcome2(id):
return 'Hello World!'+ id

使用jinja2渲染并返回文件

1
2
3
4
@app.route("/")
def index():
# 渲染好返回文件
return render_template("index.html")

渲染同时可以传递参数到页面,

1
2
time = datetime.date.today()
return render_template("index.html", var=time)
1
<h1>Welcome {{ var }}</h1>

传递列表参数的时候又特定语法

1
2
3
name = ["校长", "小王", "小赵"]
task = {"任务":"打扫卫生","时间":"3小时"}
return render_template("index.html", var=time, list=name, task=task)

显示列表参数

1
2
3
{% for data in list %}
<li>{{ data }}</li>
{% endfor %}

显示字典参数

1
2
3
4
5
6
7
8
9
任务: <br>
<table>
{% for key, value in task.items() %}
<tr>
<td>{{ key }}</td>
<td>{{ value }}</td>
</tr>
{% endfor %}
</table>

类似还有if语法

处理表单

flask 里面还自带了request

from flask import Flask, render_template, request引入

1
2
3
4
5
6
7
8
9
10
11
12
13
# 表单提交
@app.route("/test/register")
def register():
return render_template("test/register.html")


@app.route("/result", methods=['POST','GET']) # 默认不接受get以外的请求
def result():
if request.method =='POST':
result = request.form
return render_template("test/result.html",result=result)
else:
print("GET")

前端表单页面

1
2
3
4
5
6
7
8
<form action="http://localhost:5000/result" method="post">
<p>姓名: <input type="text" name="name"></p>
<p>年龄: <input type="text" name="age"></p>
<p>性别: <input type="text" name="gender"></p>
<p>地址: <input type="text" name="address"></p>
<p><input type="submit" value="submit"></p>

</form>

注意此处也可以使用{{url_for('result')}}代替来获取根路由的路径

路由通过post请求接受到表单数据以后跳转到result页面 并解析数据

1
2
3
4
5
6
7
8
<table>
{% for key, value in result.items() %}
<tr>
<td>{{ key }}</td>
<td>{{ value }}</td>
</tr>
{% endfor %}
</table>

首页制作 实战

  1. 新创建一个Flask项目
  2. 从模板网站导入一个模板, 并分别放到templates和static文件夹下
  3. 使用render_template设置路由
  4. 对静态html页面进行修改, 改成只留下我们所需要的内容
  5. 修改静态html内的文字内容
  6. 使用类似方式创建movie.html来使数据库中的数据可视化为表格

Movie表格可视化

路由设置, 从数据库中取出数据

1
2
3
4
5
6
7
8
9
10
11
12
13
@app.route('/movie')
def movie_page():
datalist = []
con = sqlite3.connect("movie.db")
cur = con.cursor()
sql = "select * from movie250"
data = cur.execute(sql)
for item in data:
datalist.append(item)
cur.close()
con.close()

return render_template("movie.html", movies=datalist)

然后再前端页面中建一个表格

1
2
3
4
5
6
7
8
9
10
11
12
13
<table class="table table-striped">

<tr>
<th>排名</th>
<th>电影中文名</th>
<th>电影外文名</th>
<th>电影评分</th>
<th>评价人数</th>
<th>一句话概述</th>
<th>其他信息</th>
</tr>

</table>

获取数据显示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{% for movie in movies %}
<tr>
<td>{{ movie[0] }}</td>
<td>
<a href="{{ movie[1] }}">
{{ movie[3] }}
</a>

</td>
<td>{{ movie[4] }}</td>
<td>{{ movie[5] }}</td>
<td>{{ movie[6] }}</td>
<td>{{ movie[7] }}</td>
<td>{{ movie[8] }}</td>
</tr>
{% endfor %}

Echarts应用

官方中文网址: http://www.echartsjs.com/zh/index.html

新版网址: https://echarts.apache.org/

示例:

  1. 引入文件
  2. 从官方网站拷贝提供的示例源码

使用

  1. 新建score.html显示页面,
  2. 编写路由查询处理需要渲染的数据
  3. 前端解析

路由:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@app.route('/score')
def score_page():
score = []
score_count = []
con = sqlite3.connect('movie.db')
cur = con.cursor()
sql = "select score, count(score) from movie250 group by score"
data = cur.execute(sql)
for item in data:
print(item)
score.append(item[0])
score_count.append(item[1])
cur.close()
con.close()

return render_template("score.html", score=score, score_count=score_count)


前端解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<script type="text/javascript">
var dom = document.getElementById("main");
var myChart = echarts.init(dom);
var app = {};
option = null;
option = {
color: ['#3398DB'],
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
grid: {
top: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
data: {{ score }}
},
yAxis: {
type: 'value'
},
series: [{
data: {{ score_count }},
barWidth: '60%',
type: 'bar'

}]
};
;
if (option && typeof option === "object") {
myChart.setOption(option, true);
}
</script>

WordCloud应用

使用中文词云需要使用jieba, matplotlib, wordcloud

wordcloud 安装不成功的话需要到官方网址去: https://www.lfd.uci.edu/~gohlke/pythonlibs/#wordcloud

1
2
3
4
5
6
import jieba                                # 分词
from matplotlib import pyplot as plt # 数据可视化
from wordcloud import WordCloud # 词云
from PIL import Image # 图片处理
import numpy as np # 矩阵运算
import sqlite3 # 数据库
  1. 从数据库中获取
  2. 分词
  3. 设置词云配置
  4. 生成词云
  5. 显示解析词云图片

数据库获取

1
2
3
4
5
6
7
8
9
10
con = sqlite3.connect('../movie.db')
cur = con.cursor()
sql = 'select introduction from movie250'
data = cur.execute(sql)
text = ""
for item in data:
text = text + item[0]
# print(text)
cur.close()
con.close()

分词

1
2
3
4
# 分词
cut = jieba.cut(text)
str = ' '.join(cut)
# print(str)

使用图片轮廓设置词云

1
2
3
4
5
6
7
8
img = Image.open(r'../static/assets/img/tree.jpg')
img_array = np.array(img) # 将u图片转换成数组
wc = WordCloud(
background_color='white',
mask=img_array,
font_path="msyh.ttc" # 字体所在位置: C:\Windows\Fonts

)

生成词云图片

1
2
3
4
5
6
7
wc.generate_from_text(str)

# 绘制图片
fig = plt.figure(1)
plt.imshow(wc)
plt.axis('off')
plt.show()

或者生成图片为文件

1
2
# 输出词云文件到文件
plt.savefig(r'../static/assets/img/word.jpg', dpi=500) # 需要注释掉 plt.show()

将图片放到页面中

直接更改原本模板中word.html中的图片路径即可, 然后删除多余的元素

—End—

Author: klenq
Link: https://klenq.github.io/2021/12/06/Python学习笔记(一·)/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.