Skip to content

メディア抽出実践

テキスト、画像、リンクに加えて、ライブラリは HTML から動画と音声リソースを抽出できます。本ガイドでは抽出メカニズムとフィールドの意味を詳しく解説します。

抽出の概要

Extract を呼び出す際、動画と音声の抽出は DOM パースの後、コンテンツのフォーマット前に実行されます。結果はそれぞれ Result.VideosResult.Audios に格納されます。

text
DOM パース → 動画抽出(3 ソース) → 音声抽出(2 ソース) → フォーマット → Result

動画抽出(3 つのソース)

動画抽出は以下の順序で実行され、各 URL は重複排除されるため、重複して収集されることはありません:

順序ソース走査対象説明
生 HTML スキャンiframe/embed/objectsrc/data 属性安全なサニタイズの前に実行され、サニタイズされる埋め込みタグが失われないようにします
DOM 走査video/iframe/embed/object 要素パースされた DOM ツリーを走査し、要素の属性と <source> 子要素を読み取ります
正規表現フォールバック動画ファイル URLHTML テキスト内の裸の動画リンクをスキャンします

なぜ生 HTML をスキャンするのか

iframeembedobject などの埋め込みタグは、安全なサニタイズ段階で削除される可能性があります。ライブラリはサニタイズの前に、生 HTML 文字列からこれらのタグのメディア URL を抽出することで、埋め込み動画がサニタイズによって失われないようにします。

正規表現フォールバックが対応する動画拡張子

.mp4  .webm  .ogg  .mov  .avi  .wmv  .flv  .mkv  .m4v  .3gp

正規表現は http:// または https:// で始まる完全な URL のみをマッチし、ファイル名の断片を誤ってマッチすることはありません。

音声抽出(2 つのソース)

順序ソース走査対象説明
DOM 走査audio 要素および <source> 子要素src 属性または子 <source>src/type を読み取ります
正規表現フォールバック音声ファイル URLHTML テキスト内の裸の音声リンクをスキャンします

正規表現フォールバックが対応する音声拡張子

.mp3  .wav  .ogg  .m4a  .aac  .flac  .wma  .opus  .oga

.ogg 拡張子は動画と音声の両方のリストに含まれます

OGG はコンテナフォーマットであり、動画(Theora)または音声(Vorbis/Opus)を格納できます。拡張子 .ogg の URL は動画でも音声でもあると検出され、Result.VideosResult.Audios の両方に同時に現れる可能性があります。音声専用のバリアント .oga は音声リストにのみ現れます。

フィールドの詳細

VideoInfo

フィールド説明
URLstring動画ソースのアドレス
Typestring検出されたタイプ:MIME タイプ(例:video/mp4)または embed(iframe で埋め込まれたページ)
Posterstring<video>poster 属性(カバー画像の URL)
Widthstring幅属性(元の文字列、数値にはパースされません)
Heightstring高さ属性(元の文字列、数値にはパースされません)
Durationstring再生時間属性(元の文字列、数値にはパースされません)

AudioInfo

フィールド説明
URLstring音声ソースのアドレス
Typestring検出されたタイプ:MIME タイプ(例:audio/mpeg
Durationstring再生時間属性(元の文字列、数値にはパースされません)

Type フィールドの値の決定ルール

Type は 2 種類の動画ソースを区別します:

Type の値意味発生するシーン
embediframe が参照する動画ページYouTube、Vimeo、Youku、Bilibili などの埋め込みプレーヤー
MIME タイプ(例:video/mp4動画ファイルコンテナ正規表現フォールバックでマッチした裸の URL、または <source type="..."> 属性値
空文字列タイプが検出されなかった<video src="..."> でソースを直接指定(<source> 子要素がない場合)

embed 検出に対応する埋め込みプラットフォーム:

プラットフォームURL パターン
YouTubeyoutube.com/embed/youtube-nocookie.com/embed/
Vimeoplayer.vimeo.com/video/
Dailymotiondailymotion.com/embed/
Youkuplayer.youku.com/
Tencent Videov.qq.com/
Bilibilibilibili.com/

完全なサンプル

go
package main

import (
    "fmt"
    "log"

    "github.com/cybergodev/html"
)

func main() {
    // 3 つのメディアシナリオを含む HTML:
    // 1. iframe による YouTube 埋め込み(Type = "embed")
    // 2. <source> 子要素を持つネイティブ動画(Type は type 属性から取得)
    // 3. <source> 子要素を持つ音声(Type は type 属性から取得)
    data := []byte(`<html><body><article>
        <h1>マルチメディアページ</h1>
        <p>この記事では動画と音声の技術について紹介します。</p>
        <iframe src="https://www.youtube.com/embed/dQw4w9WgXcQ" width="560" height="315"></iframe>
        <video poster="poster.jpg" width="640" height="360">
            <source src="https://example.com/trailer.mp4" type="video/mp4">
        </video>
        <audio>
            <source src="https://example.com/episode.mp3" type="audio/mpeg">
        </audio>
    </article></body></html>`)

    result, err := html.Extract(data)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("動画数:%d\n", len(result.Videos))
    // 動画数:2

    for i, v := range result.Videos {
        fmt.Printf("  動画 %d: %s\n", i+1, v.URL)
        fmt.Printf("    Type: %s", v.Type)
        if v.Poster != "" {
            fmt.Printf(", ポスター: %s", v.Poster)
        }
        if v.Width != "" || v.Height != "" {
            fmt.Printf(", サイズ: %sx%s", v.Width, v.Height)
        }
        fmt.Println()
    }
    // 動画 1: https://www.youtube.com/embed/dQw4w9WgXcQ
    //   Type: embed, サイズ: 560x315
    // 動画 2: https://example.com/trailer.mp4
    //   Type: video/mp4, ポスター: poster.jpg, サイズ: 640x360

    fmt.Printf("\n音声数:%d\n", len(result.Audios))
    // 音声数:1

    for i, a := range result.Audios {
        fmt.Printf("  音声 %d: %s (Type: %s)\n", i+1, a.URL, a.Type)
    }
    // 音声 1: https://example.com/episode.mp3 (Type: audio/mpeg)
}

設定による制御

Preserve* オプション

PreserveVideosPreserveAudiosExtract の結果にメディアを含めるかどうかを制御します:

設定フィールドデフォルト値機能
PreserveVideostruefalse の場合 Result.Videos は空のスライスになります
PreserveAudiostruefalse の場合 Result.Audios は空のスライスになります
go
cfg := html.DefaultConfig()

// 動画と音声の抽出を無効化(テキスト、画像、リンクのみ保持)
cfg.PreserveVideos = false
cfg.PreserveAudios = false

result, err := html.Extract(data, cfg)
// result.Videos → []
// result.Audios → []

Preserve* と Include* の違い

2 つの設定グループは独立して動作し、異なる API を制御します:

設定グループ制御する API説明
PreserveVideos/PreserveAudiosExtractResult.Videos/Result.Audios にデータを格納するかどうかを制御
IncludeVideos/IncludeAudiosExtractAllLinksリンク列挙に動画/音声 URL を含めるかどうかを制御

両者は独立しています

PreserveVideos を無効にしても ExtractAllLinksIncludeVideos には影響せず、逆も同様です。使用する API に応じて対応するオプションを設定してください。

TextOnlyConfig パフォーマンスプリセット

テキストのみが必要な場合、TextOnlyConfig() はすべての Preserve* オプションを無効化済みのため、手動設定は不要です:

go
cfg := html.TextOnlyConfig()
// PreserveImages = false
// PreserveLinks = false
// PreserveVideos = false
// PreserveAudios = false

result, err := html.Extract(data, cfg)
// すべてのメディア抽出をスキップし、最高のパフォーマンスを得る

次のステップ