python网络爬虫进阶day02

  2019.5.25,今天用selenium+chromedriver做了一个12306抢票小爬虫,总共100+行代码,写的真费劲,看来还是没学到家,话不多说,首先看一下README:

12306抢票功能:
通过手动登录,手动填写出发地,目的地,出发日期,然后自动完成抢票

程序流程:
- 1、首先进入登录界面(logging_page),然后等待用户登录。
- 2、在登录成功页面处“购买”中找到“单程”,执行点击事件,进入余票查询页面。
- 3、等待用户在网页中手动输入出发地,目的地,出发日期,然后判断“查询”按钮是否可以点击,若可以,执行点击事件,否则等待。
- 4、执行“查询”按钮后,等待页面显示车次信息,找到对应的车次,判断有无票,有,则找到“预定”按钮,执行点击事件。
- 5、进入选择乘客信息页面,找到对应乘客的CheckBox,执行点击事件。然后找到“提交订单”按钮,执行点击事件。
- 6、出现确认信息页面,找到“确认”按钮,执行点击事件。
- 7、完成抢票。

代码里也写了很清楚的注释了,上代码:
  1 # Author:K
  2 from selenium import webdriver
  3 from selenium.webdriver.support.ui import WebDriverWait
  4 from selenium.webdriver.support import expected_conditions as EC
  5 from selenium.webdriver.common.by import By
  6 
  7 class TicketGrabbing(object):
  8     def __init__(self):
  9         self.driver = webdriver.Chrome(executable_path = 'D:\ChromeDriver\chromedriver.exe')
 10         self.login_url = 'https://kyfw.12306.cn/otn/login/init'  # 这个不行'https://kyfw.12306.cn/otn/resources/login.html'
 11         self.index_url = 'https://kyfw.12306.cn/otn/view/index.html'
 12         self.order_url = 'https://kyfw.12306.cn/otn/leftTicket/init?linktypeid=dc'
 13         self.commit_url = 'https://kyfw.12306.cn/otn/confirmPassenger/initDc'
 14 
 15 
 16     def run(self):
 17         self._login()
 18         self._order_ticket()
 19 
 20 
 21     def _wait_input(self):
 22         self.from_station = input('请输入出发地:')
 23         self.to_station = input('请输入目的地:')
 24         self.date = input('请输入出发日期(格式为yyyy-mm-dd):')
 25         self.trains = input('请输入车次(多个车次用英文逗号隔开):').split(',')
 26         self.passengers = input('请输入乘客(多个乘客用英文逗号隔开):').split(',')
 27         # 等待出发地输入
 28         WebDriverWait(self.driver,300).until(
 29             # 因为此标签'input'是单标签,所以要用text_to_be_present_in_element_value,
 30             # 如果是双标签的话就用text_to_be_present_in_element
 31             EC.text_to_be_present_in_element_value((By.ID,'fromStationText'),self.from_station)
 32         )
 33         # 等待目的地输入
 34         WebDriverWait(self.driver, 300).until(
 35             EC.text_to_be_present_in_element_value((By.ID, 'toStationText'), self.to_station)
 36         )
 37         # 等待出发日期输入
 38         WebDriverWait(self.driver, 300).until(
 39             EC.text_to_be_present_in_element_value((By.ID, 'train_date'), self.date)
 40         )
 41         # 等待查询按钮是否可用
 42         WebDriverWait(self.driver,300).until(
 43             EC.element_to_be_clickable((By.ID,'query_ticket'))
 44         )
 45 
 46 
 47 
 48     def _login(self):
 49         self.driver.get(self.login_url)
 50         # 登录成功后,等待页面跳转至首页
 51         WebDriverWait(self.driver,300).until(
 52             EC.url_to_be(self.index_url)
 53         )
 54         print('登录成功!')
 55         # 等待是否到达订票页面
 56         WebDriverWait(self.driver,300).until(
 57             EC.url_to_be(self.order_url)
 58         )
 59 
 60 
 61     def _order_ticket(self):
 62         self._wait_input()
 63         query_button = self.driver.find_element_by_id('query_ticket')
 64         query_button.click()
 65         # 等待车次信息出现
 66         WebDriverWait(self.driver,300).until(
 67             EC.presence_of_element_located((By.XPATH,'.//tbody[@id="queryLeftTable"]/tr'))
 68         )
 69         # 获取车次信息
 70         tr_list = self.driver.find_elements_by_xpath('.//tbody[@id="queryLeftTable"]/tr[not(@datatran)]')
 71         # print(tr_list)  # 测试
 72         for tr in tr_list:
 73             train_number = tr.find_element_by_class_name('number').text
 74             if train_number in  self.trains:
 75                 tickets_left = tr.find_element_by_xpath('./td[4]').text
 76                 if tickets_left == '' or tickets_left.isdigit:
 77                     # print(train_number,tickets_left)  # 测试
 78                     # print('='*30)  # 测试
 79                     book_button = tr.find_element_by_class_name('btn72')
 80                     book_button.click()
 81                     # 等待页面是否跳转到提交订单页面,并且出现乘客信息
 82                     WebDriverWait(self.driver,300).until(
 83                         EC.presence_of_element_located((By.XPATH,'.//ul[@id="normal_passenger_id"]/li'))
 84                     )
 85                     # 找到所有乘客信息
 86                     li_list = self.driver.find_elements_by_xpath('.//ul[@id="normal_passenger_id"]/li')
 87                     for li in li_list:
 88                         if li.text in self.passengers:
 89                             print(li.text)
 90                             # 找到乘客对应的CheckBox,并执行点击事件
 91                             check_box = li.find_element_by_class_name('check')
 92                             check_box.click()
 93                     # 找到提交订单按钮,并执行点击事件
 94                     commit_button = self.driver.find_element_by_id('submitOrder_id')
 95                     commit_button.click()
 96                     # 等待确认订单弹窗出现
 97                     WebDriverWait(self.driver,300).until(
 98                         EC.presence_of_element_located((By.CLASS_NAME,'dhtmlx_wins_body_outer'))
 99                     )
100                     # 等待确认按钮加载
101                     WebDriverWait(self.driver, 300).until(
102                         EC.presence_of_element_located((By.ID, 'qr_submit_id'))
103                     )
104                     # 找到确认按钮,并执行点击事件
105                     confirm_button = self.driver.find_element_by_id('qr_submit_id')
106                     confirm_button.click()
107                     # 因为确认按钮可能会未被点击,所以用一个while循环点击,若正确点击了确认按钮,则调出while循环
108                     while confirm_button:
109                         confirm_button.click()
110                         confirm_button = self.driver.find_element_by_id('qr_submit_id')
111                     # 打开一个新的窗口,并将driver转换成新的窗口
112                     self.driver.execute_script('window.open("%s")' % self.order_url)
113                     self.driver.switch_to.window(self.driver.window_handles[1])
114                     # 再次等待车次信息出现
115                     WebDriverWait(self.driver, 300).until(
116                         EC.presence_of_element_located((By.XPATH, './/tbody[@id="queryLeftTable"]/tr'))
117                     )
118 
119 
120 if __name__ == '__main__':
121     spider = TicketGrabbing()
122     spider.run()
12306抢票案例

  测试的时候用的4G网,感觉用4G网更快一些,不知道是不是错觉。。。。

    好了,这个小案例的功能还有待完善,欢迎补充!

猜你喜欢

转载自www.cnblogs.com/KisInfinite/p/10924698.html