菜鸟炒股,做新型肺炎的数据可视化

一、背景:
虽然穷还菜鸟,但投钱进了股市,也维持着一个涨停数据项目。当前最重大时事就是新型肺炎。各大网站都有数据统计,可视化做很漂亮。但都是国内的,没做国际的。而新型肺炎已经上升为国际事件,国内与国际资本市场也相互影响。这种情况下,其他国家新型肺炎数据也值得关注.没有现成的就得自己做。
编程菜鸟初学不精,能实现目标就好。
二、过程:
1、爬取数据:
最终选择了网易。能力有限,其他的爬不下来。

import re
import time
import requests
from bs4 import BeautifulSoup

url = "http://news.163.com/special/epidemic/"

def get_htmltext(url):
""
直接黏贴的,找了个最简单的。不懂原理,能得到想要的数据。
""
    try:
        r = requests.get(url, timeout=30)
        r.raise_for_status()
        r.content.decode('gbk').encode('utf-8')
        return r.text
    except:
        raise 
  
text = get_htmltext(url)
soup = BeautifulSoup(text, 'html.parser')
data = soup.find_all('p')

[

中国(含港澳台):确诊 11891 例,死亡 259 例,治愈 270 例

,

海外:确诊 137 例

,

海外确诊病例:日本20例,泰国19例

,

新加坡18例,韩国12例,澳大利亚12例

,

马来西亚8例,德国7例,美国7例,法国6例

,

越南6例,阿联酋4例,加拿大4例,英国2例

,

意大利2例,俄罗斯2例,印度1例,瑞典1例

,

芬兰1例,尼泊尔1例,西班牙1例

,

斯里兰卡1例,柬埔寨1例,菲律宾1例

,

单击省份可查看病例数

,

以上数据均来自官方通报

,

全国确诊

,

治愈人数

,

死亡人数

,

已开启实时追踪

]

2、整理数据:

result = str(data).replace('<p>','').replace('</p>','')
result = str(result).split(',')
l0 = [i for i in result if not i.startswith(' <p')][:-3] # 通过for遍历,用<p来判断是否为有用数据,然后切片得到如下: 

[’[中国(含港澳台):确诊 11891 例,死亡 259 例,治愈 270 例’, ’ 海外:确诊 137 例’, ’
海外确诊病例:日本20例,泰国19例’, ’ 新加坡18例,韩国12例,澳大利亚12例’, ’
马来西亚8例,德国7例,美国7例,法国6例’, ’ 越南6例,阿联酋4例,加拿大4例,英国2例’, ’
意大利2例,俄罗斯2例,印度1例,瑞典1例’, ’ 芬兰1例,尼泊尔1例,西班牙1例’, ’ 斯里兰卡1例,柬埔寨1例,菲律宾1例’]

l1 = [i.split(',') for i in l0]
l2 = [g.strip() for i in l1  for g in i] # 嵌套for循环分割,得到最终数据列表
['[中国(含港澳台):确诊 11891 例',
 '死亡 259 例',
 '治愈 270 例',
 '海外:确诊 137 例',
 '海外确诊病例:日本20例',
 '泰国19例',
 '新加坡18例',
 '韩国12例',
 '澳大利亚12例',
 '马来西亚8例',
 '德国7例',
 '美国7例',
 '法国6例',
 '越南6例',
 '阿联酋4例',
 '加拿大4例',
 '英国2例',
 '意大利2例',
 '俄罗斯2例',
 '印度1例',
 '瑞典1例',
 '芬兰1例',
 '尼泊尔1例',
 '西班牙1例',
 '斯里兰卡1例',
 '柬埔寨1例',
 '菲律宾1例']
#使用正则表达式将总体和明细数据拆分,取出数字转为int,并去除多余字符,用字典推导式生成字典。
total = {re.sub(r'[\d]+ 例','',i).replace(':',''):int(re.search(r'[\d]+', i).group()) for i in l2[:4]}
overseas_detail = {re.sub(r'[\d]+例','',i).replace('海外确诊病例:',''):int(re.search(r'[\d]+', i).group()) for i in l2[4:]}
#添加海外国家数量和日期,最终结果为一个字典。
total['海外感染国家总数'] = len(overseas_detail)
total['日期'] = time.strftime('%Y%m%d')
'''
{'[中国(含港澳台)确诊 ': 11891,
 '死亡 ': 259,
 '治愈 ': 270,
 '海外确诊 ': 137,
 '海外感染国家总数': 23,
 '日期': '20200201'}
 '''

3、做可视化:

import pandas
from pyecharts import options as opts
from pyecharts.charts import Line, Grid

df_ncov = pd.DataFrame(total.values(), index=total.keys()).T # 转为DataFrame,重设索引
df_ncov = df_ncov.set_index('日期')

def get_line(tb):
   line0 = Line(init_opts=opts.InitOpts(width='500px', bg_color='#F5F5F7'))
   line0.add_xaxis(xaxis_data = tb.index.tolist())
   for col in tb.columns[1:]: 
       line0.add_yaxis(
       series_name=col,
       y_axis=tb[col].values,
       is_smooth=True,
       is_hover_animation=False,
       linestyle_opts=opts.LineStyleOpts(width=3, opacity=0.5),
       label_opts=opts.LabelOpts(is_show=True),
       # itemstyle_opts=opts.ItemStyleOpts(color='#099e79'),
       is_symbol_show=True)
       # markline_opts=opts.MarkLineOpts(data=[opts.MarkLineItem(type_="average")]))
   line0.set_global_opts(
       xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=45),is_scale=True),
       yaxis_opts=opts.AxisOpts(is_scale=True),
       title_opts=opts.TitleOpts(title="",subtitle=''),
       legend_opts=opts.LegendOpts(pos_left='right'),
       toolbox_opts=opts.ToolboxOpts(orient='vertical',pos_left=None,pos_top='top'),
       # datazoom_opts=[opts.DataZoomOpts(), opts.DataZoomOpts(type_="inside")]
   )
   line1 = Line(init_opts=opts.InitOpts(width='500px', bg_color='#F5F5F7'))
   line1.add_xaxis(xaxis_data = tb.index.tolist())
   for col in tb.columns[:1]: 
       line1.add_yaxis(
       series_name=col,
       y_axis=tb[col].values,
       is_smooth=True,
       is_hover_animation=False,
       linestyle_opts=opts.LineStyleOpts(width=3, opacity=0.5),
       label_opts=opts.LabelOpts(is_show=True),
       # itemstyle_opts=opts.ItemStyleOpts(color='#099e79'),
       is_symbol_show=True)
       # markline_opts=opts.MarkLineOpts(data=[opts.MarkLineItem(type_="average")]))
   line1.set_global_opts(
       xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=45),is_scale=True),
       yaxis_opts=opts.AxisOpts(is_scale=True),
       title_opts=opts.TitleOpts(title="新型肺炎人数",subtitle='',pos_left='center'),
       legend_opts=opts.LegendOpts(pos_left='left'),
       toolbox_opts=opts.ToolboxOpts(orient='vertical',pos_left=None,pos_top='top'),
       # datazoom_opts=[opts.DataZoomOpts(), opts.DataZoomOpts(type_="inside")]
   )
   
   grid = (
       Grid()
       .add(line0, grid_opts=opts.GridOpts(pos_left="50%"))
       .add(line1, grid_opts=opts.GridOpts(pos_right="50%"))
   )
   return grid
   ln = get_line(df_ncov)
   ln.render_notebook()
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200202002532208.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2hvdG9vdG9w,size_16,color_FFFFFF,t_70)

把数据导入了自己搭建的数据库,以后每日更新,作为参考。
三、总结:
1、不满意的地方:
本想加上疑似人数,可是能力太差。都是script的json格式,不知道怎么弄下来,最终放弃。
吐槽下pycharts。去年做涨停项目的时候,pyecharts的主页例子都有展示图片,现在反倒没有了。很不友好,不知道具体效果,都是代码,没有图片很不方便。没有基础的,估计会被劝退。
另外因为数据跨度大,放在一起效果不佳。想了几个方案解决,调整坐标(指数坐标或双坐标),上下图,左右图。第一个,没有指数坐标的选项,双坐标提示line没有overlab。示例中是bar和line做双坐标。上下不好看。最终选择左右图,其实也不好看。不满意。
2、学到的东西:
推导式、正则表达式、一些爬虫知识、重温了pyecharts等。
3、感悟:
想做成点事情真不容易,自己水平太低。这段时间看软件工程,想提高代码复用性,结果很难实现,还得努力啊。另外变懒了,懒得敲代码,有些生疏,学了很多知识和技巧,得用起来。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值