python 之post、get與cookie實戰

  項目名稱:登錄考勤管理系統爬取我的考勤信息並寫入excel表格html

 

編寫目的:python

  公司常常要統計員工的考勤信息,而員工每次都要登錄考勤系統,再複製相關信息出來,貼到EXCEL,再轉給統計人員,統計人員再挨個覈對,麻煩無比,實在是看不下去了。我擦。。。。。ajax

  因爲登錄的是內網的考勤系統,出了公司就登錄不了,因此本篇文章僅作參考,來體驗一下cookie、post與get登錄使用。編程

 

先說用用到哪些知識吧:json

  一、tkinter Gui編程,寫爬蟲沒有GUI怎麼能行cookie

  二、cookiesession

  三、post,getapp

其實很少是吧,簡單。ide

 

要爬取一個網站,總得要矢爬的網站登錄地址,及登錄信息吧。分析一下看看。。。函數

好的,咱們獲取了以下信息:

  登錄地址:LoginUrl = 'http://17.xx.xx.xx/j_acegi_security_check'

  post提交:post_data = {'j_username':'your_username','j_password':'your_password'}

那就開工 ,寫一下登錄代碼吧

#!/usr/bin/env python
# _*_ coding:utf-8 _*_

import urllib
import urllib2
import cookielib

LoginUrl = 'http://17.xx.xx.xx/j_acegi_security_check'
post_data = {'j_username':'your_username','j_password':'your_password'}

# 定義一個類
class kaoqin_login(object):
def __init__(self):
self.cj = cookielib.CookieJar() # 初始化一個cookie補全,用於存儲cookie
self.handler = urllib2.HTTPCookieProcessor(self.cj) # 建立一個cookie處理器
self.opener = urllib2.build_opener(self.handler) # 建立一個功能強大的opener

def login(self,url,post): # post提交
post_data = urllib.urlencode(post) # 編碼post數據爲標準格式
req = urllib2.Request(url,post_data) # 作爲data參數傳給Request對象,此處也能夠寫成data=post_data
response = self.opener.open(req) # 登錄網站,獲取返回結果
print response.url

if __name__ == '__main__':
cls = kaoqin_login()
cls.login(LoginUrl,post_data)

返回信息以下:
http://17.xx.xx.xx/;jsessionid=7AC236C4B9C5E653208D59ECCE55E8EF

  

好,登錄成功了,以後怎麼辦呢?嗯,對了,找一下考勤頁面在哪裏,分析一下吧

瞧,真實頁面的信息就這些了。本身把url和post信息整理出來吧,注意,提交表單信息要寫成字典,url呢,問號以前的都是了。

示例代碼

#!/usr/bin/env python
# _*_ coding:utf-8 _*_

import urllib
import urllib2
import cookielib
import json

LoginUrl = 'http://17.xx.xx.xx/j_acegi_security_check'
post_data = {'j_username':'your_username','j_password':'your_password'}

# 定義一個類
class kaoqin_login(object):
    def __init__(self):
        self.cj = cookielib.CookieJar() # 初始化一個cookie補全,用於存儲cookie
        self.handler = urllib2.HTTPCookieProcessor(self.cj) # 建立一個cookie處理器
        self.opener = urllib2.build_opener(self.handler) # 建立一個功能強大的opener

    def login(self,url,post): # post提交
        post_data = urllib.urlencode(post) # 編碼post數據爲標準html格式
        req = urllib2.Request(url,post_data) # 作爲data參數傳給Request對象,由request作post數據隱式提交,此處也能夠寫成data=post_data
        response = self.opener.open(req) # 登錄網站,獲取返回結果
        print response.url

    def get_response(self,url,post):  # get方式提交數據
        get = urllib.urlencode(post)  # 將提交的數據編碼成html標準格式
        response = self.opener.open(url,get)  # 將標準的編碼數據放到url後面,變成真正的url地址
        try:
            JsData = json.loads(response.read())
            return JsData['datas']
        except Exception as e:
            return False

if __name__ == '__main__':
    cls = kaoqin_login()
    cls.login(LoginUrl,post_data)
    Login = 'http://17.xx.xx.xx/km/attendance/km_attendance_main/kmAttendanceMain.do'
    data ={
        'method':'data'
        ,'categoryId':''
        ,'q.s_raq':0.5949037911774411
        ,'pageno':2
        ,'rowsize':15
        ,'orderby':'fdAttendanceDate'
        ,'ordertype':'down'
        ,'s_ajax':'true'
    }
    jsdata = cls.get_response(Login,data)
    print jsdata

  好了,數據取到了,發一下所有的代碼吧.

上面的代碼是我重點想說的,下面的代碼就不是那麼重要了,關於excel的讀取,博客裏有詳細的解釋,GUI開發也有相關文檔。

 

#!/usr/bin/env python
# _*_ coding:utf-8 _*_
import urllib
import urllib2
import cookielib
import json,re,time

'''
由於腳本只取了前4頁數據,因此最好用來爬取本月的考勤信息
如需爬取其它月的信息,須要更改代碼
for i in range(1,5)  將5改成更大,最大15

'''

# ==============框口區==================
from Tkinter import *
from ScrolledText import ScrolledText
import tkFileDialog
root = Tk()
root.iconbitmap('../data/spider_128px_1169260_easyicon.net.ico')
root.title('郵儲我的考勤記錄爬蟲')
# 第一行
Label(root,text='考勤日期',fg='#8F8C8F').grid(row=0,column=0)
var_date1 = StringVar()
var_date1.set('2016-01-01')
var_date2 = StringVar()
var_date2.set('2016-01-31')
date1 = Entry(root,fg='red',bg='#FFFACD',textvariable=var_date1)
date1.grid(row=0,column=1)
Label(root,text='至',fg='#8F8C8F').grid(row=0,column=2)
date2 =Entry(root,fg='red',bg='#FFFACD',textvariable=var_date2)
date2.grid(row=0,column=3)
# 第二行
Label(root,text='用戶密碼文件',fg='#8F8C8F').grid(row=1,column=0)
var = StringVar()
def get_file():
    filename = tkFileDialog.askopenfilename(initialdir='c:')
    var.set(filename)
def get_file_des():
    filename = tkFileDialog.askopenfilename(initialdir='c:')
    ent_des.set(filename)
var.set(r'C:\spider_dev\data\kaoqin_user_pwd.txt')
Ent = Entry(root,textvariable=var).grid(row=1,column=1)
Button(root,text='選擇文件',command=get_file,fg='#006400').grid(row=1,column=2)
ent_des = StringVar()
timpsta = '%d'%(time.time()*1000)
ent_des.set(r'C:\spider_dev\data\kaoqin_%s.xls'%str(timpsta))
Ent_d = Entry(root,textvariable=ent_des).grid(row=2,column=1,sticky=N)
Button(root,text='目標文件',command=get_file_des,fg='#006400').grid(row=2,column=2,sticky=N)

T_logi_info = ScrolledText(root,width=20)
T_logi_info.grid(row=2,column=0)

# 標籤
v_lable = StringVar()
v_lable.set('錯誤記錄...')
Label(root,textvariable=v_lable,fg='red').grid(row=3,column=0)
# 信息框
text = ScrolledText(root,bg='#87CEFA')
text.grid(row=0,column=4,rowspan=3)

# ==============框口區==================

# --------------爬蟲區-----------------
class kaoqin_login(object):
    def __init__(self):
        self.cj = cookielib.CookieJar()
        self.handler = urllib2.HTTPCookieProcessor(self.cj)
        self.opener = urllib2.build_opener(self.handler)

    def login(self,url,post):
        post_data = urllib.urlencode(post)
        req = urllib2.Request(url,post_data)
        response = self.opener.open(req)
        if response.code == 200:
            return True
        else:
            return False

    def get_response(self,url,post):
        get = urllib.urlencode(post)
        response = self.opener.open(url,get)
        try:
            JsData = json.loads(response.read())
            return JsData['datas']
        except Exception as e:
            return False

    def post_page(self,pages):
        get={
            'method':'data'
            ,'categoryId':''
            ,'q.s_raq':0.9518796035349586
            ,'pageno':pages
            ,'rowsize':15
            ,'orderby':'fdAttendanceDate'
            ,'ordertype':'down'
            ,'s_ajax':'true'
        }
        return get

    def get_data_file(self,filename):
        with open(filename,'rb') as f:
            data = f.read().split('\r\n')
            return data

# --------------爬蟲區-----------------

# <------------Excel文件數據寫入-------->
from openpyxl.workbook import Workbook
from openpyxl.writer.excel import ExcelWriter
from openpyxl.cell import get_column_letter

wb = Workbook()
ew = ExcelWriter(workbook=wb)
ws = wb.worksheets[0]
ws.title = u'第一個sheet'

# 數據開始寫入的行、列、無組數據及文件名
def write_2_excel(r,c,t_data,FileName):
    i = r
    for record in t_data:
        for x in range(c,len(record)+c):
            col = get_column_letter(x)
            ws.cell('%s%s'%(col,i)).value ='%s'%record[x-c]
        i+=1
    ew.save(filename=FileName)
# <------------Excel文件數據寫入-------->

# ************主函數*****************
if __name__ == '__main__':
    def Spider():
        #初始化實例
        cls = kaoqin_login()
        if var.get():
            List_username = cls.get_data_file(var.get())
        else:
            v_lable.set('密碼文件對嗎???')
        #出勤狀態,如正常、遲到
        Real_Data = []
        #按用戶獲取數據
        for each_user in List_username:
            #標題數據,好比excel的頭部,日期,星期、上下午
            Title_Data = []
            #網站登錄用戶信息
            Pno,Pname,username,password = each_user.split(',')[0],each_user.split(',')[1],each_user.split(',')[2],each_user.split(',')[3]
            LoginUrl = 'http://17.xx.xx.xx/j_acegi_security_check'
            LoginPost ="{'j_username':'%s','j_password':'%s'}"%(username,password)
            LoginPost = eval(LoginPost)
            if cls.login(LoginUrl,LoginPost):
                #進入考勤頁面
                Kq_Url = 'http://17.xx.xx.xx/km/attendance/km_attendance_main/kmAttendanceMain.do'
                tmp1=[]
                tmp2=[]
                tmp3=[]
                tmp4=[]
                tmp4.append(Pno)
                tmp4.append(Pname)
                #考勤post列表,第一頁到第四頁數據
                for i in range(1,5):
                    jsret = cls.get_response(Kq_Url,cls.post_page(i))
                    if jsret:
                        pass
                    else:
                        T_logi_info.insert(END,Pname+'登錄失敗'+ '\n')
                        T_logi_info.see(END)
                        break
                    #對考勤數據處理
                    for each_day in jsret:
                        v_date=v_week=v_Bc=v_status=v_name=''
                        start_date = var_date1.get()
                        end_date = var_date2.get()
                        if start_date and end_date:
                            for item_dic in each_day:
                                col = item_dic['col']
                                if col == 'fdAttendanceDate':
                                    v_date = item_dic['value'].strip()
                                if col == 'fdWeek':
                                    v_week = item_dic['value'].strip()
                                if col == 'fdBc':
                                    v_Bc = item_dic['value'].strip()
                                if col == 'fdStatus':
                                    v_status = item_dic['value'].strip()
                                    v_status = re.search('>(.*?)<',v_status).group(1)
                                if col == 'fdPerson.fdName':
                                    v_name = item_dic['value']

                            if v_date >= start_date and v_date <= end_date:
                                tmp1.append(v_date)
                                tmp2.append(v_week)
                                tmp3.append(v_Bc)
                                tmp4.append(v_status)
                                text.insert(END, v_name +',' + v_date+','+v_week+','+v_Bc+','+v_status+'\n')
                                text.see(END)
                                text.update()
                        else:
                            v_lable.set('時間不對吧...')
                            pass
                Title_Data.append(tmp1)
                Title_Data.append(tmp2)
                Title_Data.append(tmp3)
                Real_Data.append(tmp4)
        write_2_excel(1,3,Title_Data,ent_des.get())
        write_2_excel(4,1,Real_Data,ent_des.get())

    #第三行
    Button(root,text='開始爬取',fg='#3CB371',command=Spider).grid(row=3,column=4)
    root.mainloop()

  好了,看看一下實際效果吧

 

 

相關文章
相關標籤/搜索