老狗啃爬虫-模拟用户登录之Selenium
摘要:
前面我们学了借助Selenium抓取动态页面,感受了下Selenium飘逸的功能。但有时候呢,查看页面时需要一些权限,不登录没法看,这让人如何是好…莫怕,Selenium有办法!Selenium能模拟用户登录,是可以让我们通过爬虫程序获取受限制的数据信息的,接着我们就这前面的,在百度移动端的页面上,来实现用户登录
前面我们学了借助Selenium抓取动态页面,感受了下Selenium飘逸的功能。但有时候呢,查看页面时需要一定点权限,比如不登录就没法看,这让人如何是好… 别担心,Selenium有办法!
Selenium能模拟用户登录,从而可以让我们通过爬虫程序获取到受限数据信息。下面我们就趁热打铁,接着前面,在百度移动端的页面上,实现用户登录。
页面分析
百度移动端的登录地址是:https://wappass.baidu.com/passport/?login&u=#/password_login
我们先用chrome浏览器打开,直接F12进入调试状态,在移动设备模式下,我们研究页面得出结论,用于登陆的主要就是以下这三个元素:

登录名、密码和一个提交按钮,到后边我们就可以用xpath定位拿到它们,然后用程序自动去操作。
接下来,我们先手动操作,登录成功,跳转到的百度页面,留意右上角有个用户的小图标:

可以很容易发现,相对页面上的其他元素,这个小图标比较有特性,好,我们就选它作为登录成功的辨别标识。
下面我们就写程序来实现登录操作。
程序实现
经过上面的一番分析,大概流程基本也比较明晰了,我们就选用最直接的实现方式,啪啪啪一顿键盘敲击,代码如下:
package cn.veiking.selenium;
import java.util.Set;
import org.openqa.selenium.By;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Component;
import cn.veiking.base.common.logs.SimLogger;
import cn.veiking.base.config.SeleniumConfig;
/**
* @author :Veiking
* @version :2020年12月30日 说明 :使用Selenium模拟登录
*/
@Component
@EnableConfigurationProperties(SeleniumConfig.class)
public class SeleniumForLogin {
private SimLogger logger = new SimLogger(this.getClass());
@Autowired
private SeleniumConfig seleniumConfig;
private WebDriver webDriver;
private ChromeOptions options;
private int sleepTime = 1000;
private static String loginname = "dog@veiking"; // 账号
private static String password = "********"; // 密码
// 模拟登录
public void login() {
// 初始数据
checkInit();
String url = "https://wappass.baidu.com/passport/?login&u=#/password_login"; // 百度移动端登录地址
try {
// 打开百度移动端登录页
webDriver.get(url);
// 输入用户名
webDriver.findElement(By.xpath("//*[@id=\"naPassWrapper\"]/section/article[1]/form/section[1]/div/input"))
.clear();
webDriver.findElement(By.xpath("//*[@id=\"naPassWrapper\"]/section/article[1]/form/section[1]/div/input"))
.sendKeys(loginname);
// 输入密码
webDriver.findElement(By.xpath("//*[@id=\"naPassWrapper\"]/section/article[1]/form/section[2]/div/input"))
.clear();
webDriver.findElement(By.xpath("//*[@id=\"naPassWrapper\"]/section/article[1]/form/section[2]/div/input"))
.sendKeys(password);
// 点击登录
webDriver.findElement(By.xpath("//*[@id=\"naPassWrapper\"]/section/article[1]/form/input")).click();
// 充分休息,要人工输入百度那个转圈圈的验证码
WebElement loginSeccess = null;
while (null == loginSeccess) {
try {
// 登录成功的页面右上角有个用户头像标识,可以用做成功登录辨别
loginSeccess = webDriver.findElement(By.xpath("//*[@id=\"personal-center\"]/div[2]/div[1]/img"));
} catch (Exception e) {
Thread.sleep(sleepTime);
}
}
logger.info("Login success !");
} catch (InterruptedException e) {
e.printStackTrace();
}
webDriver.quit(); // 关闭所有相关窗口,退出
webDriver = null;
}
// 初始
private void checkInit() {
// 实例化WebDriver前必须配置
System.getProperties().setProperty("webdriver.chrome.driver", seleniumConfig.getChromedriverPath());
// 浏览器位置
options = new ChromeOptions();
options.addArguments("--user-agent=Galaxy S5"); // 设置手机设备-浏览器访问
webDriver = new ChromeDriver(options);
webDriver.manage().window().setSize(new Dimension(500, 800)); // 浏览器size
}
}
经过前一篇的学习,这些代码就相对比较简单了,checkInit()方法负责一些变量初始化工作,然后login()方法里,就是按部就班的操作步骤,输登录名密码,提交。
注意这里有个while循坏,是考虑到百度那个图片转圈圈的验证环节,它不出现就是直接登录成功了,出现时就会暂时卡在这里,需要我们人工来操作下。
功能测试
好了,逻辑代码写完,我们直接写个测试类:
package cn.veiking.selenium;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import cn.veiking.StartTest;
import cn.veiking.base.common.logs.SimLogger;
/**
* @author :Veiking
* @version :2020年12月30日
* 说明 :SeleniumForLoginTest 测试
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = StartTest.class)
public class SeleniumForLoginTest {
SimLogger logger = new SimLogger(this.getClass());
@Autowired
private SeleniumForLogin seleniumForLogin;
@Test
public void testLogin() {
long startTime, endTime;
logger.info("SeleniumForLoginTest [start={}] ", "开始爬取数据");
startTime = System.currentTimeMillis();
// 模拟登录
seleniumForLogin.login();
endTime = System.currentTimeMillis();
logger.info("SeleniumForLoginTest [end={}] ", "爬取结束,耗时约" + ((endTime - startTime) / 1000) + "秒");
}
}
这里也没别的逻辑,就是调用一下:seleniumForLogin.login()。
然后我们看着浏览器自己启动,自己填入登录名密码,自己提交,然后在验证这块儿我们动动手:

验证通过后,果如所愿,完美登录。
结语
借助Selenium完成登录断操作,是相对比较简单的,一般我们登陆的主要目的呢,还是想要拿到他的Cookie,来实现其他的具体操作,在下一篇,我们就看看Selenium中这个Cookie怎么用。