Live2D

使用Selenium 爬虫12306 实现自动抢票

1.12306抢票

import org.jsoup.Jsoup
import org.openqa.selenium.By
import org.openqa.selenium.Keys
import org.openqa.selenium.firefox.FirefoxDriver
import org.openqa.selenium.firefox.FirefoxOptions
import org.openqa.selenium.firefox.FirefoxProfile
import org.openqa.selenium.interactions.Actions
import java.io.InputStreamReader
import java.util.*

const val URL = "https://kyfw.12306.cn/otn/leftTicket/init?linktypeid=dc"
const val LOGIN_URL = "https://kyfw.12306.cn/otn/resources/login.html"

class Info_12306 {

}

fun main() {
    val timer = Timer()
    timer.schedule(object : TimerTask() {
        override fun run() {
            use()
        }

    }, 0, 80000)

}

fun use() {
    val pro = Properties()
    pro.load(InputStreamReader(Info_12306::class.java.classLoader.getResourceAsStream("12306.properties"),"UTF-8"))
    val date = pro.getProperty("date")
    val fromStation = pro.getProperty("startStation")
    val toStation = pro.getProperty("endStation")
    val lUsername = pro.getProperty("username")
    val lPassword = pro.getProperty("password")
    val passenger=pro.getProperty("passenger")
    println(fromStation)
    println(toStation)

    System.setProperty("webdriver.gecko.driver", "/usr/local/bin/geckodriver")
    var options = FirefoxOptions()
    val profile = FirefoxProfile()
    //禁止GPU渲染
    options.addArguments("--disable-gpu")
//    options.addArguments("--headless")
    //忽略错误
    options.addArguments("ignore-certificate-errors")
    //禁止浏览器被自动化的提示
    options.addArguments("--disable-infobars")
    //反爬关键:window.navigator.webdrive值=false*********************
    options.addPreference("dom.webdriver.enabled", false)
    //设置请求头
    profile.setPreference(
        "general.useragent.override",
        "Mozilla/5.0(iPhone;CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML,like Gecko) Version/11.0 Mobile/15A372 Safari/604.1"
    )
    //禁用缓存
    options.addPreference("network.http.use-cache", false)
    options.addPreference("browser.cache.memory.enable", false)
    options.addPreference("browser.cache.disk.enable", false)
    options.addPreference("browser.sessionhistory.max_total_viewers", 3)
    options.addPreference("network.dns.disableIPv6", true)
    options.addPreference("Content.notify.interval", 750000)
    options.addPreference("content.notify.backoffcount", 3)
    options.addPreference("network.http.pipelining", true)
    options.addPreference("network.http.proxy.pipelining", true)
    options.addPreference("network.http.pipelining.maxrequests", 32)

    val driver = FirefoxDriver(options)
    // 访问登录界面
    driver.get(LOGIN_URL)

    // 必须执行  去除浏览器对selenium的识别 不然滑动验证码会报错
    val script = "Object.defineProperty(navigator, 'webdriver', {get: () => false,});"
    driver.executeScript(script)


    // 用户名 密码 处理
    val username = driver.findElement(By.id("J-userName"))
    val password = driver.findElement(By.id("J-password"))
    username.sendKeys(lUsername)
    Thread.sleep(500)
    password.sendKeys(lPassword)
    Thread.sleep(500)
    // 登录按钮
    driver.findElement(By.id("J-login")).click()
    Thread.sleep(1000)

    //验证码
    val block = driver.findElement(By.id("nc_1_n1z"))

    val action = Actions(driver)
    action.clickAndHold(block)
    // 移动
    action.moveByOffset(350, 0).perform()
    Thread.sleep(300)
    action.release().perform()
    Thread.sleep(1000)

    // 访问买票页面
    driver.get(URL)
    driver.findElement(By.id("qd_closeDefaultWarningWindowDialog_id")).click()

    val startStation = driver.findElement(By.id("fromStationText"))
    startStation.click()
    startStation.sendKeys(fromStation)
    startStation.sendKeys(Keys.ENTER)


    val endStation = driver.findElement(By.id("toStationText"))
    endStation.clear()
    endStation.click()
    endStation.sendKeys(toStation)
    endStation.sendKeys(Keys.ENTER)

    val startDate = driver.findElement(By.id("train_date"))
    startDate.click()
    startDate.clear()

    startDate.sendKeys(date)

    driver.findElement(By.id("cc_train_type_btn_all")).findElement(By.xpath("//input[@value='G']")).click()
    driver.findElement(By.id("query_ticket")).click()
    driver.findElement(By.id("avail_ticket")).click()


    for (i in 0..3) {
        driver.findElement(By.id("query_ticket")).click()
        var flag = false
        if (driver.findElement(By.id("show_all_query_result")).text != "显示全部车次") {
            val trCollection = driver.findElement(By.id("queryLeftTable")).findElements(By.tagName("tr"))
            trCollection.forEach {
                val time = try {
                    it.findElement(By.className("start-t")).text.substring(0 until 2).toInt()
                } catch (t: Throwable) {
                    100000
                }
                // 筛选时间
                try {
                    if (time in 1..19 && it.findElements(By.tagName("td"))[3].text == "有") {
                        it.findElement(By.className("btn72")).click()
                        Thread.sleep(1500)
                       val dom= Jsoup.parse(driver.pageSource)
                        println(dom.getElementById("qd_closeDefaultWarningWindowDialog_id"))
                        // 买票
                        if (dom.getElementById("qd_closeDefaultWarningWindowDialog_id")!=null){
                            driver.findElement(By.id("qd_closeDefaultWarningWindowDialog_id")).click()
                        }

                        val liCollection =
                            driver.findElement(By.id("normal_passenger_id")).findElements(By.tagName("li"))
                        liCollection.forEach { info ->
                            if (info.findElement(By.tagName("label")).text == passenger) {
                                info.findElement(By.tagName("label")).click()
                                driver.findElement(By.id("submitOrder_id")).click()
                                Thread.sleep(2000)
                                driver.findElement(By.id("qr_submit_id")).click()
                                flag = true

                            }
                        }
                    }
                } catch (t: Throwable) {
                }
            }


        }
        if (flag) {
            driver.quit()
            break
        }
        Thread.sleep(10000)
    }
    driver.quit()
}

config.properties

date=2022-10-09
startStation=武汉
endStation=北京西
username=aa
password=bb
passenger=乘车人
posted @ 2022-09-28 14:45  没有梦想的java菜鸟  阅读(251)  评论(0编辑  收藏  举报