简介
写过爬虫的朋友一定遇到过这样一个问题:网页的部分内容是由js(ajax)技术生成的,而这部分内容恰恰是我们想要的,并且这个ajax请求的url或者生成的cookie信息我们很难拿到。
普通的爬虫工具例如HttpClient只能模拟http发送请求,我们无法拿到url或者cookie,所以当然也无法拿到动态网页内容;htmlunit具有js渲染的功能,某些场景下使用htmlunit是一个比较合适的选择,但是 htmlunit对于某些复杂js却显得无能为力,关于htmlunit的使用,我们会在另外一篇博客中详细叙述。
Selenium,作为一个Web应用程序测试的工具,功能显然更加强大。Selenium的核心Selenium Core基于JsUnit,完全由 JavaScript编写,因此可运行于任何支持JavaScript的浏览器上。显然,Selenium非常适合解决上述我们提到的动态网页加载问题。
这里我们主要讲一下Selenium如何在java平台上使用、以及一些使用过程中出现的坑。
入门
环境搭建
首先我们要准备一些jar包,里面有一些api可供我们使用,具体如下:
commons-codec-1.9.jar commons-collections-3.2.1.jar commons-exec-1.1.jar commons-io-2.4.jar commons-lang3-3.3.2.jar commons-logging-1.1.3.jar cssparser-0.9.14.jar guava-15.0.jar httpclient-4.3.4.jar httpcore-4.3.2.jar httpmime-4.3.3.jar jna-3.4.0.jar phantomjsdriver-1.2.0.jar selenium-api-2.41.0.jar selenium-chrome-driver-2.44.0.jar selenium-firefox-driver-2.44.0.jar selenium-htmlunit-driver-2.44.0.jar selenium-ie-driver-2.44.0.jar selenium-java-2.44.0.jar selenium-remote-driver-2.41.0.jar selenium-safari-driver-2.44.0.jar selenium-support-2.44.0.jar |
其中版本是我自己选取,若要使用其他版本,大家可以自己尝试哦。
2. 由于Selenium可以操作各种浏览器进行测试,所以在使用之前我们需要在电脑上安装对应的浏览器。注意,Selenium版本与浏览器版本不一定兼容,以下是FireFox和Chrome具体对应版本:
FireFox:
2.25.0 -> 18 2.30.0 -> 19 2.31.0 -> 20 2.42.2 -> 29 2.44.0 -> 33 (不支持31) 2.53.0 -> 43,46(不支持47) 2.41.0 -> 26(绿色版本) 2.44 -> 32.0-35.0 2.53.0-2.53.6 -> 40.0.3 |
Chrome:
2.29 -> 56-58 2.28 -> 55-57 2.27 -> 54-56 2.26 -> 53-55 2.25 -> 53-55 2.24 -> 52-54 2.23 -> 51-53 2.22 -> 49-52 2.21 -> 46-50 2.20 -> 43-48 2.19 -> 43-47 2.18 -> 43-46 2.17 -> 42-43 2.13 -> 42-45 2.15 -> 40-43 2.14 -> 39-42 2.13 -> 38-41 2.12 -> 36-40 2.11 -> 36-40 2.10 -> 33-36 2.9 -> 31-34 2.8 -> 30-33 2.7 -> 30-33 2.6 -> 29-32 2.5 -> 29-32 2.4 -> 29-32 |
java环境搭建部分此处略过。打开Eclipse,新建Java Project,取名selenium_demo,然后将下载的jar包导入工程。至此,环境搭建完毕。
代码实现
1.使用Selenium新建一个浏览器(这里以火狐浏览器为例,我这里是mac操作系统):
String browserPath = "/Applications/Firefox.app/Contents/MacOS/firefox"; System.setProperty("webdriver.firefox.bin", browserPath); WebDriver driver = new FirefoxDriver(); |
其中browserPath是火狐浏览器的驱动路径。如果要新建一个PhantomJs浏览器,则代码如下:
String browserPath = "/opt/app/PhantomJS/phantomjs-2.1.1-linux-x86_64/bin/phantomjs"; System.setProperty("phantomjs.binary.path", browserPath); WebDriver driver = new PhantomJSDriver(); |
2.为Selenium设置代理:
FireFox:
String proxyIp = "10.10.10.1"; int proxyPort = 80; FirefoxProfile profile = new FirefoxProfile(); profile.setPreference("network.proxy.type", 1); profile.setPreference("network.proxy.http", proxyIp); profile.setPreference("network.proxy.http_port", proxyPort); profile.setPreference("network.proxy.ssl", proxyIp); profile.setPreference("network.proxy.ssl_port", proxyPort); WebDriver driver = new FirefoxDriver(profile); |
PhantomJs:
DesiredCapabilities desiredCapabilities = DesiredCapabilities.phantomjs(); Proxy proxy = new Proxy(); proxy.setProxyType(org.openqa.selenium.Proxy.ProxyType.MANUAL); proxy.setAutodetect(false); String proxyIp = "10.10.10.1"; int proxyPort = 80; proxy.setHttpProxy(proxyIp + ":" + proxyPort); desiredCapabilities.setCapability(CapabilityType.PROXY, proxy); WebDriver driver = new PhantomJSDriver(desiredCapabilities); |
3.打开一个url并获取对应的网页源码:
String url = "http://www.baidu.com"; driver.get(url); String pageSource = driver.getPageSource(); System.out.println(pageSource); |
4.浏览器窗口最大化:
driver.manage().window().maximize(); |
5.定位某个元素:
根据ID定位元素: WebElement ele = driver.findElement(By.id("id")); 根据Class定位元素: WebElement ele = driver.findElement(By.className("className")); 根据xpath定位元素: WebElement ele = driver.findElement(By.xpath("xpath")); |
6.向表单填数据:
WebElement ele = driver.findElement(By.id("id")); ele.clear(); ele.sendKeys("str"); |
7.触发元素的点击事件:
WebElement ele = driver.findElement(By.id("id")); ele.click(); |
一些坑
使用find_element_by_xxxx()方法查找元素时,如果元素找不到,不会返回null,而是抛出异常,所以需要自己捕获异常。
使用firefox后,很多选项虽然在浏览器中进行了设置,但是通过selenium启动firefox后,设置并没有生效,所以这些设置你需要在代码中添加。
使用WebDriver点击Button元素时,如果Button元素其他元素遮住了,或没出现在界面中(比如Button在页面底部,但是屏幕只能显示页面上半部分),使用Click()方法可能无法触发Click事件。
上文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理。