Python爬虫-使用selenium+chromedriver
2020-04-20 本文已影响0人
复苏的兵马俑
实现功能:
1、让浏览器打开12306的登录界面,然后手动进行登录;
2、登录完成后让浏览器跳转到购票的界面;
3、手动输入出发地、目的地、出发日,检测到以上三个信息都输入完成后,然后找到查询按钮,执行点击事件,进行车次查询;
4、查找我们需要的车次,然后看对应的席位是否还有余票(有、数字),找到这个车次的预订按钮,然后执行点击事件,如果没有出现以上两个(有、数字),那么我们就让循环这个查询工作;
5、一旦检测到有票(有、数字),就执行预订按钮的点击事件,来到预订的界面后,找到对应的乘客,然后找到这个乘客的checkbox,执行点击事件,再找到提交订单的按钮,执行点击事件;
点击完提交订单按钮以后,会弹出一个确认的对话框,然后找到“确认”按钮,执行点击事件,这样就完成了抢票。
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
class robTickets(object):
# 初始化函数
def __init__(self):
self.loginUrl = "https://kyfw.12306.cn/otn/resources/login.html"
self.userCenterUrl = "https://kyfw.12306.cn/otn/view/index.html"
self.searchTicketUrl = "https://kyfw.12306.cn/otn/leftTicket/init?linktypeid=dc"
self.selectPassengerUrl = "https://kyfw.12306.cn/otn/confirmPassenger/initDc"
driverPath = r"D:\chromedriver\chromedriver.exe"
self.driver = webdriver.Chrome(executable_path=driverPath) # 驱动Chrome浏览器进行操作
def waitInput(self):
self.fromStation = input("出发地:")
self.toStation = input("目的地:")
# 时间格式必须为yyyy-MM-dd的形式
self.trainDate = input("出发日(格式:2020-04-01):")
self.passengers = input("乘客姓名(如有多个乘客,用英文逗号隔开):").split(",")
self.trains = input("车次(如有多个车次,用英文逗号隔开):").split(",")
# _login只想在类中调用
def _login(self):
self.driver.get(self.loginUrl) # 打开登录页面
WebDriverWait(self.driver, timeout=1000).until(
EC.url_to_be(self.userCenterUrl)
)
print("恭喜你,已成功登录!")
def _orderTicket(self):
# 跳转到查询余票的页面
self.driver.get(self.searchTicketUrl)
# 等待出发地是否输入正确
WebDriverWait(self.driver, timeout=1000).until(
EC.text_to_be_present_in_element_value((By.ID, "fromStationText"), self.fromStation)
)
# 等待目的地是否输入正确
WebDriverWait(self.driver, timeout=1000).until(
EC.text_to_be_present_in_element_value((By.ID, "toStationText"), self.toStation)
)
# 等待出发日是否输入正确
WebDriverWait(self.driver, timeout=1000).until(
EC.text_to_be_present_in_element_value((By.ID, "train_date"), self.trainDate)
)
# 等待查询按钮是否可用
WebDriverWait(self.driver, timeout=1000).until(
EC.element_to_be_clickable((By.ID, "query_ticket"))
)
# 如果可以点击了,那么就找到这个查询按钮,执行点击事件
searchBtn = self.driver.find_element_by_id("query_ticket")
searchBtn.click()
# 在点击查询按钮后,等待车次信息是否显示出来
WebDriverWait(self.driver, timeout=1000).until(
EC.presence_of_element_located((By.XPATH, ".//tbody[@id='queryLeftTable']/tr"))
)
# 找到所有没有datatran属性的tr标签,这些标签是存储了车次信息的
trList = self.driver.find_elements_by_xpath(".//tbody[@id='queryLeftTable']/tr[not(@datatran)]")
# 遍历所有的满足条件的tr标签
for tr in trList:
trainNum = tr.find_element_by_class_name("number").text
if trainNum in self.trains:
leftTicket = tr.find_element_by_xpath(".//td[4]").text # 找到第4个标签下的文本
if leftTicket == "有" or leftTicket.isdigit(): # 判断输入的车次是否在列表中
orderBtn = tr.find_element_by_class_name("btn72")
orderBtn.click()
# 等待是否来到乘客选择页面
WebDriverWait(self.driver, 1000).until(EC.url_to_be(self.selectPassengerUrl))
# 等待所有乘客信息是否被加载完毕
WebDriverWait(self.driver, timeout=1000).until(
EC.presence_of_element_located((By.XPATH, ".//ul[@id = 'normal_passenger_id']/li"))
)
# 获取所有的乘客信息
passengerLabels = self.driver.find_elements_by_xpath(".//ul[@id='normal_passenger_id']/li/label")
# 遍历所有的label标签
for passengerLabel in passengerLabels: # 遍历所有的label标签
name = passengerLabel.text
if name in self.passengers: # 判断姓名是否在之前输入的姓名列表中
passengerLabel.click() # 执行点击操作
# 获取提交按钮
submitBtn = self.driver.find_element_by_id("submitOrder_id")
submitBtn.click()
# 显示等待确认订单对话框是否出现
WebDriverWait(self.driver, timeout=1000).until(
EC.presence_of_element_located((By.CLASS_NAME,'dhtmlx_wins_body_outer'))
)
# 显示等待确认按钮是否加载出现,出现后执行点击操作
WebDriverWait(self.driver, timeout=1000).until(
EC.presence_of_element_located((By.ID, "qr_submit_id"))
)
confirmBtn = self.driver.find_element_by_id("qr_submit_id")
confirmBtn.click()
return
def run(self):
self.waitInput()
self._login()
self._orderTicket()
if __name__ == '__main__':
spider = robTickets()
spider.run()