【143】Java獲取HTML代碼中視頻video標籤的URL地址

創景

用戶使用HTML富文本編輯器編輯文章上傳到服務器。文章中可以嵌入視頻,視頻使用了H5的video 標籤,我需要提取出視頻的URL地址,用於做視頻鑑黃等操作。

代碼實現

本例子一共用了三個文件,分別是 RegexUtils.java、VideoTagUtils.java 和 Main.java。其中 RegexUtils 類封裝了正則表達式的操作。VideoTagUtils 提取視頻URL。Main 類包含main方法,用於測試。

RegexUtils.java

package blog141;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 正則表達式工具類
 * @author zhangchao
 */
public final class RegexUtils {
    /**
     * 獲得匹配正則表達式的內容
     * @param str 字符串
     * @param reg 正則表達式
     * @param isCaseInsensitive 是否忽略大小寫,true忽略大小寫,false大小寫敏感
     * @return 匹配正則表達式的字符串,組成的List
     */
    public static List<String> getMatchList(final String str, final String reg, final boolean isCaseInsensitive) {
        ArrayList<String> result = new ArrayList<String>();
        Pattern pattern = null;
        if (isCaseInsensitive) {
            //編譯正則表達式,忽略大小寫
            pattern = Pattern.compile(reg, Pattern.CASE_INSENSITIVE);
        } else {
            //編譯正則表達式,大小寫敏感
            pattern = Pattern.compile(reg);
        }
        Matcher matcher = pattern.matcher(str);// 指定要匹配的字符串
        while (matcher.find()) { //此處find()每次被調用後,會偏移到下一個匹配
            result.add(matcher.group());//獲取當前匹配的值
        }
        result.trimToSize();
        return result;
    }

    /**
     * 獲取第一個匹配正則表達式的子串
     * @param str 完整字符串
     * @param reg 正則表達式
     * @param isCaseInsensitive 是否忽略大小寫,true表示忽略,false表示大小寫敏感。
     * @return 第一個匹配正則表達式的子串。
     */
    public static String getFirstMatch(final String str, final String reg, final boolean isCaseInsensitive) {
        Pattern pattern = null;
        if (isCaseInsensitive) {
            //編譯正則表達式,忽略大小寫
            pattern = Pattern.compile(reg, Pattern.CASE_INSENSITIVE);
        } else {
            //編譯正則表達式,大小寫敏感
            pattern = Pattern.compile(reg);
        }
        Matcher matcher = pattern.matcher(str);// 指定要匹配的字符串
        if (matcher.find()) {
            return matcher.group();
        }
        return null;
    }
}

VideoTagUtils.java

package blog141;

import java.util.ArrayList;
import java.util.List;

/**
 * 處理視頻HTML標籤的工具類
 * @author zhangchao
 */
public final class VideoTagUtils {

    /**
     * 從html代碼中,獲得指定標籤的指定屬性的取值
     * @param html  HTML代碼
     * @param tagName  指定的標籤名稱
     * @param propertyName 指定的屬性名稱
     * @return
     */
    public static final List<String> listTagPropertyValue(final String html, final String tagName, final String propertyName) {
        // 結果集合
        ArrayList<String> result = new ArrayList<String>();
        // 找出HTML代碼中所有的tagName標籤
        List<String> list = RegexUtils.getMatchList(html, "<" + tagName + "[^>]*>", true);
        // 循環遍歷每個標籤字符串,找出其中的屬性字符串,比如 src=....
        for (String tagStr : list) {
            // 去掉標籤結尾的/>,方便後面 src 屬性的正則表達式。
            // 這樣可以適應  <video src=http://www.yourhost.com/xxx>  這樣的標籤
            if (tagStr.endsWith("/>")) {
                tagStr = tagStr.substring(0, tagStr.length() - 2);
                tagStr = tagStr + " ";
            }
            // 去掉標籤結尾的>,方便後面匹配屬性的正則表達式。
            // 這樣可以適應  <video src=http://www.yourhost.com/xxx>  這樣的標籤
            else if (tagStr.endsWith(">")) {
                tagStr = tagStr.substring(0, tagStr.length() - 1);
                tagStr = tagStr + " ";
            }
            // 去掉字符串開頭的 <video 或 <source
            tagStr = tagStr.substring(1 + tagName.length());
            tagStr = " " + tagStr;

            // 取出屬性的值
            String regSingleQuote = "^" + propertyName + "='[^']*'"; // 使用單引號
            String regDoubleQuote = "^" + propertyName + "=\"[^\"]*\""; // 使用雙引號
            String reg = "^" + propertyName + "=[^\\s]*\\s"; // 不使用引號
            int index = 0;
            int length = tagStr.length();
            while (index <= length) {
                String subStr = tagStr.substring(index);
                String str = RegexUtils.getFirstMatch(subStr, regSingleQuote, true);
                if (null != str) {
                    // 往後跳過已經匹配的字符串。
                    index += str.length();
                    String srcStr = str;
                    srcStr = srcStr.trim();
                    // 去掉 src=
                    srcStr = srcStr.substring(propertyName.length() + 1);
                    // 去掉單引號
                    srcStr = srcStr.substring(1);
                    srcStr = srcStr.substring(0, srcStr.length() - 1);
                    // 結果中加入圖片URL
                    result.add(srcStr);
                }
                else if ((str = RegexUtils.getFirstMatch(subStr, regDoubleQuote, true)) != null) {
                    // 往後跳過已經匹配的字符串。
                    index += str.length();
                    String srcStr = str;
                    srcStr = srcStr.trim();
                    // 去掉 src=
                    srcStr = srcStr.substring(propertyName.length() + 1);
                    // 去掉雙引號
                    srcStr = srcStr.substring(1);
                    srcStr = srcStr.substring(0, srcStr.length() - 1);
                    // 結果中加入圖片URL
                    result.add(srcStr);
                }
                else if ((str = RegexUtils.getFirstMatch(subStr, reg, true)) != null) {
                    // 往後跳過已經匹配的字符串。
                    index += str.length();
                    String srcStr = str;
                    srcStr = srcStr.trim();
                    // 去掉 src=
                    srcStr = srcStr.substring(propertyName.length() + 1);
                    // 結果中加入圖片URL
                    result.add(srcStr);
                }
                else if ((str = RegexUtils.getFirstMatch(subStr, "^[\\w]+='[^']*'", true)) != null) {
                    // 往後跳過已經匹配的字符串。
                    index += str.length();
                }
                else {
                    index ++;
                }
            }
        } // end for (String tagStr : list)
        result.trimToSize();
        return result;
    }


    /**
     * 從html代碼中找出video標籤的圖片路徑
     * @param html  HTML代碼
     * @return  字符串列表,裏面每個字符串都是圖片鏈接地址
     */
    public static List<String> listVideoSrc(final String html) {
        // 結果集合
        ArrayList<String> result = new ArrayList<String>();
        if (null == html || html.length() == 0 || html.trim().length() == 0) {
            return result;
        }
        List<String> videoSrcList = listTagPropertyValue(html, "video", "src");
        List<String> sourceSrcList = listTagPropertyValue(html, "source", "src");
        if (null != videoSrcList) {
            result.addAll(videoSrcList);
        }
        if (null != sourceSrcList) {
            result.addAll(sourceSrcList);
        }
        result.trimToSize();
        return result;
    }
}

Main.java

package blog141;

import java.util.List;

public final class Main {

    public static void main(String[] args) {
        String html = "<p>圖圖</p><video style='margin-top:5px' width=100% webkit-playsinline=true playsinline=true\n" +
                " controls poster='https://img.yiqilaiwang.com/lmrDJ01geGORjvKIAGbEWerQ9mMh?vframe/jpg/offset/0'>\n" +
                " <source aasrc='https://img.yiqilaiwang.com/lmrDJ01geGORjv' \nsrc=\"https://img.yiqilaiwang.com/lmrDJ01geGORjvKIAGbEWerQ9mMh\"type=video/mp4></video>" +
                "<Video style=\"width:100%\"src=\"/aaa/aaa.mp4\"></Video";
        List<String> list = VideoTagUtils.listVideoSrc(html);
        for (String str : list) {
            System.out.println(str);
        }
    }
}

程序運行結果:

/aaa/aaa.mp4
https://img.yiqilaiwang.com/lmrDJ01geGORjvKIAGbEWerQ9mMh
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章