Python【原创】Python网络爬虫

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()
上一篇 下一篇

猜你喜欢

热点阅读