版權(quán)聲明:本文為作者原創(chuàng)文章,可以隨意轉(zhuǎn)載,但必須在明確位置標(biāo)明出處S淅ァ!麻蹋!
最近知乎上有一篇文章《月入五萬(wàn)的西二旗人教你如何活得像月薪五千》說(shuō)的是北京西二旗程序員月入五萬(wàn)卻過(guò)著月薪五千一樣的生活跛溉,相比較其它行業(yè),程序員的工資相對(duì)來(lái)說(shuō)算是比較高的哥蔚,程序員給人的形象永遠(yuǎn)都是眼鏡倒谷、沒(méi)刮過(guò)的胡須、亂糟糟的頭發(fā)糙箍、還有個(gè)必備的電腦包(畢竟這可是吃飯的家伙)渤愁,就是這種形象的人拿著月薪五萬(wàn)卻過(guò)著月薪五千的生活,不過(guò)這是有原因的深夯,996的工作時(shí)間(朝九晚九+周六)抖格,公司發(fā)的工裝和沖鋒衣可以一年四季穿到頭,全年都不帶買衣服的咕晋,唯一的愛(ài)好可能就是打打游戲雹拄,買買電子產(chǎn)品了,顯示器一定要大掌呜,而且不止一個(gè)滓玖。所以如果你是妹子,那么找個(gè)程序員也是不錯(cuò)的质蕉,安全势篡、放心。當(dāng)然本章的重點(diǎn)不是講怎么月入五萬(wàn)模暗,本章的重點(diǎn)是講怎么將數(shù)據(jù)寫入到Excel表格中禁悠,方便我們做簡(jiǎn)單的統(tǒng)計(jì)。
上一章講到了將如何將數(shù)據(jù)寫入到文本文件里兑宇,但文本文件操作比較簡(jiǎn)單碍侦,如果我們要對(duì)數(shù)據(jù)做一些統(tǒng)計(jì)之類的操作那么文本文件就提供不了這些支持了,所以本章我們將數(shù)據(jù)寫到Excel表格里做一些簡(jiǎn)單的統(tǒng)計(jì)隶糕。
openpyxl庫(kù)
讀寫Excel需要用到第三方庫(kù)瓷产,這里我們選擇openpyxl庫(kù),這個(gè)庫(kù)可以操作新版本的Excel枚驻,xlrt濒旦、xlwt兩個(gè)庫(kù)是用來(lái)讀寫老版本的Execl的,也就是擴(kuò)展名是*.xls
安裝openpyxl庫(kù)
在ubuntu命令行終端輸入以下命令就可以安裝openpydl庫(kù)了测秸,如果沒(méi)有報(bào)錯(cuò)則證明你安裝好了疤估。
sudo pip install openpyxl
校驗(yàn)openpyxl是否安裝
在終端執(zhí)行python--》回車--》import openpyxl--》回車。如果沒(méi)有拋出異常證明該庫(kù)已經(jīng)安裝好了霎冯。
workbook铃拇、worksheet
要讀寫Excel我們首先要弄清楚兩個(gè)概念,
- workbook: 工作簿沈撞,它的意思是我們打開(kāi)一個(gè)Excel文檔后慷荔,整個(gè)Excel文檔被稱作為一個(gè)工作簿。
- worksheet: 工作表缠俺,如果我們新鍵一個(gè)Excel文件显晶,然后打開(kāi)它,我們可以看到底部有一個(gè)Sheet的選項(xiàng)壹士,也就是我們的當(dāng)前表格磷雇,也被稱之為活動(dòng)表格。
所以我們操作Excel表格的時(shí)候一定是要先有workbook后才能去操作worksheet躏救,這點(diǎn)概念大家要弄清楚唯笙。
在內(nèi)存中操作Excel
有了上面工作簿和工作表的概念,那么我們?cè)趦?nèi)存中的操作步驟也要遵循上面的先有工作簿盒使,再有工作表的規(guī)定崩掘。所以我們第一步是先創(chuàng)建一個(gè)工作簿,其次是獲取一個(gè)活動(dòng)的工作表少办,最后才是去操作工作表中的元素苞慢,代碼如下
from openpyxl import Workbook
#創(chuàng)建一個(gè)工作簿
wb = Workbook()
#活取一個(gè)活動(dòng)的工作表
ws = wb.active
#給A1單元賦值
ws['A1'] = 'test'
#保存Excel
wb.save('sample.xlsx')
執(zhí)行結(jié)果
從結(jié)果可以看到A1單元確實(shí)被賦值為test了。Sheet及時(shí)我們的活動(dòng)表格英妓。
如果你想修改Sheet的名稱挽放,或者想創(chuàng)建其它Sheet,下面這么做就可以了鞋拟。
from openpyxl import Workbook
#創(chuàng)建一個(gè)工作簿
wb = Workbook()
#活取一個(gè)活動(dòng)的工作表
ws = wb.active
#給A1單元賦值
ws['A1'] = 'test'
ws.title = 'test'
ws1 = wb.create_sheet("test1")
ws2 = wb.create_sheet("test2")
#保存Excel
wb.save('sample.xlsx')
執(zhí)行結(jié)果
從結(jié)果中可以看到我們將Sheet該成了test骂维,并且新創(chuàng)建了test1,test2表格頁(yè)簽。
訪問(wèn)元素
這里需要注意的是贺纲,當(dāng)我們?cè)趦?nèi)存中創(chuàng)建一個(gè)worksheet的時(shí)候航闺,它是不包含cells的,也就是不包含創(chuàng)建了單元格猴誊,只有當(dāng)我們第一次去訪問(wèn)它的時(shí)候它才回去創(chuàng)建單元格潦刃,就像上面的代碼ws['A1'] = 'test',當(dāng)給A1單元格賦值的時(shí)候才回去創(chuàng)建單元格A1懈叹,這樣做的目的相信大家都已經(jīng)看出來(lái)了乖杠,節(jié)約資源,提高效率澄成。cells操作還可以通過(guò)行胧洒、列來(lái)操作畏吓,如ws.cell(row=4, column=2, value=10),就是給第4行第二列賦值為10卫漫,各位可是執(zhí)行運(yùn)行試試菲饼,看看結(jié)果是不是這樣的。
多行多列范圍訪問(wèn)
- 切片式范圍訪問(wèn): 切片是python里經(jīng)常用到的操作列赎,openpyxl庫(kù)對(duì)范圍訪問(wèn)也可以切片宏悦,語(yǔ)法如下
from openpyxl import Workbook
#創(chuàng)建一個(gè)工作簿
wb = Workbook()
#活取一個(gè)活動(dòng)的工作表
ws = wb.active
cell_range = ws['A1' : 'C4']
print(cell_range)
訪問(wèn)A1到C4范圍的所有cell,它的輸出結(jié)果如下:
((<Cell 'Sheet'.A1>, <Cell 'Sheet'.B1>, <Cell 'Sheet'.C1>),
(<Cell 'Sheet'.A2>, <Cell 'Sheet'.B2>, <Cell 'Sheet'.C2>),
(<Cell 'Sheet'.A3>, <Cell 'Sheet'.B3>, <Cell 'Sheet'.C3>),
(<Cell 'Sheet'.A4>, <Cell 'Sheet'.B4>, <Cell 'Sheet'.C4>))
結(jié)果返回的是一個(gè)元組包吝,元組里每一項(xiàng)又包含了一個(gè)元組饼煞,該元組表示一行,一共4行诗越。
- 按列訪問(wèn): 按列訪問(wèn)的語(yǔ)法如下
from openpyxl import Workbook
#創(chuàng)建一個(gè)工作簿
wb = Workbook()
#活取一個(gè)活動(dòng)的工作表
ws = wb.active
col_range = ws['C:D']
print(col_range)
訪問(wèn)第C列到第D列的cell砖瞧,執(zhí)行結(jié)果如下
((<Cell 'Sheet'.C1>,), (<Cell 'Sheet'.D1>,))
從這里我們可以看出在內(nèi)存中創(chuàng)建一個(gè)工作表時(shí),只有訪問(wèn)cell的時(shí)候cell才回被創(chuàng)建嚷狞,當(dāng)我們的程序做出一下改變是芭届,它的結(jié)果會(huì)是什么呢。
from openpyxl import Workbook
#創(chuàng)建一個(gè)工作簿
wb = Workbook()
#活取一個(gè)活動(dòng)的工作表
ws = wb.active
ws['A4'] = 'SFS'
col_range = ws['C:D']
print(col_range)
執(zhí)行程序后的結(jié)果變成了:
((<Cell 'Sheet'.C1>, <Cell 'Sheet'.C2>, <Cell 'Sheet'.C3>, <Cell 'Sheet'.C4>),
(<Cell 'Sheet'.D1>, <Cell 'Sheet'.D2>, <Cell 'Sheet'.D3>, <Cell 'Sheet'.D4>))
- 按行訪問(wèn):按行訪問(wèn)跟按列訪問(wèn)是一樣的感耙,具體的執(zhí)行結(jié)果是怎么楊的褂乍,大家可以自己去嘗試一下,語(yǔ)法如下:
row5= ws[5]
row_range = ws[5:10]
迭代器訪問(wèn)行列區(qū)域
除了切片方式即硼,openpyxl也提供了迭代器的方式來(lái)訪問(wèn)行列逃片,如下按行優(yōu)先訪問(wèn)2 * 3列范圍的元素
from openpyxl import Workbook
#創(chuàng)建一個(gè)工作簿
wb = Workbook()
#活取一個(gè)活動(dòng)的工作表
ws = wb.active
for row in ws.iter_rows(min_row=1, max_col=3, max_row=2):
for cell in row:
print(cell)
執(zhí)行結(jié)果如下:
<Cell 'Sheet'.A1>
<Cell 'Sheet'.B1>
<Cell 'Sheet'.C1>
<Cell 'Sheet'.A2>
<Cell 'Sheet'.B2>
<Cell 'Sheet'.C2>
按列優(yōu)先訪問(wèn)如下:
from openpyxl import Workbook
#創(chuàng)建一個(gè)工作簿
wb = Workbook()
#活取一個(gè)活動(dòng)的工作表
ws = wb.active
for row in ws.iter_cols(min_row=1, max_col=3, max_row=2):
for cell in row:
print(cell)
執(zhí)行結(jié)果如下:
<Cell 'Sheet'.A1>
<Cell 'Sheet'.A2>
<Cell 'Sheet'.B1>
<Cell 'Sheet'.B2>
<Cell 'Sheet'.C1>
<Cell 'Sheet'.C2>
如果你需要迭代所有的行列那你可以像這樣做:
from openpyxl import Workbook
#創(chuàng)建一個(gè)工作簿
wb = Workbook()
#活取一個(gè)活動(dòng)的工作表
ws = wb.active
#按行優(yōu)先迭代
ws['C9'] = 'test'
print(tuple(ws.rows))
#按列優(yōu)先迭代
print(tuple(ws.columns))
執(zhí)行結(jié)果到底怎樣,各位自行探索一下只酥。
加載一個(gè)已存在的Excel文檔
加載一個(gè)已存在的Excel文檔非常簡(jiǎn)單褥实,加載后返回一個(gè)workbook對(duì)象,那么我們就可以像上面介紹的操作去處理加載后的文檔了裂允。
from openpyxl import load_workbook
wb2 = load_workbook('sample.xlsx')
print wb2.get_sheet_names()
圖表
圖表有2D和3D圖表损离,下面以一個(gè)2D的圖表作為例子,這個(gè)例子是openpyxl手冊(cè)上的例子
from openpyxl import Workbook
from openpyxl.chart import (
AreaChart,
Reference,
Series,
)
wb = Workbook()
ws = wb.active
rows = [
['Number', 'Batch 1', 'Batch 2'],
[2, 40, 30],
[3, 40, 25],
[4, 50, 30],
[5, 30, 10],
[6, 25, 5],
[7, 50, 10],
]
for row in rows:
ws.append(row)
chart = AreaChart()
chart.title = "Area Chart"
chart.style = 13
chart.x_axis.title = 'Test'
chart.y_axis.title = 'Percentage'
cats = Reference(ws, min_col=1, min_row=1, max_row=7)
data = Reference(ws, min_col=2, min_row=1, max_col=3, max_row=7)
chart.add_data(data, titles_from_data=True)
chart.set_categories(cats)
ws.add_chart(chart, "A10")
wb.save("area.xlsx")
執(zhí)行后的結(jié)果:
openpyxl提供了非常豐富的圖表支持绝编,像條形圖僻澎、柱狀圖、餅圖十饥、曲線圖等等窟勃,有興趣的同學(xué)可以到https://openpyxl.readthedocs.io/en/default/查看。當(dāng)然想合并單元格逗堵、公式秉氧、高亮、文本格式等等用法都可以到上面提供的網(wǎng)址查看蜒秤。
用圖表來(lái)表示哪個(gè)用戶獲得的好笑數(shù)最高
下面我們把爬到的數(shù)據(jù)寫入到Excel表格中汁咏,并且用圖表來(lái)先生哪個(gè)用戶的好笑數(shù)最高亚斋,代碼如下,源碼放在https://github.com/Gavinxyj/Python/tree/master/python_study/Scrapy/modules歡迎大家fork攘滩、Stars
# Scheduler.py
from urllib import request
from urllib import error
import re
import os
from Excel import ExcelOper
class Scheduler(object):
def __init__(self, url, user_agent):
self.url = url
self.headers = {'User-Agent': user_agent}
self.excel_obj = ExcelOper()
def read_html(self, codec):
'''[read_html]
[讀取html頁(yè)面內(nèi)容]
Arguments:
url {[string]} -- [url地址]
headers {[dict]} -- [用戶代理伞访,這里是一個(gè)字典類型]
codec {[string]} -- [編碼方式]
Returns:
[string] -- [頁(yè)面內(nèi)容]
'''
# 構(gòu)建一個(gè)請(qǐng)求對(duì)象
try:
req = request.Request(self.url, headers=self.headers)
# 打開(kāi)一個(gè)請(qǐng)求
response = request.urlopen(req)
# 讀取服務(wù)器返回的頁(yè)面數(shù)據(jù)內(nèi)容
content = response.read().decode(codec)
return content
except error.URLError as e:
print(e.reason)
return None
def match_element(self, content, pattern):
'''[match_element]
[匹配元素]
Arguments:
content {[string]} -- [文本內(nèi)容]
pattern {[object]} -- [匹配模式]
Returns:
[list] -- [匹配到的元素]
'''
# 匹配所有用戶信息
userinfos = re.findall(pattern, content)
return userinfos
def write_file(self, content):
with open('./qiubai.txt', 'a+') as fp:
fp.write(content + '\n')
def get_content(self):
content = self.read_html('utf-8')
pattern = re.compile(r'<div class="article block untagged mb15[\s\S]*?class="stats-vote".*?</div>', re.S)
if content:
userinfos = self.match_element(content, pattern)
infos = []
if userinfos:
pattern = re.compile(r'<a href="(.*?)".*?<h2>(.*?)</h2>.*?<div class="content">(.*?)</div>.*?<i class="number">(.*?)</i>', re.S)
picture = re.compile(r'<div class="thumb">.*?src="(.*?)"', re.S)
for userinfo in userinfos:
item = self.match_element(userinfo, pattern)
pictures = self.match_element(userinfo, picture)
try:
if item:
userid, name, content, num = item[0]
# 去掉換行符,<span></span>轰驳,<br/>符號(hào)
userid = re.sub(r'\n|<span>|</span>|<br/>', '', userid)
name = re.sub(r'\n|<span>|</span>|<br/>', '', name)
content = re.sub(r'\n|<span>|</span>|<br/>|\x01', '', content)
if pictures:
path = './users/'
if not os.path.exists(path):
os.makedirs(path)
request.urlretrieve('http:' + pictures[0], path + os.path.basename(pictures[0]))
infos.append((userid, name, int(num), content, pictures[0]))
#print((userid, name, num, content, pictures[0]))
#self.write_file(userid + '\t' + name + '\t' + content + '\t' + num + '\t' + pictures[0])
else:
#print((userid, name, content, num))
infos.append((userid, name, int(num), content))
#self.write_file(userid + '\t' + name + '\t' + content + '\t' + num)
except Exception as e:
print(e)
self.excel_obj.write_excel(infos)
if __name__ == '__main__':
url = 'https://www.qiushibaike.com'
user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36'
handle = Scheduler(url, user_agent)
handle.get_content()
# Excel.py
from openpyxl import Workbook
from openpyxl.chart import (
AreaChart,
Reference,
Series,
)
class ExcelOper(object):
def __init__(self):
self.wb = Workbook()
def write_excel(self, infos):
try:
ws = self.wb.active
# 增加表頭
ws.append(['id', 'username', 'funny_num', 'context', 'url'])
for row_index,row_value in enumerate(infos, 2):
for col_index, col_value in enumerate(row_value, 1):
ws.cell(row=row_index, column=col_index, value=col_value)
self.draw_chart(ws)
self.wb.save('qiubai.xlsx')
except Exception as e:
raise e
def draw_chart(self, ws):
chart = AreaChart()
chart.title = "Joker Chart"
chart.style = 13
chart.x_axis.title = 'User'
chart.y_axis.title = 'Funny Num'
cats = Reference(ws, min_col=2, min_row=1, max_row=25)
data = Reference(ws, min_col=3, min_row=1, max_col=3, max_row=25)
chart.add_data(data, titles_from_data=True)
chart.set_categories(cats)
ws.add_chart(chart, "A30")
def read_excel(self):
pass
整個(gè)程序增加了一個(gè)Excel.py文件,主要用來(lái)主要用來(lái)操作excel表格弟灼,里面使用到的方法在本章都已經(jīng)講過(guò)级解,更多的圖表制作有興趣的同學(xué)可以自己去研究研究,最后奉上執(zhí)行結(jié)果田绑。
PS: 如果你是“表”姐勤哗,需要經(jīng)常在網(wǎng)上收集內(nèi)容,那么找個(gè)程序員男朋友吧掩驱,他會(huì)幫你弄得妥妥的芒划,再也不用加班,不用熬夜了欧穴,哈哈哈...