需求:用12306进行买票
第一步 登陆
第二步 车次及余票查询
- 由个人详情页面跳转车次界面
- 先要获取所有的站点以及对应的编号–>把数数据存到字典当中 key name value code
- 输入出发地 输入目的地 输入出发日期
- 1 定位input标签
- 2 获取编号
- 3 driver.excute_script()方法来设置隐藏标签 code设置到value里面
- 4 定位查询按钮 点击查询 出现车次列表
第三步 解析车次列表
显式等待车次列表
车次列表分析 tbody标签下面的 tr标签 过滤没有车次信息的tr标签 xpath (not )
替换 拼接的方式把车次信息的数据放到了一个列表里面
init方法里面初始化了一个用户的车次 先获得了这个车次 做了一个判断 判断这个数据在我们初始
化信息里面
然后进行 我们想要买的车次的数据解析
第四步 确认乘客信息
显式等待乘客信息页面
显示等待是否乘客标签加载出来了
init 方法里面 初始化了乘客信息 [ xxx ,xxx]
确定席位 select标签 Select类 下标 value 操作下拉菜单
二等座如果没有了 NoSuchElementException try catch 点击提交按钮
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
| import requests from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC import csv from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import Select from selenium.common.exceptions import NoSuchElementException from selenium.common.exceptions import ElementNotVisibleException
driver = webdriver.Chrome() class TrainSpider(): login_url = 'https://kyfw.12306.cn/otn/resources/login.html' personal_url = 'https://kyfw.12306.cn/otn/view/index.html' Ticket_url = 'https://kyfw.12306.cn/otn/leftTicket/init?linktypeid=dc' confirm_url = 'https://kyfw.12306.cn/otn/confirmPassenger/initDc' def __init__(self,fsta,tosta,tdata,trains,passengers): '''
:param fsta: 出发地 :param tosta: 目的地 :param tdata: 日期 :param trains: 车次及席位 :param passengers: 乘客信息 ''' self.fsta = fsta self.tosta = tosta self.data = tdata self.trains = trains self.passengers = passengers self.selected_number = None self.station_code = {} self.init_station_code()
def init_station_code(self): with open('person.csv', 'r', encoding='utf-8') as f: reader = csv.DictReader(f) for i in reader: name = i['name'] code = i['code'] self.station_code[name] = code def login(self): driver.get(self.login_url) WebDriverWait(driver,1000).until( EC.url_contains(self.personal_url) ) print('登陆成功') def Ticket(self): driver.get(self.Ticket_url) from_station_input = driver.find_element_by_id('fromStation') from_station_code = self.station_code[self.fsta] driver.execute_script('arguments[0].value="%s"'%from_station_code,from_station_input) to_station_input = driver.find_element_by_id('toStation') to_station_code = self.station_code[self.tosta] driver.execute_script('arguments[0].value="%s"' % to_station_code, to_station_input) train_date_input = driver.find_element_by_id('train_date') driver.execute_script('arguments[0].value="%s"' % self.data, train_date_input) btn = driver.find_element_by_id('query_ticket') btn.click() WebDriverWait(driver,1000).until( EC.presence_of_element_located((By.XPATH,'//tbody[@id="queryLeftTable"]/tr')) ) trs = driver.find_elements_by_xpath('//tbody[@id="queryLeftTable"]/tr[not(@datatran)]') is_searched = False for tr in trs: infos = tr.text.replace('\n',' ').split(' ') num = infos[0] if num in self.trains: seat_types = self.trains[num] for seat_type in seat_types: if seat_type == 'O': count = infos[9] if count.isdigit() or count == '有': is_searched = True break elif seat_type == 'M': count = infos[8] if count.isdigit() or count == '有': is_searched = True break if is_searched: self.selected_number = num order_btn = tr.find_element_by_xpath('.//a[@class="btn72"]') order_btn.click() break def confrim(self): WebDriverWait(driver,1000).until( EC.url_contains(self.confirm_url) ) WebDriverWait(driver, 1000).until( EC.presence_of_element_located((By.XPATH, '//ul[@id="normal_passenger_id"]/li/label')) ) passenger_labels = driver.find_elements_by_xpath('//ul[@id="normal_passenger_id"]/li/label') for passenger_label in passenger_labels: name = passenger_label.text if name in self.passengers: passenger_label.click()
seat_select = Select(driver.find_element_by_id('seatType_1')) seat_types = self.trains[self.selected_number] for set_type in seat_types: try: seat_select.select_by_value(set_type) except NoSuchElementException: continue else: break submit_btn = driver.find_element_by_id('submitOrder_id') submit_btn.click()
WebDriverWait(driver, 1000).until( EC.presence_of_element_located((By.CLASS_NAME, 'dhtmlx_window_active')) )
sub_btn = driver.find_element_by_id('qr_submit_id') while sub_btn: try: sub_btn.click() sub_btn = driver.find_element_by_id('qr_submit_id') except ElementNotVisibleException: break
def run(self): self.login() self.Ticket() self.confrim()
def main(): spider = TrainSpider('北京','长沙','2020-11-09',{'G485':['O','M'],},['XXX']) spider.run()
if __name__ == '__main__': main()
|
person.csv如下,如果知道其他站点代码 可以添加
1 2 3 4 5
| name,code
北京,BJP
长沙,CSQ
|