之前写了一篇本篇博客的结构如下:
首先会给出一些使用selenium + ChromeDriver的入门的一些友情链接
其次讲解一下本人在爬取网站的一些思路和流程
最后给出github地址并总结经验。
环境配置以及入门知识参考我的之前一篇博客:
详细使用方式参考webDriver中文社区:
使用过程的常见异常参考他人博客:
2. 爬取思路及流程
整体的爬取思路见上图,分为两个流程的原因是:在点击页面去向另一个页面时会出现让你登陆或者数据验证码的情况。如果每一步都要进行判断不好管理,还不如直接放在一个方法里面进行管理。只要每次有点击页面链接或者按钮的情况都进入到页面判断及处理流程中去。通过这个方法判断你新进入的页面是什么情况,并且对不同的页面进行不同的处理。下面对每个步骤进行详细讲解
2.1 点击登录
1 //去登陆页面并且登录 2 public static void toLoginAndLogin(WebDriver driver) { 3 //1、去登陆页面 4 List<WebElement> elements = driver.findElements(By.cssSelector("div.pull-right a")); 5 //2、通过下标得到对应的登录链接 6 WebElement loginElement = elements.get(elements.size() - 1); 7 loginElement.click(); 8 //2、该方法判断当前页面是登录页面,则进行登录 9 CompanyInfoPageHandle.handleDifferentPage(driver); 10 }
//查询公司名称 public static void searchCompanyName(WebDriver driver, String CompanyName) { //1、查询公司名称 try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } //2、选取输入框 WebElement search = driver.findElement(By.cssSelector("input[placeholder=\"请输入企业名、人名、产品名等关键词,多关键词用空格隔开,如:上海 平安\"]")); search.sendKeys(CompanyName); //3、选取按钮 WebElement submit = driver.findElement(By.cssSelector("i.input-group-addon.search-btn.icon.icon-search")); submit.click(); //4、判断当前页面的情况并进行处理 CompanyInfoPageHandle.handleDifferentPage(driver); }
/** * 保存信息 * @param driver * @param companyName */ private void saveResult(WebDriver driver, String companyName) { try { Thread.sleep(2000); //1、首先遍历每行的公司信息 List<WebElement> companyElementList = driver.findElements(By.cssSelector("div.col-xs-24.padding-v-1x.margin-0-0x.border-b-b4.company-item")); //2、保存当前一行公司的信息 for (WebElement companyElement : companyElementList) {//保存信息 try { List<WebElement> companyInfoElementList = companyElement.findElements(By.cssSelector("div")); List<String> infoList = new ArrayList<>(); for (WebElement companyInfo : companyInfoElementList) { infoList.add(companyInfo.getText().replace("\n", "")); } String result = String.join("\t", infoList); FileUtils.saveLineAppend(companyName + ".txt", result); } catch (Exception e) { continue; } } } catch (Exception e) { e.printStackTrace(); } }
在之前的过程中,只要有点击事件触发则需要判断触发之后的页面是什么页面,才能够对当前的页面进行处理。主要分为两个过程,第一步判断当前页面是什么,第二步对不同的页面有不同的处理方式,具体见下面代码:
/** * 用来判别页面的情况 */ public class CompanyInfoPageClassification { /** * 页面判断的主方法,用来判断当前的页面是什么页面 * @param driver * @return */ public static String PageClassificationMain(WebDriver driver){ if (isVerificationCodePage(driver)){ return "验证码"; } if (is404Page(driver)){ return "404"; } if (isLoginPage(driver)){ return "登录"; } return "正常"; } /** * 判断当前页面是否是验证码页面 * @param driver * @return */ private static boolean isVerificationCodePage(WebDriver driver){ List<WebElement> buttonList = driver.findElements(By.cssSelector("button.btn4")); if (buttonList.size() != 0 && buttonList.get(0).getText().equals("点击按钮进行验证")) { return true; } else { return false; } } /** * 判断当前页面是否是404 * @param driver * @return */ private static boolean is404Page(WebDriver driver){ List<WebElement> buttonList = driver.findElements(By.cssSelector("div.error-container.error-404")); if (buttonList.size() != 0 ) { return true; } else { return false; } } /** * 判断当前页面是否是登录页面 * @param driver * @return */ private static boolean isLoginPage(WebDriver driver){ List<WebElement> buttonList = driver.findElements(By.cssSelector("input[placeholder=\"请输入手机号码\"]")); if (buttonList.size() != 0 ) { return true; } else { return false; } } }
** * 根据不同的页面进行不同的处理 */ public class CompanyInfoPageHandle { public static void handleDifferentPage(WebDriver driver){ try { Thread.sleep(2000); } catch (Exception e) { e.printStackTrace(); } String pageStatus = CompanyInfoPageClassification.PageClassificationMain(driver); switch (pageStatus){ case "验证码": //1、如果是验证码页面那么需要在这里进行处理,例如手动输入验证码。如果验证码比较简单可以使用字符识别的方法 System.out.println("验证码页面"); //2、登录完了之后再判断是什么页面,然后再对当前页面进行处理 handleDifferentPage(driver); break; case "登录": //1、如果是登录页面那就进行登录 login(driver, "用户名","密码"); //2、登录完了之后再判断是什么页面,然后再对当前页面进行处理 handleDifferentPage(driver); break; case "404": break; } } private static void login(WebDriver driver, String userName, String password){ WebElement phoneElement = driver.findElement(By.cssSelector("input[placeholder=\"请输入手机号码\"]")); phoneElement.sendKeys(userName); WebElement passwordElement = driver.findElement(By.cssSelector("input[placeholder=\"请输入密码\"]")); passwordElement.sendKeys(password); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } List<WebElement> elements2 = driver.findElements(By.cssSelector("div a.btn")); WebElement login = elements2.get(0); login.click(); } }
经验总结:
<li><a href="/example" data-marko="{"onclick":"handleClickDebounce s0-9-20 false 0"}">2</a></li>