多次尝试块
Multiple try block
我试图解决的问题是这样的:我试图从网页中抓取一些内容,我正在使用 selenium,findElementByClassName
来获取元素内容,并且它有效伟大到现在。但是考虑到我正在抓取的网站更改了 html 中的那些元素 类 之一,我不想让 could not find element exception
使其余代码无法执行和跳转直接进入捕获块。
我的想法是将每一行代码放入一个 try catch 块中,但是我想要抓取大约 15 个字段,这使得代码看起来很丑陋。自己看看:
String name = null;
String type = null;
String description = null;
try {
driver.get(link);
try {
name = driver.findElementByClassName(environment.getProperty("booking.propertyName")).getText();
}catch (Exception e){
log.error("error doing thing");
}
try {
type = driver.findElementByClassName(environment.getProperty("booking.propertyType")).getText();
}catch (Exception e){
log.error("error doing thing");
}
try {
description = driver.findElementByClassName(environment.getProperty("booking.propertyDescription")).getText();
}catch (Exception e){
log.error("error doing thing");
}
}catch (Exception e){
log.error("Error during scraping");
}
因此,如果其中一个出现问题,我仍然希望代码的其余部分继续执行,而不是在有一个 try-catch 块时,第一个失败的部分会阻止其他部分的执行。
上面的代码工作得很好,但它看起来不太好,所以我的问题是你有什么想法可以使它更好看吗?
没有灵丹妙药。但避免重复代码的标准方法是重构。例如:
try {
type = driver.findElementByClassName(environment.getProperty("something"))
.getText();
} catch (Exception e){
log.error("error doing thing");
}
可以改写为:
type = getElementTextIgnoringExceptions(driver, environment, "something");
其中 getElementTextIgnoringExceptions
定义如下:
public String getElementTextIgnoringExceptions(
Driver driver, Environment env, String name) {
try {
String className = env.getProperty(name);
return driver.findElementByClassName(className).getText();
} catch (Exception ex) {
log.error("error getting " + name, ex);
return null;
}
}
但是...您在此处尝试简化的代码有一些不好的地方:
- 赶上
Exception
不好。你不知道你会抓到什么,也不知道继续下去是否安全或明智。
- 不记录异常是不好的。如果您的日志文件中出现“操作错误”消息,您将如何诊断问题?
- 在异常之后继续(在您的应用程序的上下文中)可能会导致问题。您的代码的其余部分将充斥着
null
检查以处理无法获取的元素(或其他)。错过一张支票,您将有可能获得 NPE;例如在您的单元测试中未涵盖的某些 edge-case。
这些问题比让代码好看更重要。
如果您使用的是 Java 8+,则可以进行重构,以便将逻辑作为 lambda 表达式传递。这取决于所用变量的性质。
我试图解决的问题是这样的:我试图从网页中抓取一些内容,我正在使用 selenium,findElementByClassName
来获取元素内容,并且它有效伟大到现在。但是考虑到我正在抓取的网站更改了 html 中的那些元素 类 之一,我不想让 could not find element exception
使其余代码无法执行和跳转直接进入捕获块。
我的想法是将每一行代码放入一个 try catch 块中,但是我想要抓取大约 15 个字段,这使得代码看起来很丑陋。自己看看:
String name = null;
String type = null;
String description = null;
try {
driver.get(link);
try {
name = driver.findElementByClassName(environment.getProperty("booking.propertyName")).getText();
}catch (Exception e){
log.error("error doing thing");
}
try {
type = driver.findElementByClassName(environment.getProperty("booking.propertyType")).getText();
}catch (Exception e){
log.error("error doing thing");
}
try {
description = driver.findElementByClassName(environment.getProperty("booking.propertyDescription")).getText();
}catch (Exception e){
log.error("error doing thing");
}
}catch (Exception e){
log.error("Error during scraping");
}
因此,如果其中一个出现问题,我仍然希望代码的其余部分继续执行,而不是在有一个 try-catch 块时,第一个失败的部分会阻止其他部分的执行。 上面的代码工作得很好,但它看起来不太好,所以我的问题是你有什么想法可以使它更好看吗?
没有灵丹妙药。但避免重复代码的标准方法是重构。例如:
try {
type = driver.findElementByClassName(environment.getProperty("something"))
.getText();
} catch (Exception e){
log.error("error doing thing");
}
可以改写为:
type = getElementTextIgnoringExceptions(driver, environment, "something");
其中 getElementTextIgnoringExceptions
定义如下:
public String getElementTextIgnoringExceptions(
Driver driver, Environment env, String name) {
try {
String className = env.getProperty(name);
return driver.findElementByClassName(className).getText();
} catch (Exception ex) {
log.error("error getting " + name, ex);
return null;
}
}
但是...您在此处尝试简化的代码有一些不好的地方:
- 赶上
Exception
不好。你不知道你会抓到什么,也不知道继续下去是否安全或明智。 - 不记录异常是不好的。如果您的日志文件中出现“操作错误”消息,您将如何诊断问题?
- 在异常之后继续(在您的应用程序的上下文中)可能会导致问题。您的代码的其余部分将充斥着
null
检查以处理无法获取的元素(或其他)。错过一张支票,您将有可能获得 NPE;例如在您的单元测试中未涵盖的某些 edge-case。
这些问题比让代码好看更重要。
如果您使用的是 Java 8+,则可以进行重构,以便将逻辑作为 lambda 表达式传递。这取决于所用变量的性质。