【问题标题】:Extract images using jsoup that have no img tag使用 jsoup 提取没有 img 标签的图像
【发布时间】:2018-07-24 20:50:32
【问题描述】:

我需要提取 div 中的图像,并且 src 未在 img 标记中列出。我也不能做 getElementById() ,因为它因页面而异。对于这种情况,我可以使用一些正则表达式从文档中提取图像吗?任何帮助表示赞赏。

HTML sn-p:

<div 
    class="rendition-bg rendition-bg--alignment desktop-center-center mobile-center-center" 
    data-src="/content/dam/Image.jpg.transform/default- 
mobile/image.jpg" 
    data-mobile-rendition="/content/dam/Image.jpg.transform/default-mobile/image.jpg" 
    data-tablet-rendition="/content/dam/Image.jpg.transform/default-mobile/image.jpg" 
    data-desktop- rendition="/content/dam/Image.jpg.transform/default-desktop/image.jpg" 
    style="background-image: url(&quot;/content/dam/Image.jpg.transform/default- 
mobile/image.jpg&quot;);">
</div>

【问题讨论】:

  • 您是否要提取 div attrs 中所有图像的路径以及“.jpg”之后的“转换”是什么?你想怎么对待他们?它们是否应该被视为下一条路径的一部分?还是作为分隔符扔掉?
  • @GaponenkoAndrei 是的,我想提取所有路径,只要它们是图像。 “变换”部分可以扔掉。

标签: java html jsoup


【解决方案1】:

远非优雅或简单的解决方案,但这里有一些东西,希望能给你一些开始:

    String snippet =
      "<div class=\"rendition-bg rendition-bg--alignment desktop-center-center" +
        "mobile-center-center \" data-src=\"/content/dam/Image.jpg.transform/default-" +
        "mobile/image.jpg\" data-mobile- \n" +
        "rendition=\"/content/dam/Image.jpg.transform/default-mobile/image.jpg\" data-" +
        "tablet-rendition=\"/content/dam/Image.jpg.transform/default-mobile/image.jpg\"" +
        "data-desktop- rendition=\"/content/dam/Image.jpg.transform/default-desktop/image.jpg\"" +
        "style=\"background-image: url(&quot;/content/dam/Image.jpg.transform/default-" +
        "mobile/image.jpg&quot;);\"></div>";

    List<String> imgAttrs =
      Jsoup.parse(snippet)
        .getElementsByTag("div")
        .stream()
        // get lists of attributes
        .map(Element::attributes)
        // flatten all attrs to single list
        .flatMap(attrs -> attrs.asList().stream())
        // filter attributes
        .filter(attribute -> attribute.getValue() != null && attribute.getValue().contains(".jpg"))
        // map to values
        .map(Attribute::getValue)
        // replace all ".transform" with a whitespace
        .map(attrValue -> attrValue.replace(".transform", " "))
        // get url value of a "background-image"
        .map(attrValue -> getUrlFromBackgroundImage(attrValue))
        // split attributes by whitespaces
        .flatMap(attrValue -> Stream.of(attrValue.split(" ")))
        .collect(toList());
      }

     private static String getUrlFromBackgroundImage(final String backgroundImage) {
        Pattern pattern = Pattern.compile("background-image:[ ]?url\\((['\"]?(.*?\\.(?:png|jpg|jpeg|gif)(\\s)?)*)");
        Matcher matcher = pattern.matcher(backgroundImage);
        return matcher.find() ? matcher.group(1) : backgroundImage;
     }

imgAttrs 的内容应该是:

/content/dam/Image.jpg
/default-mobile/image.jpg
/content/dam/Image.jpg
/default-desktop/image.jpg
/content/dam/Image.jpg
/default-mobile/image.jpg
"/content/dam/Image.jpg
/default-mobile/image.jpg

不确定这是否是您需要的。

【讨论】:

    【解决方案2】:

    仔细观察 div,我们可以看到引用了 2 张图片。他们是

    data-src=                  "/content/dam/Image.jpg.transform/default-mobile/image.jpg" 
    data-mobile-rendition=     "/content/dam/Image.jpg.transform/default-mobile/image.jpg" 
    data-tablet-rendition=     "/content/dam/Image.jpg.transform/default-mobile/image.jpg" 
    data-desktop- rendition=   "/content/dam/Image.jpg.transform/default-desktop/image.jpg" 
    style="background-image: url/content/dam/Image.jpg.transform/default-mobile/image.jpg
    

    在这四个图像引用中,有 3 个是指同一个图像,而另一个是指桌面 ~ 图像。所以如果我们需要提取这两张图片的URL:

    data-src=                  "/content/dam/Image.jpg.transform/default-mobile/image.jpg" 
    data-desktop- rendition=   "/content/dam/Image.jpg.transform/default-desktop/image.jpg"
    

    我们可以使用以下代码:

            Elements els = doc.select("div.rendition-bg");
            for (Element ele :els){
                    System.out.println(ele.absUrl("data-src"));
                    System.out.println(ele.absUrl("data-desktop-"));                
                }
    

    如果我正确理解了您的要求,请告诉我。

    【讨论】:

      【解决方案3】:

      cmets 中的解释:

          Document doc = Jsoup.parse(
              "<div class=\"rendition-bg rendition-bg--alignment desktop-center-center mobile-center-center \" "
              + "data-src=\"/content/dam/Image.jpg.transform/default-mobile/image.jpg\" "
              + "data-mobile-rendition=\"/content/dam/Image.jpg.transform/default-mobile/image.jpg\" "
              + "data-tablet-rendition=\"/content/dam/Image.jpg.transform/default-mobile/image.jpg\" "
              + "data-desktop-rendition=\"/content/dam/Image.jpg.transform/default-desktop/image.jpg\" "
              + "style=\"background-image: url(&quot;/content/dam/Image.jpg.transform/default-mobile/image.jpg&quot;);\"></div>");
      
          // select all elements with "data-src" attribute, but here we use only the first of them
          Map<String, String> dataAttributes = doc.select("[data-src]").first().dataset();
      
          // here we have all data attributes of this element:
          System.out.println(dataAttributes);
      
          // you can access them like this:
          System.out.println(dataAttributes.get("mobile-rendition"));
          System.out.println(dataAttributes.get("tablet-rendition"));
          System.out.println(dataAttributes.get("desktop-rendition"));
      
          // split and create list of urls (contains duplicates)
          List<String> urls = dataAttributes.entrySet().stream().flatMap(e -> Stream.of(e.getValue().split("\\.transform")))
                      .collect(Collectors.toList());
      
          // if you need only unique urls use this one instead:
          //  Set<String> urls = dataAttributes.entrySet().stream().flatMap(e -> Stream.of(e.getValue().split(".transform"))).collect(Collectors.toSet());
          System.out.println(urls);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-02-01
        • 2019-09-29
        相关资源
        最近更新 更多