12306爬虫代码

用到的驱动和谷歌浏览器可在我的资源列表中查看到

驱动存放位置:

src/main/resources/chromedriver.exe

maven配置

		<dependency>
			<groupId>net.sourceforge.htmlunit</groupId>
			<artifactId>com.springsource.com.gargoylesoftware.htmlunit</artifactId>
			<version>2.6.0</version>
		</dependency>
		<dependency>
			<groupId>org.seleniumhq.selenium</groupId>
			<artifactId>selenium-java</artifactId>
			<version>3.4.0</version>
		</dependency>
		<dependency>
			<groupId>net.sourceforge.htmlunit</groupId>
			<artifactId>htmlunit</artifactId>
			<version>2.49.1</version>
		</dependency>
		<!--   selenium 浏览器测试  不添加此依赖会抛com.google.common.util.concurrent.SimpleTimeLimiter.create异常-->
		<dependency>
			<groupId>com.google.guava</groupId>
			<artifactId>guava</artifactId>
			<version>23.0</version>
		</dependency>
		<dependency>
			<groupId>com.google.code.gson</groupId>
			<artifactId>gson</artifactId>
			<version>2.8.2</version>
		</dependency>

话不多说,直接上代码


    private static final String loginUrl = "https://kyfw.12306.cn/otn/resources/login.html";
    private static final String indexUrl = "https://kyfw.12306.cn/otn/view/index.html";
    private static final String searchUrl = "https://kyfw.12306.cn/otn/leftTicket/init";
    private static final String confirmUrl = "https://kyfw.12306.cn/otn/payOrder/init";


    public static void main(String[] args) throws InterruptedException {
        
        // 获取驱动
        WebDriver driver = getWebDriver();
        // 最大化
        driver.manage().window().maximize();
        // 处理登录
        handleLogin(driver);
        // 前往搜索
        handleSearch(driver);
        // 用户输入的车次
        String carCode = handleInputCarCode();
        // 处理预定
        handleReserve(driver, carCode);
        // 处理提交
        handleSubmit(driver);
        // 处理确认提交信息
        handleConfirm(driver);
        // 处理提醒用户
        handleCallUser(driver);
        driver.get(confirmUrl);
        List<WebElement> elements = driver.findElements(By.id("payButton"));
        elements.get(0).click();
        driver.get("https://epay.12306.cn/pay/payGateway");
        Thread.sleep(2000);
        WebElement element = driver.findElement(By.name("支付宝"));
        element.click();

        // 睡眠等待用户确认信息完毕
        Thread.sleep(1000000);
        // 关闭浏览器
        driver.close();


    }

    private static void handleCallUser(WebDriver driver) throws InterruptedException {

        String windowHandle = driver.getWindowHandle();
        JavascriptExecutor executor = (JavascriptExecutor) driver;
        executor.executeScript("window.open('https://music.163.com/#/song?id=224877')");
        // 切换到网易云窗口
        Thread.sleep(1000);
        List<String> windowHandles = new ArrayList<>(driver.getWindowHandles());
        driver.switchTo().window(windowHandles.get(windowHandles.size() - 1));
        Thread.sleep(1000);
        driver.switchTo().frame("contentFrame");
        Thread.sleep(1000);
        driver.findElement(By.cssSelector("[id=content-operation]>a:first-child")).click();
        Thread.sleep(1000);
        driver.switchTo().window(windowHandle);
    }

    private static void handleConfirm(WebDriver driver) throws InterruptedException {
        Thread.sleep(1000);
        if(driver.findElements(By.cssSelector("#checkticketinfo_id #qr_submit_id")).size() > 0) {
            // 点击确认订单信息
            driver.findElements(By.cssSelector("#checkticketinfo_id #qr_submit_id")).get(0).click();
        }
        log.debug("购票成功");
    }

    private static void handleSubmit(WebDriver driver) throws InterruptedException {
        Thread.sleep(1000);
        driver.findElement(By.cssSelector("#normalPassenger_0")).click();
        //
        do {
            if(driver.findElements(By.cssSelector("#transforNotice_id #qr_closeTranforDialog_id")).size() > 0) {
                // 这里有可能会出现网络繁忙的情况, 如果出现就点击确认, 关闭窗口, 然后再重试
                driver.findElement(By.cssSelector("#transforNotice_id #qr_closeTranforDialog_id")).click();
            }
            Thread.sleep(1000);
            driver.findElement(By.cssSelector("#submitOrder_id")).click();
            //
        } while(driver.findElements(By.cssSelector("#transforNotice_id #qr_closeTranforDialog_id")).size() > 0);
    }

    private static void handleLogin(WebDriver driver) throws InterruptedException {
        driver.get(loginUrl);
        List<WebElement> elements = driver.findElements(By.id("J-userName"));
        elements.get(0).sendKeys("xxx");
        List<WebElement> element2s = driver.findElements(By.id("J-password"));
        element2s.get(0).sendKeys("xxx");
        List<WebElement> element3s = driver.findElements(By.id("J-login"));
        element3s.get(0).click();
        List<WebElement> element4s = driver.findElements(By.id("id_card"));
        Thread.sleep(3000);
        element4s.get(0).sendKeys("xxx");
        List<WebElement> element5s = driver.findElements(By.id("verification_code"));
        element5s.get(0).click();
        List<WebElement> element6s = driver.findElements(By.id("code"));
        element6s.get(0).click();
        List<WebElement> element7s = driver.findElements(By.id("sureClick"));
        element7s.get(0).click();

        // log.debug("等待用户登录");
        // // 登录成功
        // WebDriverWait wait = new WebDriverWait(driver, 120);
        // wait.until(ExpectedConditions.urlContains(indexUrl));
        log.debug("用户登录成功~");
    }

    private static void handleReserve(WebDriver driver, String carCode) throws InterruptedException {
        clickSearch : for (int i = 1; ; i++) {
            List<WebElement> trs = driver.findElements(By.cssSelector("table tbody#queryLeftTable:first-of-type tr"));
            for (WebElement tr : trs) {
                if (tr.getAttribute("id").contains("ticket_")) {
                    String currentCarCode = tr.findElements(By.cssSelector("td div.ticket-info > div.train a.number")).get(0).getText();
                    if (carCode.equals(currentCarCode)) {
                        // 找到了车次
                        WebElement purchaseTd = tr.findElement(By.cssSelector("td:last-of-type"));
                        String text = purchaseTd.getText();
                        log.debug("找到预定text:" + text);
                        List<WebElement> aElementList = purchaseTd.findElements(By.tagName("a"));
                        if (aElementList.size() > 0) {
                            log.debug("点击预定:");
                            purchaseTd.click();
                            Thread.sleep(1000);
                            if (driver.findElements(By.id("defaultwarningAlert_id")).size() > 0) {
                                // 可能出现不可以预定时间
                                List<WebElement> tips = driver.findElements(By.id("content_defaultwarningAlert_hearder"));
                                if (tips.size() > 0) {
                                    String tip = tips.get(0).getText();
                                    log.debug("预定失败:" + tip);
                                }
                                // 关闭弹窗
                                driver.findElement(By.id("qd_closeDefaultWarningWindowDialog_id")).click();
                                continue clickSearch;
                            }
                            // 需要处理登录问题
                            break clickSearch;
                        }
                    }
                }
            }
            // 没有找到车次, 或者, 点击查询按钮, 10次刷新一下页面
            if (i % 10 == 0) {
                log.debug("重新刷新页面");
                driver.navigate().refresh();
                continue;
            }
            long sleepTime = ThreadLocalRandom.current().nextLong(800, 2000);
            Thread.sleep(sleepTime);
            List<WebElement> query_ticket = driver.findElements(By.id("query_ticket"));
            if (query_ticket.size() > 0) {
                log.debug("准备点击查询更新数据第: " + i + " 次");
                query_ticket.get(0).click();
                // 等待页面数据出来
                WebDriverWait wait = new WebDriverWait(driver, 120);
                wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("table tbody#queryLeftTable:first-of-type tr")));
            } else {
                log.debug("查询按钮不可用");
            }
        }
    }

    private static String handleInputCarCode() {
        System.err.println("=============================请在下方输入你需要抢购的车次==================================");
        String carCode = null;
        try (Scanner scanner = new Scanner(System.in)) {
            while (StringUtils.isEmpty(carCode)) {
                System.out.println();
                carCode = scanner.nextLine();
            }
        }
        System.out.println("您输入的车次为:" + carCode);
        return carCode;
    }

    private static void handleSearch(WebDriver driver) {
        driver.get(searchUrl);
        System.out.println();
        System.err.println("请在打开的浏览器页面中填写 '出发地' '目的地' '出发日' 等相关信息, 并且点击 '查询' 按钮完成本次操作");
        // 获取搜索的条数
        WebDriverWait wait = new WebDriverWait(driver,120);
        wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("table tbody#queryLeftTable:first-of-type tr")));
        List<WebElement> trs = driver.findElements(By.cssSelector("table tbody#queryLeftTable:first-of-type tr"));
        List<String> currentCarCodeList = new ArrayList<>(16);
        for (WebElement tr : trs) {
            if (tr.getAttribute("id").contains("ticket_")) {
                String currentCarCode = tr.findElements(By.cssSelector("td div.ticket-info > div.train a.number")).get(0).getText();
                currentCarCodeList.add(currentCarCode);
            }
        }
        System.out.println("本次查找到车次数量为: " + currentCarCodeList.size());
        for (int i = 0; i < currentCarCodeList.size(); i++) {
            String currentCarCode = currentCarCodeList.get(i);
            System.out.print(currentCarCode + "\t||\t");
            if (i % 5 == 1) {
                System.out.println();
            }
        }
    }


    private static WebDriver getWebDriver() {
        // System.setProperty("webdriver.chrome.driver", "C:\\install\\chromedriver\\chromedriver.exe");// chromedriver地址
        System.setProperty("webdriver.chrome.driver", "src/main/resources/chromedriver.exe");// chromedriver地址
        WebDriver driver = new ChromeDriver(); // 新建一个WebDriver 的对象,但是new 的是谷歌的驱动
        return driver;
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值