每逢佳节倍思亲,中秋节到了,这里祝愿大家中秋节快乐。
今天主要向大家介绍的是如何自动打开浏览器并自动搜索指定内容。
1. 下载谷歌浏览器驱动
为什么要下载驱动?
因为一般的写爬虫的方法是用脚本直接对目标网站进行访问,而且只对目标数据进行采集,访问速度很快,这样目标网站很容易就识别出你是爬虫,然后把你封锁了。这个时候,为了更加像人浏览网站,需要一个控制器来控制浏览器,这样就可以避开封锁,很多难爬的网站也可以轻而易举的抓数据了。
我们就是通过一个叫做Selenium的工具做到模拟人浏览浏览器的,当然,Selenium不仅如此,它还是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。这个工具的主要功能包括:测试与浏览器的兼容性——测试你的应用程序看是否能够很好得工作在不同浏览器和操作系统之上。测试系统功能——创建回归测试检验软件功能和用户需求。支持自动录制动作和自动生成 .Net、Java、Perl等不同语言的测试脚本。
针对不同的浏览器,控制底层的逻辑实现不同,因此,不同的浏览器需要下载不同的驱动,这有点类似于连接到不同的数据库时需要不同的数据库驱动一样,这里提供一个谷歌浏览器的驱动下载链接:谷歌浏览器驱动。
2. 元素定位之XPath
XPath即为XML路径语言,它是一种用来确定XML(标准通用标记语言的子集)文档中某部分位置的语言。XPath基于XML的树状结构,提供在数据结构树中找寻节点的能力,在实际开发自动化脚本过程中,XPath的使用是最多的一种方法。关于XPath的其他内容,读者可以自行百度。
这里主要介绍一下如何获取某一个元素的XPath,例如,我们以获取百度首页的搜索文本框填入搜索内容后点击搜索按钮距离。
上述操作对于没有接触过谷歌浏览器的读者可能有一定的困难,如果有不懂可以评论区留兰。
copy xpath后,直接黏贴,可以看到如下的路径字符串:
//*[@id="kw"]
为了实现搜索,我们也获取一下“百度一下”按钮的XPath:
//*[@id="su"]
3. 搜索内容
下面演示一下如何打开浏览器并输入搜索“中秋快乐”的。
3.1 添加依赖
首先,建立一个maven项目,并在pom.xml中添加依赖的jar包:
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.4.0</version>
</dependency>
接着,编写我们主要的代码:
3.2 获取驱动对象
/**
* 获取Chrome驱动
*
* @param path 路径
* @return
* @throws Exception
*/
public static WebDriver createChromeWebDriver(String path) throws Exception {
if (path == null || "".equals(path)) {
throw new Exception("配置错误, 没有配置:chrome path");
}
System.getProperties().setProperty("webdriver.chrome.driver", path);
WebDriver webDriver = new ChromeDriver();
webDriver.manage().timeouts().pageLoadTimeout(1200, TimeUnit.SECONDS);
webDriver.manage().window().setSize(new Dimension(1024, 768));
return webDriver;
}
3.3 搜索
/**
* 搜索
*
* @param key 关键字
*/
public static void search(WebDriver driver, String key) {
driver.get("http://baidu.com/");
WebElement elementKey = driver.findElement(By.xpath("//*[@id=\"kw\"]"));
elementKey.sendKeys(key);
WebElement elementClick = driver.findElement(By.xpath("//*[@id=\"su\"]"));
elementClick.click();
}
3.4 主函数
public static void main(String[] args) {
WebDriver webDriver;
try {
webDriver = createChromeWebDriver("webdrivers\\chromedriver.exe");
search(webDriver, "中秋快乐");
} catch (Exception e) {
e.printStackTrace();
}
}
3.5 完整代码和效果
package com.clawer.logintest;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
/**
* 百度搜索
*/
public class App {
public static void main(String[] args) {
WebDriver webDriver;
try {
webDriver = createChromeWebDriver("driver\\chromedriver.exe");
search(webDriver, "中秋快乐");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 创建Chrome
*
* @param path 路径
* @return
* @throws Exception
*/
public static WebDriver createChromeWebDriver(String path) throws Exception {
if (path == null || "".equals(path)) {
throw new Exception("配置错误, 没有配置:chrome path");
}
System.getProperties().setProperty("webdriver.chrome.driver", path);
WebDriver webDriver = new ChromeDriver();
webDriver.manage().timeouts().pageLoadTimeout(1200, TimeUnit.SECONDS);
webDriver.manage().window().setSize(new Dimension(1024, 768));
return webDriver;
}
/**
* 搜索
*
* @param key 关键字
*/
public static void search(WebDriver driver, String key) {
driver.get("http://baidu.com/");
WebElement elementKey = driver.findElement(By.xpath("//*[@id=\"kw\"]"));
elementKey.sendKeys(key);
WebElement elementClick = driver.findElement(By.xpath("//*[@id=\"su\"]"));
elementClick.click();
}
}
4. 报错处理
unknown error: call function result missing 'value',网上关于这个错误的说法是chrome版本和driver的版本不一致,因此,笔者这里建议升级chrome,并下载对应的驱动。
Starting ChromeDriver 2.33.506120 (e3e53437346286c0bc2d2dc9aa4915ba81d9023f) on port 38667
Only local connections are allowed.
九月 13, 2019 2:27:01 下午 org.openqa.selenium.remote.ProtocolHandshake createSession
信息: Detected dialect: OSS
org.openqa.selenium.WebDriverException: unknown error: call function result missing 'value'
(Session info: chrome=76.0.3809.100)
(Driver info: chromedriver=2.33.506120 (e3e53437346286c0bc2d2dc9aa4915ba81d9023f),platform=Windows NT 10.0.17134 x86_64) (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 81 milliseconds
Build info: version: '3.4.0', revision: 'unknown', time: 'unknown'
System info: host: 'MicroWin10-2025', ip: '192.168.44.45', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '1.8.0_131'
Driver info: org.openqa.selenium.chrome.ChromeDriver
Capabilities [{applicationCacheEnabled=false, rotatable=false, mobileEmulationEnabled=false, networkConnectionEnabled=false, chrome={chromedriverVersion=2.33.506120 (e3e53437346286c0bc2d2dc9aa4915ba81d9023f), userDataDir=C:\Users\ADMINI~1\AppData\Local\Temp\scoped_dir8664_25666}, takesHeapSnapshot=true, pageLoadStrategy=normal, databaseEnabled=false, handlesAlerts=true, hasTouchScreen=false, version=76.0.3809.100, platform=XP, browserConnectionEnabled=false, nativeEvents=true, acceptSslCerts=true, locationContextEnabled=true, webStorageEnabled=true, browserName=chrome, takesScreenshot=true, javascriptEnabled=true, cssSelectorsEnabled=true, setWindowRect=true, unexpectedAlertBehaviour=}]
Session ID: 879a1a7546fff18bd185a2a8a54c6b48
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:215)
at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:167)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:671)
at org.openqa.selenium.remote.RemoteWebElement.execute(RemoteWebElement.java:272)
at org.openqa.selenium.remote.RemoteWebElement.sendKeys(RemoteWebElement.java:96)
at com.clawer.logintest.App.search(App.java:52)
at com.clawer.logintest.App.main(App.java:20)