python将爬取的数据并可视化,python数据实时可视化
很多朋友提到python数据可视化,第一反应就是matplotlib库,但实际上python有很多有用的数据可视化的库。下面这篇文章主要介绍如何使用Python捕捉数据并可视化的相关信息。有需要的可以参考一下。
00-1010前言1。数据采集1。防爬措施的简单构造2。数据分析3。完成代码2。数据可视化1。数据可视化数据库的选择2。案例练习(1)。酒吧(2图表(2)。地图地图(3)。饼图(4图表(4)。线(5图表(5)。组合图汇总。
目录
大家好,写这篇文章的目的是为了加深对数据可视化pyecharts的理解,也想分享给大家。以下文章如有错误请指正,哈哈哈!
这次主要用的第三方库:
requestspandaspyecharts
之所以用pyecharts做数据可视化,是因为它有丰富精致的图表和地图,也可以轻松集成到Flask、Django等主流Web框架中,html渲染网页时可以保存图片(这里好像截图就够了,)任君挑选!!!
这个数据集合就是从招聘网站上抓取的python招聘职位信息。良好的.其实抓取的数据有点少(只有1200左右,没办法,位置太少了.),所以会导致后期制作可视化图表时不雅观和吓人。本来我也考虑过用Java(data 10000)的数据来做测试,但是我觉得是用python写的,就只好将就这个数据了。当然,如果你有兴趣,可以用java,这些前端帖子的数据来做测试,稍微改变一下下面提供的数据抓取方法,就可以抓取其他帖子。
好了,事不宜迟,我们开始吧!
前言
一、数据抓取篇
这里有一个简单易用的网站,可以帮助我们在编写爬虫时快速构建请求头和cookie。但是这个网站不知道为什么。反之,在被访问的时候不能频繁访问!嗯.说说它的用途吧!首先,我们只需要按照下图的步骤操作就可以了。
完成后我们会复制请求头中的内容,然后通过Ctrl V打开URL https://curlconverter.com/直接粘贴到输入框中,然后下面会解析内容,我们直接复制完成。又快又简单哈哈哈。
1.简单的构建反爬措施
这里,请求URL得到的数据并不在html元素标签中,所以我们无法使用lxml、css选择器等来解析数据。这里我们使用重正则化来解析数据,得到的数据看起来像字典类型,其实不是,所以还需要json将其转换成字典类型的数据供我们提取。
这里用json转换字典类型数据后,如果不好查看,可以用pprint打印查看。
导入pprint
pprint.pprint(parse_data_dict)
2.解析数据
导入请求
进口re
导入json
导入csv
导入时间
从随机导入随机
从fake_useragent导入用户代理
def spider _ python(key _ word):
标题={
接受“:”文本/htm
l,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9,
Accept-Language: zh-CN,zh;q=0.9,
Cache-Control: no-cache,
Connection: keep-alive,
Pragma: no-cache,
Sec-Fetch-Dest: document,
Sec-Fetch-Mode: navigate,
Sec-Fetch-Site: same-origin,
Sec-Fetch-User: ?1,
Upgrade-Insecure-Requests: 1,
User-Agent: UserAgent().Chrome,
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="100", "Google Chrome";v="100",
sec-ch-ua-mobile: ?0,
sec-ch-ua-platform: "Windows",
}
params = {
lang: c,
postchannel: 0000,
workyear: 99,
cotype: 99,
degreefrom: 99,
jobterm: 99,
companysize: 99,
ord_field: 0,
dibiaoid: 0,
line: ,
welfare: ,
}
save_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()).replace( , _).replace(:,_)
file_path = f./testDataPython-{save_time}.csv
f_csv = open(file_path, mode=w, encoding=utf-8, newline=)
fieldnames = [公司名字, 职位名字, 薪资, 工作地点,
招聘要求, 公司待遇,招聘更新时间, 招聘发布时间,
公司人数, 公司类型, companyind_text, job_href, company_href]
dict_write = csv.DictWriter(f_csv, fieldnames=fieldnames)
dict_write.writeheader()
page = 0 #页数
error_time = 0 #在判断 职位名字中是否没有关键字的次数,这里定义出现200次时,while循环结束
# (因为在搜索岗位名字时(如:搜索python),会在网站20多页时就没有关于python的岗位了,但是仍然有其它的岗位出现,所以这里就需要if判断,使其while循环结束)
flag = True
while flag:
page += 1
print(f第{page}抓取中……)
try:
time.sleep(random()*3) #这里随机休眠一下,简单反爬处理,反正我们用的是单线程爬取,也不差那一点时间是吧
url=这里你们自己构建url吧,从上面的图片应该能看出,我写出来的话实在是不行,过不了审核,难受!!!
###这里还是要添加cookies的好,我们要伪装好不是?防止反爬,如果你用上面提供的方法,也就很快的构建出cookies。
response = requests.get(url=url,params=params, headers=headers)
except:
print(f\033[31m第{page}请求异常!033[0m)
flag = False
parse_data = re.findall("engine_jds":(.*?),"jobid_count",response.text)
parse_data_dict = json.loads(parse_data[0])
# import pprint
# pprint.pprint(parse_data_dict)
# exit()
for i in parse_data_dict:
###在这里要处理下异常,因为在爬取多页时,可能是网站某些原因会导致这里的结构变化
try:
companyind_text = i[companyind_text]
except Exception as e:
print(f\033[31m异常:{e}033[0m)
companyind_text = None
dic = {
公司名字: i[company_name],
职位名字: i[job_name],
薪资: i[providesalary_text],
工作地点: i[workarea_text],
招聘要求: .join(i[attribute_text]),
公司待遇: i[jobwelf],
招聘更新时间: i[updatedate],
招聘发布时间: i[issuedate],
公司人数: i[companysize_text],
公司类型: i[companytype_text],
companyind_text: companyind_text,
job_href: i[job_href],
company_href: i[company_href],
}
if Python in dic[职位名字] or python in dic[职位名字]:
dict_write.writerow(dic)
print(dic[职位名字], ——保存完毕!)
else:
error_time += 1
if error_time == 200:
flag = False
print(抓取完成!)
f_csv.close()
if __name__ == __main__:
key_word = python
# key_word = java ##这里不能输入中文,网址做了url字体加密,简单的方法就是直接从网页url里面复制下来用(如:前端)
# key_word = %25E5%2589%258D%25E7%25AB%25AF #前端
spider_python(key_word)
二、数据可视化篇
1.数据可视化库选用
本次数据可视化选用的是pyecharts第三方库,它制作图表是多么的强大与精美!!!想要对它进行一些简单地了解话可以前往这篇博文:
https://www.jb51.net/article/247122.htm
安装: pip install pyecharts
2.案例实战
本次要对薪资、工作地点、招聘要求里面的经验与学历进行数据处理并可视化。
(1).柱状图Bar
按住鼠标中间滑轮或鼠标左键可进行调控。
import pandas as pdfrom pyecharts import options as opts
python_data = pd.read_csv(./testDataPython-2022-05-01_11_48_36.csv)
python_data[工作地点] = [i.split(-)[0] for i in python_data[工作地点]]
city = python_data[工作地点].value_counts()
###柱状图
from pyecharts.charts import Bar
c = (
Bar()
.add_xaxis(city.index.tolist()) #城市列表数据项
.add_yaxis("Python", city.values.tolist())#城市对应的岗位数量列表数据项
.set_global_opts(
title_opts=opts.TitleOpts(title="Python招聘岗位所在城市分布情况"),
datazoom_opts=[opts.DataZoomOpts(), opts.DataZoomOpts(type_="inside")],
xaxis_opts=opts.AxisOpts(name=城市), # 设置x轴名字属性
yaxis_opts=opts.AxisOpts(name=岗位数量), # 设置y轴名字属性
)
.render("bar_datazoom_both.html")
)
(2).地图Map
省份
这里对所在省份进行可视化。
import pandas as pdimport copy
from pyecharts import options as opts
python_data = pd.read_csv(./testDataPython-2022-05-01_11_48_36.csv)
python_data_deepcopy = copy.deepcopy(python_data) #深复制一份数据
python_data[工作地点] = [i.split(-)[0] for i in python_data[工作地点]]
city = python_data[工作地点].value_counts()
city_list = [list(ct) for ct in city.items()]
def province_city():
这是从接口里爬取的数据(不太准,但是误差也可以忽略不计!)
area_data = {}
with open(./中国省份_城市.txt, mode=r, encoding=utf-8) as f:
for line in f:
line = line.strip().split(_)
area_data[line[0]] = line[1].split(,)
province_data = []
for ct in city_list:
for k, v in area_data.items():
for i in v:
if ct[0] in i:
ct[0] = k
province_data.append(ct)
area_data_deepcopy = copy.deepcopy(area_data)
for k in area_data_deepcopy.keys():
area_data_deepcopy[k] = 0
for i in province_data:
if i[0] in area_data_deepcopy.keys():
area_data_deepcopy[i[0]] = area_data_deepcopy[i[0]] +i[1]
province_data = [[k,v]for k,v in area_data_deepcopy.items()]
best = max(area_data_deepcopy.values())
return province_data,best
province_data,best = province_city()
#地图_中国地图(带省份)Map-VisualMap(连续型)
c2 = (
Map()
.add( "Python",province_data, "china")
.set_global_opts(
title_opts=opts.TitleOpts(title="Python招聘岗位——全国分布情况"),
visualmap_opts=opts.VisualMapOpts(max_=int(best / 2)),
)
.render("map_china.html")
)
这是 中国省份_城市.txt 里面的内容,通过[接口]抓取到的中国地区信息。
源码:
import requestsimport json
header = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36",
}
response = requests.get(https://j.i8tq.com/weather2020/search/city.js,headers=header)
result = json.loads(response.text[len(var city_data =):])
print(result)
each_province_data = {}
f = open(./中国省份_城市.txt,mode=w,encoding=utf-8)
for k,v in result.items():
province = k
if k in [上海, 北京, 天津, 重庆]:
city = ,.join(list(v[k].keys()))
else:
city = ,.join(list(v.keys()))
f.write(f{province}_{city}\n)
each_province_data[province] = city
f.close()
print(each_province_data)
城市
这里对所在城市进行可视化。
import pandas as pdimport copy
from pyecharts import options as opts
python_data = pd.read_csv(./testDataPython-2022-05-01_11_48_36.csv)
python_data_deepcopy = copy.deepcopy(python_data) #深复制一份数据
python_data[工作地点] = [i.split(-)[0] for i in python_data[工作地点]]
city = python_data[工作地点].value_counts()
city_list = [list(ct) for ct in city.items()]
###地图_中国地图(带城市)——Map-VisualMap(分段型)
from pyecharts.charts import Map
c1 = (
Map(init_opts=opts.InitOpts(width="1244px", height="700px",page_title=Map-中国地图(带城市), bg_color="#f4f4f4"))
.add(
"Python",
city_list,
"china-cities", #地图
label_opts=opts.LabelOpts(is_show=False),
)
.set_global_opts(
title_opts=opts.TitleOpts(title="Python招聘岗位——全国分布情况"),
visualmap_opts=opts.VisualMapOpts(max_=city_list[0][1],is_piecewise=True),
)
.render("map_china_cities.html")
)
地区
这里对上海地区可视化。
import pandas as pdimport copy
from pyecharts import options as opts
python_data = pd.read_csv(./testDataPython-2022-05-01_11_48_36.csv)
python_data_deepcopy = copy.deepcopy(python_data) #深复制一份数据
shanghai_data = []
sh = shanghai_data.append
for i in python_data_deepcopy[工作地点]:
if 上海 in i:
if len(i.split(-)) > 1:
sh(i.split(-)[1])
shanghai_data = pd.Series(shanghai_data).value_counts()
shanghai_data_list = [list(sh) for sh in shanghai_data.items()]
#上海地图
c3 = (
Map()
.add("Python", shanghai_data_list, "上海") ###这个可以更改地区(如:成都)这里改了的话,上面的数据处理也要做相应的更改
.set_global_opts(
title_opts=opts.TitleOpts(title="Map-上海地图"),
visualmap_opts=opts.VisualMapOpts(max_=shanghai_data_list[0][1])
)
.render("map_shanghai.html")
)
(3).饼图Pie
Pie1
from pyecharts import options as optsfrom pyecharts.charts import Pie
import pandas as pd
python_data = pd.read_csv(./testDataPython-2022-05-01_11_48_36.csv)
require_list = []
rl = require_list.append
for i in python_data[招聘要求]:
if 经验 in i:
rl(i.split( )[1])
else:
rl(未知)
python_data[招聘要求] = require_list
require = python_data[招聘要求].value_counts()
require_list = [list(ct) for ct in require.items()]
print(require_list)
c = (
Pie()
.add(
"",
require_list,
radius=["40%", "55%"],
label_opts=opts.LabelOpts(
position="outside",
formatter="{a{a}}{abg}\n{hr}\n {b{b}: }{c} {per{d}%} ",
background_color="#eee",
border_color="#aaa",
border_width=1,
border_radius=4,
rich={
"a": {"color": "#999", "lineHeight": 22, "align": "center"},
"abg": {
"backgroundColor": "#e3e3e3",
"width": "100%",
"align": "right",
"height": 22,
"borderRadius": [4, 4, 0, 0],
},
"hr": {
"borderColor": "#aaa",
"width": "100%",
"borderWidth": 0.5,
"height": 0,
},
"b": {"fontSize": 16, "lineHeight": 33},
"per": {
"color": "#eee",
"backgroundColor": "#334455",
"padding": [2, 4],
"borderRadius": 2,
},
},
),
)
.set_global_opts(
title_opts=opts.TitleOpts(title="工作经验要求"),
legend_opts=opts.LegendOpts(padding=20, pos_left=500),
)
.render("pie_rich_label.html")
)
Pie2
from pyecharts import options as optsfrom pyecharts.charts import Pie
import pandas as pd
python_data = pd.read_csv(./testDataPython-2022-05-01_11_48_36.csv)
xueli_list = []
xl = xueli_list.append
for i in python_data[招聘要求]:
if len(i.split( )) == 3:
xl(i.split( )[2])
else:
xl(未知)
python_data[招聘要求] = xueli_list
xueli_require = python_data[招聘要求].value_counts()
xueli_require_list = [list(ct) for ct in xueli_require.items()]
c = (
Pie()
.add(
"",
xueli_require_list,
radius=["30%", "55%"],
rosetype="area",
)
.set_global_opts(title_opts=opts.TitleOpts(title="学历要求"))
.render("pie_rosetype.html")
)
(4).折线图Line
这里对薪资情况进行可视化。
import pandas as pdimport re
python_data = pd.read_csv(./testDataPython-2022-05-01_11_48_36.csv)
sal = python_data[薪资]
xin_zi1 = []
xin_zi2 = []
xin_zi3 = []
xin_zi4 = []
xin_zi5 = []
xin_zi6 = []
for s in sal:
s = str(s)
if 千 in s:
xin_zi1.append(s)
else:
if re.findall(-(.*?)万,s):
s = float(re.findall(-(.*?)万,s)[0])
if 1.0<s<=1.5:
xin_zi2.append(s)
elif 1.5<s<=2.5:
xin_zi3.append(s)
elif 2.5<s<=3.2:
xin_zi4.append(s)
elif 3.2<s<=4.0:
xin_zi5.append(s)
else:
xin_zi6.append(s)
xin_zi = [[<10k,len(xin_zi1)],[10~15k,len(xin_zi2)],[15<25k,len(xin_zi3)],
[25<32k,len(xin_zi4)],[32<40k,len(xin_zi5)],[>40k,len(xin_zi6),]]
import pyecharts.options as opts
from pyecharts.charts import Line
x, y =[i[0] for i in xin_zi],[i[1] for i in xin_zi]
c2 = (
Line()
.add_xaxis(x)
.add_yaxis(
"Python",
y,
markpoint_opts=opts.MarkPointOpts(
data=[opts.MarkPointItem(name="max", coord=[x[2], y[2]], value=y[2])] #name=自定义标记点
),
)
.set_global_opts(title_opts=opts.TitleOpts(title="薪资情况"),
xaxis_opts=opts.AxisOpts(name=薪资范围), # 设置x轴名字属性
yaxis_opts=opts.AxisOpts(name=数量), # 设置y轴名字属性
)
.render("line_markpoint_custom.html")
)
(5).组合图表
最后,将多个html上的图表进行合并成一个html图表。
首先,我们执行下面这串格式的代码(只写了四个图表,自己做相应添加即可)
import pandas as pdfrom pyecharts.charts import Bar,Map,Pie,Line,Page
from pyecharts import options as opts
python_data = pd.read_csv(./testDataPython-2022-05-01_11_48_36.csv)
python_data[工作地点] = [i.split(-)[0] for i in python_data[工作地点]]
city = python_data[工作地点].value_counts()
city_list = [list(ct) for ct in city.items()]
###柱状图
def bar_datazoom_slider() -> Bar:
c = (
Bar()
.add_xaxis(city.index.tolist()) #城市列表数据项
.add_yaxis("Python", city.values.tolist())#城市对应的岗位数量列表数据项
.set_global_opts(
title_opts=opts.TitleOpts(title="Python招聘岗位所在城市分布情况"),
datazoom_opts=[opts.DataZoomOpts(), opts.DataZoomOpts(type_="inside")],
xaxis_opts=opts.AxisOpts(name=城市), # 设置x轴名字属性
yaxis_opts=opts.AxisOpts(name=岗位数量), # 设置y轴名字属性
)
)
return c
# 地图_中国地图(带省份)Map-VisualMap(连续型)
def map_china() -> Map:
import copy
area_data = {}
with open(./中国省份_城市.txt, mode=r, encoding=utf-8) as f:
for line in f:
line = line.strip().split(_)
area_data[line[0]] = line[1].split(,)
province_data = []
for ct in city_list:
for k, v in area_data.items():
for i in v:
if ct[0] in i:
ct[0] = k
province_data.append(ct)
area_data_deepcopy = copy.deepcopy(area_data)
for k in area_data_deepcopy.keys():
area_data_deepcopy[k] = 0
for i in province_data:
if i[0] in area_data_deepcopy.keys():
area_data_deepcopy[i[0]] = area_data_deepcopy[i[0]] + i[1]
province_data = [[k, v] for k, v in area_data_deepcopy.items()]
best = max(area_data_deepcopy.values())
c = (
Map()
.add("Python", province_data, "china")
.set_global_opts(
title_opts=opts.TitleOpts(title="Python招聘岗位——全国分布情况"),
visualmap_opts=opts.VisualMapOpts(max_=int(best / 2)),
)
)
return c
#饼图
def pie_rich_label() -> Pie:
require_list = []
rl = require_list.append
for i in python_data[招聘要求]:
if 经验 in i:
rl(i.split( )[1])
else:
rl(未知)
python_data[招聘要求] = require_list
require = python_data[招聘要求].value_counts()
require_list = [list(ct) for ct in require.items()]
c = (
Pie()
.add(
"",
require_list,
radius=["40%", "55%"],
label_opts=opts.LabelOpts(
position="outside",
formatter="{a{a}}{abg}\n{hr}\n {b{b}: }{c} {per{d}%} ",
background_color="#eee",
border_color="#aaa",
border_width=1,
border_radius=4,
rich={
"a": {"color": "#999", "lineHeight": 22, "align": "center"},
"abg": {
"backgroundColor": "#e3e3e3",
"width": "100%",
"align": "right",
"height": 22,
"borderRadius": [4, 4, 0, 0],
},
"hr": {
"borderColor": "#aaa",
"width": "100%",
"borderWidth": 0.5,
"height": 0,
},
"b": {"fontSize": 16, "lineHeight": 33},
"per": {
"color": "#eee",
"backgroundColor": "#334455",
"padding": [2, 4],
"borderRadius": 2,
},
},
),
)
.set_global_opts(
title_opts=opts.TitleOpts(title="工作经验要求"),
legend_opts=opts.LegendOpts(padding=20, pos_left=500),
)
)
return c
#折线图
def line_markpoint_custom() -> Line:
import re
sal = python_data[薪资]
xin_zi1 = []
xin_zi2 = []
xin_zi3 = []
xin_zi4 = []
xin_zi5 = []
xin_zi6 = []
for s in sal:
s = str(s)
if 千 in s:
xin_zi1.append(s)
else:
if re.findall(-(.*?)万,s):
s = float(re.findall(-(.*?)万,s)[0])
if 1.0<s<=1.5:
xin_zi2.append(s)
elif 1.5<s<=2.5:
xin_zi3.append(s)
elif 2.5<s<=3.2:
xin_zi4.append(s)
elif 3.2<s<=4.0:
xin_zi5.append(s)
else:
xin_zi6.append(s)
xin_zi = [[<10k,len(xin_zi1)],[10~15k,len(xin_zi2)],[15<25k,len(xin_zi3)],
[25<32k,len(xin_zi4)],[32<40k,len(xin_zi5)],[>40k,len(xin_zi6),]]
x, y =[i[0] for i in xin_zi],[i[1] for i in xin_zi]
c = (
Line()
.add_xaxis(x)
.add_yaxis(
"Python",
y,
markpoint_opts=opts.MarkPointOpts(
data=[opts.MarkPointItem(name="MAX", coord=[x[2], y[2]], value=y[2])]
),
)
.set_global_opts(title_opts=opts.TitleOpts(title="薪资情况"),
xaxis_opts=opts.AxisOpts(name=薪资范围), # 设置x轴名字属性
yaxis_opts=opts.AxisOpts(name=数量), # 设置y轴名字属性
)
)
return c
#合并
def page_draggable_layout():
page = Page(layout=Page.DraggablePageLayout)
page.add(
bar_datazoom_slider(),
map_china(),
pie_rich_label(),
line_markpoint_custom(),
)
page.render("page_draggable_layout.html")
if __name__ == "__main__":
page_draggable_layout()
执行完后,会在当前目录下生成一个page_draggable_layout.html。
然后我们用浏览器打开,就会看到下面这样,我们可以随便拖动虚线框来进行组合,组合好后点击Save Config就会下载一个chart_config.json,然后在文件中找到它,剪切到py当前目录。
文件放置好后,可以新建一个py文件来执行以下代码,这样就会生成一个resize_render.html,也就完成了。
from pyecharts.charts import PagePage.save_resize_html(./page_draggable_layout.html,cfg_file=chart_config.json)
最后,点击打开resize_render.html,我们合并成功的图表就是这样啦!
总结
到此这篇关于Python抓取数据并可视化的文章就介绍到这了,更多相关Python抓取数据可视化内容请搜索盛行IT软件开发工作室以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT软件开发工作室!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。