Selenium数据爬取最近遇到的几个问题(Java)

一、日志

自己写项目,因为平时都是完成一些学生作业,所以很少会用到日志这个东西。有什么问题就直接在控制台打印出来了,但是Eclipse中Console控制台默认的输出空间是有限的,这样输出日志,不太可靠。所以还是需要采用正规的日志方法。

log4j

pache的开源项目log4j是一个功能强大的日志组件,提供方便的日志记录。在apache网站:jakarta.apache.org/log4j 可以免费下载到Log4j最新版本的软件包。

log4j.properties

我自己用的是Maven的项目,所以设置文件直接放置在这个位置就可以直接被编译。
Selenium数据爬取最近遇到的几个问题(Java)

log4j的具体使用说明

具体如何应用log4j 在这篇文章中说的很清晰了,大家可以移步去学习。
最详细的Log4J使用教程

另外的输出日志的方法

除了使用专业的日志包,我觉得在一些小型的项目中,还可以采用将控制台的内容输出打印到文本文件中的简易方法。更改System.out中的out对象,使其输出位置发生改变。

System.setOut(new PrintStream(new File(“D:/logs/myqscdata.txt”)));

在Main方法最开始的地方,加入这样一条代码,就可以使整个程序中打印在控制台的内容被输出的你想要的位置文件中了。在一些小型的程序中,不失为一种方便快捷的方法。

二、 Selenium中定位button的若干问题

Selenium数据爬取最近遇到的几个问题(Java)
网页中很多数据都是动态加载的,比如说我这里需要点击的这个查看全部动态的div。只有在我点击了这个button之后,服务器才会发来其他的用户发布的动态数据。这个时候浏览器准确的点击到这个元素就至关重要。
但是,Selenium点击元素的方法只会根据当前窗口的位置进行点击,也就是说,如果这个目标元素没有显示在当前的页面上,浏览器依然会发出点击行为,但是接受到这次click的元素就不一定是我们想要点击的那个元素了。也就会报出这样的错误。org.openqa.selenium.WebDriverException: unknown error: Element <span>...</span> is not clickable at point (458, 780). Other element would receive the click: <a class="finished-bar-link-item " href="https://huzhu2.qschou.com/html/pay/join-quickly.html?jam=yZP7Ax42&amp;cc=20001.v7_2.finalbanner_join_click">...</a> (Session info: chrome=70.0.3538.67) (Driver info: chromedriver=2.41.578737 (49da6702b16031c40d63e5618de03a32ff6c197e),platform=Windows NT 6.3.9600 x86_64) (WARNING: The server did not provide any stacktrace information) Command duration or timeout: 65 milliseconds Build info: version: '2.33.0', revision: '4ecaf82108b2a6cc6f006aae81961236eba93358', time: '2013-05-22 12:00:17' System info: os.name: 'Windows Server 2012 R2', os.arch: 'x86', os.version: '6.3', java.version: '1.8.0_181' Driver info: org.openqa.selenium.chrome.ChromeDriver Capabilities [{mobileEmulationEnabled=false, hasTouchScreen=false, platform=XP, acceptSslCerts=false, goog:chromeOptions={debuggerAddress=localhost:62188}, acceptInsecureCerts=false, webStorageEnabled=true, browserName=chrome, takesScreenshot=true, javascriptEnabled=true, setWindowRect=true, unexpectedAlertBehaviour=, applicationCacheEnabled=false, rotatable=false, networkConnectionEnabled=false, chrome={chromedriverVersion=2.41.578737 (49da6702b16031c40d63e5618de03a32ff6c197e), userDataDir=C:\Users\ADMINI~1\AppData\Local\Temp\2\scoped_dir6368_3892}, takesHeapSnapshot=true, pageLoadStrategy=normal, databaseEnabled=false, handlesAlerts=true, version=70.0.3538.67, browserConnectionEnabled=false, nativeEvents=true, locationContextEnabled=true, cssSelectorsEnabled=true}] Session ID: 4d08d762d6502950557852f2c4c11cad

解决方法

明白了问题的原理后,就可以对症下药,解决问题。浏览器解析网页中的元素的速度是超过显示速度的,意思是在网页中不一定会显示到这个元素的时候,浏览器就已经知道网页结构中会出现这个元素了。所以我们可以设置一个循环,循环体中不断下拉网页,当成功点击到我们想要的元素之后,break,跳出循环。否则catch错误,继续下拉网页,试图在执行click的时候成功定位到目标元素。`public WebElement GetDongTaiButton(WebDriver driver)
{

	for (int i=0;i<20;i++)
	{
		  ((JavascriptExecutor) driver).executeScript("window.scrollTo(0,1800)");
		  try {
			  Thread.sleep(5000);
			  WebElement button2=driver.findElement(By.xpath("/html/body/div[2]/div[3]/section[4]/section/div/div/div[2]/div[1]/div[1]/ul/div[1]/span"));
			  System.out.println("成功获取到按钮");	
			  WebElement finishbar=driver.findElement(By.xpath("/html/body/footer/div/div[1]/div[2]"));
			  finishbar.click();
			  button2.click();
		      System.out.println("成功点击到展开动态按钮");
		      return button2;
		     
		  }catch (Exception e) {
			  e.printStackTrace();
			  System.out.println("没有点击到按钮");
		}
		  
	}
	 return null;
}

在我的方法中,我设置了20次的下拉循环,只有当成功点击到展开动态的时候才跳出循环。执行结果是这样的:
Selenium数据爬取最近遇到的几个问题(Java)
浏览器会先获取到目标元素,但是获取到并不一定能够点击到。执行若干次下拉操作之后,成功click到目标元素!

三、 JDBC自动断开连接

Mysql的连接在8小时没用进行读写操作之后,会自动断开连接。由于我没用使用任何框架,所以只好在链接字符串处进行设置。

解决方法

mysql JDBC URL格式如下:

jdbc:mysql://[host:port],[host:port]…/[database][?参数名1][=参数值1][&参数名2][=参数值2]…
Selenium数据爬取最近遇到的几个问题(Java)
对应中文环境,通常mysql连接URL可以设置为:

jdbc:mysql://localhost:3306/test?user=root&password=&useUnicode=true&characterEncoding=gbk&autoReconnect=true&failOverReadOnly=false