一、實驗背景
每年的12月底,由於接近年底,手機通訊會比較頻繁,通過登錄移動網上營業廳以後大家可以知道自己這一個月的語音詳單如何,但是望着密密麻麻的數據,有幾個人靜得下心去仔細看看每一條通訊記錄的詳情,所以在這個背景下博主花了點時間寫了一個賬單分析的腳本代碼,當是練練手吧,主要的目的是打印下這個月內通訊排名前三的是哪幾個號碼。本文提供僅一個簡單實例。
二、實驗準備
- Python語言
- 移動網上營業廳(浙江)當月語音詳單
三、實驗過程
首先是準備數據,也就是當月的移動語音詳單,通過登錄移動網上營業廳,找到查詢業務,下載選定月份的語音詳單,這裏需要注意一下,博主所在的浙江移動下載下來的詳單爲html文件,假如大家有人下載的是Excel文件或者csv文件(不知道會不會有這種類型的文件),也可以通過自己動手去實現相關讀取功能。廢話不多說,移動詳單如下所示:
通過Firefox的web控制檯查看html的標籤信息,確定了需要抓取的內容格式:
之後通過Python的beautifulsoup模塊來對文件內容進行解析和重要數據的提取
Python代碼的第一個函數主要是對html文件讀取以後解析相關的數據,以電話號碼爲key構造一個dict對象來存儲數據,這裏需要提取的是對於指定號碼的主叫和被叫時間的記錄,所以選擇了一個list來保存數據,list對象的第一位存下主叫時間,第二位存下被叫時間,代碼一角如下:
#!/usr/bin/python
#coding:utf-8
from bs4 import BeautifulSoup
'''import sys
reload(sys)
sys.setdefaultencoding('utf-8')'''
#解析賬單html文件,返回信息dict對象,key爲電話號碼,value爲一個list對象,第一位是主叫時間,第二位是被叫時間
def parseHTML(filename):
soup = BeautifulSoup(open(filename),'lxml')
soup1 = BeautifulSoup("<td>主叫 </td>",'lxml')
tmp = soup1.find_all('td')
flag1 = str(unicode(tmp[0].string))
soup2 = BeautifulSoup('<td>被叫 </td>','lxml')
tmp = soup2.find_all('td')
flag2 = str(unicode(tmp[0].string))
tr_tags = soup.find_all('tr',class_='content2')
infos = dict()
for tr_tag in tr_tags:
info_list = list()
td_tags = tr_tag.find_all('td',class_='talbecontent1')
if len(td_tags) <= 3:
continue
for td_tag in td_tags:
info_list.append(unicode(td_tag.string))
tele = str(info_list[5])
call_type = str(info_list[4])
call_time = info_list[2]
times = spliteTime(call_time)
if tele in infos.keys():
if call_type == flag1:
infos[tele][0] += times
else:
infos[tele][1] += times
else:
time_list = list([0,0])
infos[tele] = time_list
if str(call_type) == flag1:
infos[tele][0] = times
else:
infos[tele][1] = times
return infos
#將字符類型的通話時間轉換爲秒爲單位,返回int對象
def spliteTime(time_str):
hour_list = time_str.split('小時')
hour = 0
minute_string = ''
if len(hour_list) == 1:
minute_string = hour_list[0]
else:
minute_string = hour_list[1]
hour = int(hour_list[0])
#print hour
minute_list = minute_string.split('分')
minute = 0
sec_string = ''
if len(minute_list) == 1:
sec_string = minute_list[0]
else:
sec_string = minute_list[1]
minute = int(minute_list[0])
#print minute
sec_list = sec_string.split('秒')
sec = int(sec_list[0])
#print sec
return hour*3600+minute*60+sec
上述爲代碼一角,本着模塊化的精神,本項目將重要的功能已函數形式單獨整理,主要有如下幾個函數:
- def parseHTML(filename): #解析賬單html文件,返回信息dict對象,key爲電話號碼,value爲一個list對象,第一位是主叫時間,第二位是被叫時間
- def spliteTime(time_str): #將字符類型的通話時間轉換爲秒爲單位,返回int對象
- def cmnctTime(num_int): #將int對象的數據轉換爲string對象,返回string對象
- def sortInfos(infos): #將dict對象排序,排序規則爲通話時間的升序
- def getTop3Caller(infos): #返回通話時間最多的前三個號碼
四、實驗結果
通過執行腳本以後可以看到本月通訊排名前三位的是哪幾個號碼,這裏僅提供一個簡單的實例,如果大家有興趣,可以拿到數據以後做其他方面的分析,最後也可以通過圖表形式直觀的顯示出來,如果有心的話還可以分析每個月的賬單,將數據存入自己個人的數據庫中,方便以後有需要的時候讀取來分析。
博主自己的文件放在github上,地址如下:luuuyi/analysis_bill