1.通过maven引入相关依赖
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.0.0-alpha-7</version>
</dependency>
2.下载相对应的浏览器驱动
谷歌浏览器驱动:CNPM Binaries Mirror
edge浏览器驱动:Microsoft Edge WebDriver - Microsoft Edge Developer
火狐浏览器驱动:Releases · mozilla/geckodriver · GitHub
根据实际需要,去下载对应的浏览器驱动
3.实现代码
/**
* selenium 登录
* @param url 网站地址
* @param phoneId 用户名输入款id
* @param passwordId 密码输入框id
* @param loginButtonId 登录按钮id
* @param phone 用户名
* @param password 密码
* @return 返回当前driver,供下一步操作使用
* @throws Exception
*/
public static WebDriver login(String url, String phoneId, String passwordId, String loginButtonId, String phone, String password) throws InterruptedException {
System.setProperty("webdriver.edge.driver", "D:\\driver\\msedgedriver.exe");
WebDriver driver = new EdgeDriver();
Map<String,Object> command = new HashMap<>();
// 进行反爬处理 navigator.webdriver = undefined/false
command.put("source","Object.defineProperty(navigator, 'webdriver', {get: () => undefined})");
((EdgeDriver) driver).executeCdpCommand("Page.addScriptToEvaluateOnNewDocument",command);
// 浏览器窗口最大化
driver.manage().window().maximize();
driver.get(url);
// 自动输入登录账号
driver.findElement(By.id(phoneId)).sendKeys(phone);
// 自动输入登录密码
driver.findElement(By.id(passwordId)).sendKeys(password);
// 自动点击登录按钮
driver.findElement(By.id(loginButtonId)).click();
// 等待1秒,等待滑块验证码dialog加载完成,否则可能找不到对应的id
Thread.sleep(500);
// 目前使用滑块验证码,其他验证方式可以自行修改
WebElement element = driver.findElement(By.id("nc_1_n1z"));
Actions actions = new Actions(driver);
// 12306滑块到最右边宽度为300,其他方式可自行计算
actions.dragAndDropBy(element, 300, 0).perform();
return driver;
}
/**
* @param driver 操作当前页面需要的webDriver
* @param url 购票预定页面地址
* @param startingStation 起点站
* @param destination 终点站
* @param date 出发日期,格式为 yyyy-MM-dd的字符串
*/
public static void queryAndBuyTicket(WebDriver driver, String url, String startingStation, String destination, String date) throws InterruptedException{
createQuery(driver, url, startingStation, destination, date);
List<WebElement> elements = driver.findElements(By.className("btn72"));
if (elements != null && elements.size() > 0) {
for (int i = 0; i < elements.size(); i++) {
elements.get(i).click();
Thread.sleep(500);
try {
createOrder(driver, "https://kyfw.12306.cn/otn/confirmPassenger/initDc");
} catch (Exception e) {
}
}
}
}
/**
* 查询车票信息
* @param url 网站地址
* @param startingStation 起点站
* @param destination 终点站
* @param date 出发日期,格式为 yyyy-MM-dd 的字符串
*/
public static void queryTicket(WebDriver driver, String url, String startingStation, String destination, String date) {
createQuery(driver, url, startingStation, destination, date);
}
/**
* 构建查询车票信息
* @param driver 操作页面需要的webDriver
* @param url 页面地址
* @param startingStation 起点站
* @param destination 终点站
* @param date 出发日期,格式为 yyyy-MM-dd 的字符串
*/
public static void createQuery(WebDriver driver, String url, String startingStation, String destination, String date) {
driver.get(url);
// 先要对输入框内容进行清空操作,对于输入方式的起点站和目的地,需要额外确认一次点击才能完成查询,所以要确保输入的地址是正确的,
// 可能会出现多个到达地址,默认取citem_0就行,查询结果基本上是一致的
driver.findElement(By.id("fromStationText")).clear();
driver.findElement(By.id("fromStationText")).sendKeys(startingStation);
driver.findElement(By.id("citem_0")).click();
driver.findElement(By.id("toStationText")).click();
driver.findElement(By.id("toStationText")).sendKeys(destination);
driver.findElement(By.id("citem_0")).click();
driver.findElement(By.id("train_date")).clear();
driver.findElement(By.id("train_date")).sendKeys(date);
driver.findElement(By.id("search_one")).click();
}
/**
* 创建购票订单
* @param driver 操作页面需要的webDriver
* @param url 订单提交页面地址
*/
public static void createOrder(WebDriver driver, String url) throws InterruptedException {
driver.get(url);
// 选择乘车人复选框,如果有多个乘车人,建议使用By.className来获取元素
driver.findElement(By.id("normalPassenger_0")).click();
// 提交订单
driver.findElement(By.id("submitOrder_id")).click();
// 等待500毫秒,等确认提交框弹出
Thread.sleep(500);
driver.findElement(By.id("qr_submit_id")).click();
}
该用例仅用来对selenium的练习及相关网站的测试,并不能够实现自动抢票的功能,是在为了了解和使用java进行自动化测试编写的用例,如果认为能够抢票,请忽视本篇内容。