你真知道自己加了多少班嗎?來(lái)來(lái)來(lái)粱侣,用Python分析一下考勤數(shù)據(jù)就知道了

前段時(shí)間給同事做Python爬蟲(chóng)技術(shù)分享羊壹,為了分享的效果以及聽(tīng)眾的興趣,寫(xiě)了一個(gè)爬取考勤數(shù)據(jù)的小爬蟲(chóng)齐婴。內(nèi)容比較簡(jiǎn)單油猫,以下做一個(gè)梳理:

一、問(wèn)題分析

先梳理下查詢考勤的流程:

  1. 登錄公司內(nèi)網(wǎng)的系統(tǒng)
  2. 切換到考勤查詢頁(yè)面
  3. 根據(jù)年份尔店、月份查詢對(duì)于的考勤數(shù)據(jù)即可

分析以上流程眨攘,主要解決兩個(gè)核心問(wèn)題即可:a. 賬號(hào)登錄 b. 找到考勤數(shù)據(jù)查詢的接口

二、解決登錄問(wèn)題

公司的考勤數(shù)據(jù)嚣州、人力系統(tǒng)鲫售、會(huì)議室等都在同一個(gè)系統(tǒng)里面,由于之前已經(jīng)用Selenium寫(xiě)過(guò)搶會(huì)議室的腳本该肴,所以登錄情竹、驗(yàn)證碼等問(wèn)題算是已經(jīng)解決了。
但是多想一步匀哄,要是每次爬個(gè)考勤秦效、調(diào)試都要祭出Selenium也有點(diǎn)麻煩的,所以...能不能再優(yōu)化下呢涎嚼?
...
當(dāng)然是有的阱州!

既然可以用Selenium登錄,就能得到登錄后的cookie法梯。理論上說(shuō)苔货,只要在cookie的過(guò)期時(shí)間內(nèi)都是可以實(shí)現(xiàn)免登錄的犀概。??
所以需要實(shí)現(xiàn)的工作是:
1、用Selenium模擬登錄夜惭,登錄成功后將cookie保存到本地姻灶;
2、拋棄Selenium诈茧,用Requests庫(kù)产喉,帶上前面的cookie訪問(wèn)網(wǎng)站即可。然后就能隨心所欲爬取數(shù)據(jù)了敢会。

說(shuō)干就干曾沈,以下是獲取登錄狀態(tài)cookie的實(shí)現(xiàn)代碼:

import time, os, json, requests,sqlite3
from selenium import webdriver
from time import sleep
from lib.mtHelper import MtHelper #自己封裝的關(guān)于驗(yàn)證碼識(shí)別、登錄等函數(shù)
from requests.cookies import RequestsCookieJar

#用selenium登錄系統(tǒng)走触,保存cookie到本地json文件晦譬。
def login_savecookie(user, password):
    driver = webdriver.Chrome()
    driver.maximize_window()
    driver.implicitly_wait(5)
    mtHelper = MtHelper(driver)
    driver.get('http://****.com')
    mtHelper.login_auoto(user, password, 15)#之前封裝過(guò)的登錄函數(shù),最多嘗試15次驗(yàn)證碼識(shí)別
    sleep(1)
    dict_cookie = driver.get_cookies()#登錄成功后獲取當(dāng)前的cookie
    json_cookie = json.dumps(dict_cookie)
    with open(path + "\cookies.json", "w+") as f:
        f.write(json_cookie)
    driver.quit()

#讀取本地json文件獲取cookie互广,用于requests
def parse_cookie():
    jar = RequestsCookieJar()
    with open(path + "\cookies.json", "r") as f:
        json_cookies = json.load(f)
    for cookie in json_cookies:
        jar.set(cookie['name'], cookie['value'])
    return jar

所以從理論上說(shuō)敛腌,在cookie過(guò)期時(shí)間以內(nèi),只用執(zhí)行一次Selenium登錄操作即可惫皱。之后的操作直接讀取本地的cookie數(shù)據(jù)像樊,攜帶它進(jìn)行request請(qǐng)求即可。這樣能大大減少調(diào)試旅敷、運(yùn)行的成本生棍。

三、考勤數(shù)據(jù)查詢接口

按照以往的經(jīng)驗(yàn)媳谁,凡是先按F12涂滴,觀察一下請(qǐng)求的內(nèi)容再說(shuō)。
先進(jìn)入考勤查詢系統(tǒng)晴音,調(diào)出控制臺(tái)后柔纵,用鼠標(biāo)點(diǎn)擊了一下2018年3月,立馬能看到以下請(qǐng)求(沒(méi)有截圖锤躁,就手敲了一遍搁料,實(shí)際數(shù)據(jù)做過(guò)隱私處理):

#post請(qǐng)求地址:
http://****/EMPL/s/WEBLIB_GP_PAY.ISCRIPT2.FieldFormula.IScript_getPayAbsenceList?MONTHCD=2018-3&EMPLID=111111
#參數(shù):
MONTHCD:2018-3
EMPLID:111111


#返回值(截取部分),Json格式:
"{"code":"success","list_data":
[{"ATT_RESULT_COMMENT":"無(wú)請(qǐng)休假","ATT_END_TIME":"19:29:31","ATT_DATE":"2018-03-01","ATT_BGN_TIME":"08:58:40","EMPLID":"111111","DAY_OFWEEK":"星期四","ATT_RESULT":"無(wú)異常"},
{"ATT_RESULT_COMMENT":"無(wú)請(qǐng)休假","ATT_END_TIME":"18:57:48","ATT_DATE":"2018-03-02","ATT_BGN_TIME":"09:07:43","EMPLID":"111111","DAY_OFWEEK":"星期五","ATT_RESULT":"無(wú)異常"}]}"

根據(jù)以上內(nèi)容不難推測(cè)系羞,要想獲取考勤數(shù)據(jù)郭计,只需找到該post請(qǐng)求的參數(shù)規(guī)律即可。至于返回值椒振,明顯是按照工作日排序的昭伸,只需解析該Json即可得到想要的數(shù)據(jù)。

請(qǐng)求參數(shù)分析:
MONTHCD不用說(shuō)澎迎,肯定是指查詢考勤的年月份勋乾;至于EMPLID宋下,雖然不知道具體是什么嗡善,但該變量名明顯是類似員工工號(hào)的東西辑莫,應(yīng)該是唯一的。再多嘗試了幾次罩引,果不其然各吨,它是不變的。
搞定T怼=已选!

動(dòng)手來(lái)實(shí)現(xiàn)它吧:

#獲取某月的考勤數(shù)據(jù)
#month為需要獲取的月份剔桨,employeeID為員工工號(hào)屉更,jar為cookie數(shù)據(jù)。也就是上例中從json文件中獲取的cookie信息
def request_and_get_json(month = "2018-3", employeeID = "111111", jar = None):
    url = "http://***/EMPLOYEE/EMPL/s/WEBLIB_GP_PAY.ISCRIPT2.FieldFormula.IScript_getPayAbsenceList?MONTHCD=%s&EMPLID=%s" % (month, employeeID)
    print u"正在獲取%s的數(shù)據(jù)!"%month
    response = requests.get(url, cookies = jar)
    text = response.text
    js = json.dumps(text,encoding='utf-8',ensure_ascii=False)
    js = json.loads(js)
    return js

三洒缀、數(shù)據(jù)存儲(chǔ)

前面已經(jīng)找到查詢接口的規(guī)律了瑰谜,所以用個(gè)循環(huán)遍歷就能獲取任意時(shí)間段的考勤數(shù)據(jù)了。但是僅停留于此是不夠的树绩,接下來(lái)要考慮下數(shù)據(jù)存儲(chǔ)萨脑,只有存儲(chǔ)為合理的數(shù)據(jù)結(jié)構(gòu)后才方便后面的數(shù)據(jù)分析。

數(shù)據(jù)存儲(chǔ)的方式很多饺饭,比如針對(duì)少量數(shù)據(jù)可以存為本地Json渤早、txt、Excel等文件瘫俊,數(shù)據(jù)量大也可以考慮數(shù)據(jù)庫(kù)鹊杖。
此處的考勤數(shù)據(jù)不多,不到1000條扛芽。為了便于數(shù)據(jù)的篩選骂蓖,以及減少環(huán)境搭建成本,采用sqlite3存儲(chǔ)胸哥。
先使用pip install sqlite3命令安裝sqlite3庫(kù)涯竟,接下來(lái)就是實(shí)現(xiàn):

#保存數(shù)據(jù)到數(shù)據(jù)庫(kù)
#sql格式:"insert into info(date, week, emplid, beginTime, endTime, comment, result) values ('%s', '%s', '%s', '%s', '%s', '%s', '%s')" % (date, week, emplid, beginTime, endTime, comment, result)
def save_to_db(sql):
    conn = sqlite3.connect(path + '\db\clockData.db')
    cursor = conn.cursor()
    cursor.execute('CREATE TABLE IF NOT EXISTS info (date text(20) primary key, week text(20), emplid text(20), beginTime text(20), endTime text(20), comment text(20), result text(20))')
    cursor.execute(sql)
    cursor.close()
    conn.commit()
    conn.close()

至此,將以上部分串聯(lián)起來(lái)空厌,就能爬取考勤數(shù)據(jù)了庐船!
下面就看看爬取的成果:


爬取下來(lái)的考勤數(shù)據(jù)

四、數(shù)據(jù)分析

當(dāng)然嘲更,數(shù)據(jù)分析這個(gè)范疇實(shí)在是太大了筐钟,在此只做個(gè)簡(jiǎn)單的數(shù)據(jù)統(tǒng)計(jì)(常用的sql查詢命令),用于娛樂(lè)??赋朦,順便模仿一波網(wǎng)易云的情懷文案:


考勤數(shù)據(jù)分析

不說(shuō)了篓冲,我要找老板加薪去李破!??????

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市壹将,隨后出現(xiàn)的幾起案子嗤攻,更是在濱河造成了極大的恐慌,老刑警劉巖诽俯,帶你破解...
    沈念sama閱讀 221,198評(píng)論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件妇菱,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡暴区,警方通過(guò)查閱死者的電腦和手機(jī)闯团,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)仙粱,“玉大人房交,你說(shuō)我怎么就攤上這事》ジ睿” “怎么了候味?”我有些...
    開(kāi)封第一講書(shū)人閱讀 167,643評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)口猜。 經(jīng)常有香客問(wèn)我负溪,道長(zhǎng),這世上最難降的妖魔是什么济炎? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,495評(píng)論 1 296
  • 正文 為了忘掉前任川抡,我火速辦了婚禮,結(jié)果婚禮上须尚,老公的妹妹穿的比我還像新娘崖堤。我一直安慰自己,他們只是感情好耐床,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布密幔。 她就那樣靜靜地躺著,像睡著了一般撩轰。 火紅的嫁衣襯著肌膚如雪胯甩。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,156評(píng)論 1 308
  • 那天堪嫂,我揣著相機(jī)與錄音偎箫,去河邊找鬼。 笑死皆串,一個(gè)胖子當(dāng)著我的面吹牛淹办,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播恶复,決...
    沈念sama閱讀 40,743評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼怜森,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼速挑!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起副硅,我...
    開(kāi)封第一講書(shū)人閱讀 39,659評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤姥宝,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后想许,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體伶授,經(jīng)...
    沈念sama閱讀 46,200評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片茎芭。...
    茶點(diǎn)故事閱讀 40,424評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡纸兔,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出诸迟,到底是詐尸還是另有隱情茸炒,我是刑警寧澤,帶...
    沈念sama閱讀 36,107評(píng)論 5 349
  • 正文 年R本政府宣布阵苇,位于F島的核電站壁公,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏绅项。R本人自食惡果不足惜紊册,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望快耿。 院中可真熱鬧囊陡,春花似錦、人聲如沸掀亥。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,264評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)搪花。三九已至遏片,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間撮竿,已是汗流浹背吮便。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,390評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留倚聚,地道東北人线衫。 一個(gè)月前我還...
    沈念sama閱讀 48,798評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像惑折,于是被迫代替她去往敵國(guó)和親授账。 傳聞我的和親對(duì)象是個(gè)殘疾皇子枯跑,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 目錄Cookie機(jī)制什么是CookieCookie的不可跨域名性Unicode編碼:保存中文BASE64編碼:保存...
    Tomatoro閱讀 16,952評(píng)論 7 186
  • 會(huì)話(Session)跟蹤是Web程序中常用的技術(shù),用來(lái)跟蹤用戶的整個(gè)會(huì)話白热。常用的會(huì)話跟蹤技術(shù)是Cookie與Se...
    chinariver閱讀 5,627評(píng)論 1 49
  • 轉(zhuǎn)載敛助,覺(jué)得這篇寫(xiě) SQLAlchemy Core,寫(xiě)得非常不錯(cuò)屋确。不過(guò)后續(xù)他沒(méi)寫(xiě)SQLAlchemy ORM... ...
    非夢(mèng)nj閱讀 5,420評(píng)論 1 14
  • ??支持離線 Web 應(yīng)用開(kāi)發(fā)是 HTML5 的另一個(gè)重點(diǎn)攻臀。 ??所謂離線 Web 應(yīng)用焕数,就是在設(shè)備不能上網(wǎng)的情況...
    霜天曉閱讀 1,042評(píng)論 0 2
  • (仄起平收,平水韻八庚) 天下快刀居難敵刨啸, 江湖夜夢(mèng)冷晶瑩堡赔。 天涯海角心孤獨(dú), 暖盡黃花祭月明设联。
    摩詰梵心閱讀 665評(píng)論 0 5