您的位置:軟件測(cè)試 > 開源軟件測(cè)試 > 開源功能測(cè)試工具 > Selenium
使用Selenium找出外賣點(diǎn)餐次數(shù)多的10個(gè)顧客
作者:網(wǎng)絡(luò)轉(zhuǎn)載 發(fā)布時(shí)間:[ 2016/8/1 17:58:20 ] 推薦標(biāo)簽:Selenium

  大鍋在做外賣,給我說能否統(tǒng)計(jì)出這半年點(diǎn)餐次數(shù)多的10個(gè)顧客,我不知道APP本身是否有這個(gè)功能,想了下近用selenium較多,用selenium嘗試下吧。
  1、定義一個(gè)類,這里先描述需要的屬性和方法,后面再依次具體分析:
1 class Order:
2     def __init__(self, url, username, password):
3         # URL以及用戶名和密碼
4         self.url = url
5         self.username = username
6         self.password = password
7         # webdriver對(duì)象
8         self.driver = None
9         # 日期列表
10         self.dateList = list()
11         # 存儲(chǔ)訂單的dict
12         self.orderDict = dict()
13
14     # 設(shè)置訂單的時(shí)間范圍
15     def setDate(self, startdate, enddate):
16         pass
17     # 登錄
18     def login(self):
19         pass
20     # 退出
21     def logout(self):
22         pass
23     # 切換到歷史訂單頁面
24     def switchToHistoryOrder(self):
25         pass
26     # 選擇一個(gè)時(shí)間范圍
27     def selectDate(self, startDate, endDate):
28         pass
29     # 訂單信息存入self.orderDict
30     def saveOrderIntoDict(self, tel, name, address):
31         pass
32     # 處理當(dāng)前頁面的訂單
33     def searchOrderListInCurrentPage(self):
34         pass
35     # 判斷是否還有下一頁
36     def hasNextPage(self):
37         pass
38     # 切換到下一頁
39     def enterNextPage(self):
40         pass
41     # 抓取設(shè)定日期范圍內(nèi)的所有訂單
42     def getAllOrders(self, startdate, enddate):
43         pass
44     # 篩選出點(diǎn)餐次數(shù)排名前N的顧客
45     def getTopN(self, n=10):
46         pass
  2、設(shè)置欲篩選的訂單日期范圍
  這里設(shè)置的日期格式必須是'yyyy-mm-dd',由于該網(wǎng)站在查詢訂單的時(shí)候,時(shí)間范圍必須是7天以內(nèi),比如直接查詢2016-01-01到2016-02-28之間的訂單是不行的,因此需要先將這段時(shí)間以7天為周期分割為多個(gè)時(shí)間段,然后再分段處理;
  分割后的時(shí)間段存放在self.dateList中,list的元素為tuple,一個(gè)tuple表示一個(gè)時(shí)間段:
1 # 設(shè)置訂單的時(shí)間范圍,日期格式必須是'yyyy-mm-dd'
2     # 然后以7天為周期,將日期范圍分割成list,list的每個(gè)元素為一個(gè)tuple,分別存放起止日期
3     # 例如 [('2016-01-01', '2016-01-07'), ('2016-01-08', '2016-01-14')]
4     def setDate(self, startdate, enddate):
5         # 通過正則表達(dá)式檢查日期格式
6         pdate = re.compile('d{4}-d{2}-d{2}')
7         if pdate.search(startdate) and pdate.search(enddate):
8             # 轉(zhuǎn)換為datetime格式,便于日期計(jì)算
9             startdate = datetime.datetime.strptime(startdate, '%Y-%m-%d')
10             enddate = datetime.datetime.strptime(enddate, '%Y-%m-%d')
11
12             # 將日期范圍以7天為周期分割
13             days = (enddate - startdate).days + 1
14             cnt = days / 7
15             left = days - 7*cnt
16             for x in range(cnt):
17                 d1 = (startdate + datetime.timedelta(days=7*x))
18                 d2 = (d1 + datetime.timedelta(days=6))
19                 # datetime轉(zhuǎn)換為str,再加入list中
20                 self.dateList.append((d1.strftime('%Y-%m-%d'), d2.strftime('%Y-%m-%d')))
21             if left > 0:
22                 self.dateList.append(((startdate+datetime.timedelta(days=cnt*7)).strftime('%Y-%m-%d'), enddate.strftime('%Y-%m-%d')))
23         else:
24             print u'日期格式錯(cuò)誤,必須為yyyy-mm-dd格式'
25             exit(1)
  測(cè)試一下:
  1 order = Order('url', 'username', 'password')
  2 order.setDate('2016-01-01', '2016-01-31')
  3 print order.dateList
  4 #輸出為
  5 [('2016-01-01', '2016-01-07'), ('2016-01-08', '2016-01-14'), ('2016-01-15', '2016-01-21'), ('2016-01-22', '2016-01-28'), ('2016-01-29', '2016-01-31')]
  3、登錄與退出
  登錄比較簡(jiǎn)單,直接過id定位到用戶名和密碼輸入框,然后定位登錄按鈕點(diǎn)擊登錄即可,只是定位到輸入框后需要先將框內(nèi)的提示信息清除掉。
  退出更簡(jiǎn)單了,直接關(guān)閉瀏覽器即可。
1  # 登錄
2     def login(self):
3         # 采用chrome瀏覽器
4         self.driver = webdriver.Chrome()
5         # 窗口大化
6         self.driver.maximize_window()
7         # 設(shè)置超時(shí)時(shí)間
8         self.driver.implicitly_wait(10)
9         self.driver.get(self.url)
10
11         # 查找用戶名輸入框,先清除提示信息,再輸入用戶名
12         usr = self.driver.find_element_by_id('account-name')
13         usr.clear()
14         usr.send_keys(self.username)
15
16         # 查找密碼輸入框,先清除提示信息,再輸入密碼
17         passwd = self.driver.find_element_by_id('account-password')
18         passwd.clear()
19         passwd.send_keys(self.password)
20
21         # 點(diǎn)擊登錄
22         self.driver.find_element_by_id('account-login-btn').click()
23         return
24
25     # 退出
26     def logout(self):
27         self.driver.close()
28         return
  4、切換到歷史訂單頁面
  登錄后點(diǎn)擊訂單管理,然后點(diǎn)擊歷史訂單,切換到歷史訂單頁面,如下圖所示:

  由于“訂單管理”和“歷史訂單”這兩個(gè)元素都是超鏈接,因此可以直接用超鏈接定位:
1     # 切換到歷史訂單頁面
2     def switchToHistoryOrder(self):
3         self.driver.find_element_by_partial_link_text(u'訂單管理').click()
4         self.driver.find_element_by_partial_link_text(u'歷史訂單').click()
5
6         # 切換frame,因?yàn)楹罄m(xù)的所有處理都是在hashframe中,所有在這里切換
7         self.driver.switch_to.frame('hashframe')
8         return
  注意該方法后有個(gè)切換frame的操作,下一步知道為什么要添加這句了。
  5、選擇訂單日期范圍,篩選出該日期范圍內(nèi)的訂單
  注意這里的日期范圍與第二步設(shè)置的日期范圍不一樣,第二步設(shè)置的日期范圍是我們想要篩選的起止時(shí)間,這里的日期范圍是第二步分割出來的其中一段。
  與用戶名密碼框一樣,這里的日期輸入框也可采用id定位,同樣定位后需要先將輸入框預(yù)置的日期清除:
1     # 在頁面上設(shè)置訂單的時(shí)間范圍,并篩選出該時(shí)間范圍內(nèi)的所有訂單
2     # 調(diào)用該方法時(shí),參數(shù)需從self.dateList中獲取,dateList中的每一個(gè)tuple對(duì)應(yīng)一組參數(shù)
3     def selectDate(self, startDate, endDate):
4         # 設(shè)置起始日期
5         s = self.driver.find_element_by_id('J-start')
6         s.clear()
7         s.send_keys(startDate)
8
9         # 設(shè)置終止日期
10         e = self.driver.find_element_by_id('J-end')
11         e.clear()
12         e.send_keys(endDate)
13         return
  這里說一下第4步中的切換frame,我們先將切換frame這一句注釋掉,然后來測(cè)試下選擇日期:
  1  order.login()
  2  order.switchToHistoryOrder()
  3  order.selectDate('2016-07-01', '2016-07-02')
  4 # 輸出
  5 selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"id","selector":"J-start"}
  可以看到出錯(cuò)了,提示沒有需要定位的元素,為什么呢?通過HTML代碼可以看到,這里采用了框架frame,所定位的元素在frame里面,如下所示:

  因此需要先切換到該frame里面,然后才能定位到frame里面的元素;由于后續(xù)所有的訂單操作都在該frame里面,因此在上一步切換到歷史訂單頁面后,先切換到該frame,便于后續(xù)操作。
  6、將訂單信息存入self.orderDict
  該方法是下一步需要調(diào)用的,因此這里先實(shí)現(xiàn)。每一個(gè)訂單我們只需3個(gè)信息:姓名、電話、地址,然后將這三個(gè)元素表示的訂單存入orderDict,但是由于我們要統(tǒng)計(jì)出點(diǎn)餐次數(shù)多的10個(gè)顧客,
  因此還要保存每個(gè)顧客的點(diǎn)餐次數(shù)。這里dict的元素格式為{'tel': ['name', 'address', cnt]},由于姓名可能重復(fù),因此采用了電話作為key值。如果某個(gè)顧客第一次點(diǎn)餐,保存時(shí)將點(diǎn)餐次數(shù)cnt初始化為1;
  如果不是第一次點(diǎn)餐,則將該顧客對(duì)應(yīng)的cnt值加1。
1     # 將tel, name, address表示的訂單信息存入self.orderDict
2     # self.orderDict元素的形式為 {'tel': ['name', 'address', cnt]}
3     # 以電話號(hào)碼為key,以姓名、地址、點(diǎn)餐次數(shù)組成的list為value
4     # 當(dāng)要添加的key不存在時(shí),將此訂單加入orderDict,并且cnt初始化為1
5     # 當(dāng)要添加的key已經(jīng)存在時(shí),直接將該key對(duì)應(yīng)的cnt加1
6     def saveOrderIntoDict(self, tel, name, address):
7         if self.orderDict.has_key(tel):
8             self.orderDict[tel][2] += 1
9         else:
10             self.orderDict[tel] = [name, address, 1]
11         return

上一頁12下一頁
軟件測(cè)試工具 | 聯(lián)系我們 | 投訴建議 | 誠(chéng)聘英才 | 申請(qǐng)使用列表 | 網(wǎng)站地圖
滬ICP備07036474 2003-2017 版權(quán)所有 上海澤眾軟件科技有限公司 Shanghai ZeZhong Software Co.,Ltd