多次尝试块

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;
     }
 }

但是...您在此处尝试简化的代码有一些不好的地方:

  1. 赶上 Exception 不好。你不知道你会抓到什么,也不知道继续下去是否安全或明智
  2. 不记录异常是不好的。如果您的日志文件中出现“操作错误”消息,您将如何诊断问题?
  3. 在异常之后继续(在您的应用程序的上下文中)可能会导致问题。您的代码的其余部分将充斥着 null 检查以处理无法获取的元素(或其他)。错过一张支票,您将有可能获得 NPE;例如在您的单元测试中未涵盖的某些 edge-case。

这些问题比让代码好看更重要。


如果您使用的是 Java 8+,则可以进行重构,以便将逻辑作为 lambda 表达式传递。这取决于所用变量的性质。