最近在做关于分布式爬虫和数据抽取计算的两个方面的日志分析,统计的结果也比较简单,把收集到的日志存入到hadoop,然后用python streaming实现mapreduce,把结果存入到mongodb里面。只是python这家伙实在慢的可以,直接改用 pig 来实现日志的解析,速度明显要好点。 说正题,现在数据的展现用的是 highcharts来前端的现实,实时的数据是放在Influxdb里面,Influxdb是个含有时间序的数据库。 然而我们还是有个需求是,可以做一定程度的日报和周报。 把最大的几个网上抓取数目给抽取出来。 原本我想的有些复杂,打算制作一个干净的图表页面,然后底层调用phantomjs进行截图,然后发邮件。
原文地址是,http://xiaorui.cc
但是问题来了…. … … 人家说,这高端是高端,但是你截图是好,各种的html的样式随你的变。但是你tmd不能让人复制数据呀。 这是多大的仇多大的怨呀… … 顾问说,我原本想把数据复制出来,然后放到其他的数据平台上做运算,好家伙,你这一下子来了个图片,你逗比呐。 让哥哥们一个个的复制呀。 这尼玛 ,这被喷的… …
我和你多大的仇,多大的怨 … … … 好吧,改用xlsxwriter重新制作图表。 xlsxwriter 的图表和数据表还是很简单的,这个模块帮你做了很好用的封装。
import xlsxwriter
workbook = xlsxwriter.Workbook('chart_column.xlsx')
worksheet = workbook.add_worksheet()
bold = workbook.add_format({'bold': 1})
# 这是个数据table的列
headings = ['Number', 'Batch 1', 'Batch 2']
data = [
[2, 3, 4, 5, 6, 7],
[10, 40, 50, 20, 10, 50],
[30, 60, 70, 50, 40, 30],
]
worksheet.write_row('A1', headings, bold)
worksheet.write_column('A2', data[0])
worksheet.write_column('B2', data[1])
worksheet.write_column('C2', data[2])
############################################
#创建一个图表,类型是column
chart1 = workbook.add_chart({'type': 'column'})
# 配置series,这个和前面wordsheet是有关系的。
chart1.add_series({
'name': '=Sheet1!B1',
'categories': '=Sheet1!A2:A7',
'values': '=Sheet1!B2:B7',
})
# Configure a second series. Note use of alternative syntax to define ranges.
chart1.add_series({
'name': ['Sheet1', 0, 2],
'categories': ['Sheet1', 1, 0, 6, 0],
'values': ['Sheet1', 1, 2, 6, 2],
})
# Add a chart title and some axis labels.
chart1.set_title ({'name': 'Results of sample analysis'})
chart1.set_x_axis({'name': 'Test number'})
chart1.set_y_axis({'name': 'Sample length (mm)'})
# Set an Excel chart style.
chart1.set_style(11)
# Insert the chart into the worksheet (with an offset).
worksheet.insert_chart('D2', chart1, {'x_offset': 25, 'y_offset': 10})
#######################################################################
#
# Create a stacked chart sub-type.
#
chart2 = workbook.add_chart({'type': 'column', 'subtype': 'stacked'})
# Configure the first series.
chart2.add_series({
'name': '=Sheet1!B1',
'categories': '=Sheet1!A2:A7',
'values': '=Sheet1!B2:B7',
})
# Configure second series.
chart2.add_series({
'name': '=Sheet1!C1',
'categories': '=Sheet1!A2:A7',
'values': '=Sheet1!C2:C7',
})
# Add a chart title and some axis labels.
chart2.set_title ({'name': 'Stacked Chart'})
chart2.set_x_axis({'name': 'Test number'})
chart2.set_y_axis({'name': 'Sample length (mm)'})
# Set an Excel chart style.
chart2.set_style(12)
# Insert the chart into the worksheet (with an offset).
worksheet.insert_chart('D18', chart2, {'x_offset': 25, 'y_offset': 10})
#######################################################################
#
# Create a percentage stacked chart sub-type.
#
chart3 = workbook.add_chart({'type': 'column', 'subtype': 'percent_stacked'})
# Configure the first series.
chart3.add_series({
'name': '=Sheet1!B1',
'categories': '=Sheet1!A2:A7',
'values': '=Sheet1!B2:B7',
})
# Configure second series.
chart3.add_series({
'name': '=Sheet1!C1',
'categories': '=Sheet1!A2:A7',
'values': '=Sheet1!C2:C7',
})
# Add a chart title and some axis labels.
chart3.set_title ({'name': 'Percent Stacked Chart'})
chart3.set_x_axis({'name': 'Test number'})
chart3.set_y_axis({'name': 'Sample length (mm)'})
# Set an Excel chart style.
chart3.set_style(13)
# Insert the chart into the worksheet (with an offset).
worksheet.insert_chart('D34', chart3, {'x_offset': 25, 'y_offset': 10})
workbook.close()

有些数据是需要做平均值计算的,看了下官方实例对于AVERAGE的处理函数,还算可以。然后又从某个论坛那边,搜到了刘天斯发表的一段代码,然后改了改就直接用了。自己这是需要关心series值 。 excel是有很多计算的函数计算的,其实我是懒得在接口端做计算, 就直接调用xlsxwriter计算了。
嗯,还有一个中文的问题… …. 居然还犯这么初级的问题… 编码没有指明的问题,需要指明sys.setdefaultencoding,或则会是自己申明decode
self._xml_si_element(string, attributes)
File "/Library/Python/2.7/site-packages/xlsxwriter/xmlwriter.py", line 122, in _xml_si_element
self.fh.write("""<si><t%s>%s</t></si>""" % (attr, string))
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/codecs.py", line 691, in write
return self.writer.write(data)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/codecs.py", line 351, in write
data, consumed = self.encode(object, self.errors)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe5 in position 7: ordinal not in range(128)
大家一定要把xlsxwriter对象给关闭了,不然会报错….
Exception Exception: Exception('Exception caught in workbook destructor. Explicit close() may be required for workbook.',) in <bound method Workbook.__del__ of <xlsxwriter.workbook.Workbook object at 0x10053d4d0>> ignored
下面是个干净的例子,我把从tornado 接口获取数据,到发邮件的逻辑给去掉了。。。
#coding: utf-8
import xlsxwriter
import random
def get_num():
return random.randrange(0, 201, 2)
workbook = xlsxwriter.Workbook('analyse_spider.xlsx') #创建一个Excel文件
worksheet = workbook.add_worksheet() #创建一个工作表对象
chart = workbook.add_chart({'type': 'column'}) #创建一个图表对象
#定义数据表头列表
title = [u'业务名称',u'星期一',u'星期二',u'星期三',u'星期四',u'星期五',u'星期六',u'星期日',u'平均流量']
buname= [u'时光网',u'汽车之家',u'weixin.com',u'163.com',u'baidu.com'] #定义频道名称
#定义5频道一周7天流量数据列表
data = []
for i in range(5):
tmp = []
for j in range(7):
tmp.append(get_num())
data.append(tmp)
format=workbook.add_format() #定义format格式对象
format.set_border(1) #定义format对象单元格边框加粗(1像素)的格式
format_title=workbook.add_format() #定义format_title格式对象
format_title.set_border(1) #定义format_title对象单元格边框加粗(1像素)的格式
format_title.set_bg_color('#cccccc') #定义format_title对象单元格背景颜色为
#'#cccccc'的格式
format_title.set_align('center') #定义format_title对象单元格居中对齐的格式
format_title.set_bold() #定义format_title对象单元格内容加粗的格式
format_ave=workbook.add_format() #定义format_ave格式对象
format_ave.set_border(1) #定义format_ave对象单元格边框加粗(1像素)的格式
format_ave.set_num_format('0.00') #定义format_ave对象单元格数字类别显示格式
#下面分别以行或列写入方式将标题、业务名称、流量数据写入起初单元格,同时引用不同格式对象
worksheet.write_row('A1',title,format_title)
worksheet.write_column('A2', buname,format)
worksheet.write_row('B2', data[0],format)
worksheet.write_row('B3', data[1],format)
worksheet.write_row('B4', data[2],format)
worksheet.write_row('B5', data[3],format)
worksheet.write_row('B6', data[4],format)
#定义图表数据系列函数
def chart_series(cur_row):
worksheet.write_formula('I'+cur_row, \
'=AVERAGE(B'+cur_row+':H'+cur_row+')',format_ave) #计算(AVERAGE函数)频
#道周平均流量
chart.add_series({
'categories': '=Sheet1!B1:H1', #将“星期一至星期日”作为图表数据标签(X轴)
'values': '=Sheet1!B'+cur_row+':H'+cur_row, #频道一周所有数据作
#为数据区域
'line': {'color': 'black'}, #线条颜色定义为black(黑色)
'name': '=Sheet1!A'+cur_row, #引用业务名称为图例项
})
for row in range(2, 7): #数据域以第2~6行进行图表数据系列函数调用
chart_series(str(row))
chart.set_size({'width': 577, 'height': 287}) #设置图表大小
chart.set_title ({'name': u'爬虫分析'}) #设置图表(上方)大标题
chart.set_y_axis({'name': 'count'}) #设置y轴(左侧)小标题
worksheet.insert_chart('A8', chart) #在A8单元格插入图表
workbook.close() #关闭Excel文档


这个设置x轴,我没有设置成功
好赞
这个刘天斯的书上有吧
怎么把刻度显示成万,比如30000-》3万
这个有用