Haryo Bagas Assyafah
Haryo Bagas Assyafah

Reputation: 61

How to navigate page from string html golang in chromedp

var x = `<h1>Hello World</h1>`

How to navigate chromedp to x without saving x as file?

Upvotes: 1

Views: 795

Answers (2)

Haryo Bagas Assyafah
Haryo Bagas Assyafah

Reputation: 61

This works fine for me.. thanks a lot for the keyword @Zeke Lu

package main

import (
    "context"
    "log"

    "github.com/chromedp/cdproto/page"
    "github.com/chromedp/chromedp"
)

func main() {
    opts := append(chromedp.DefaultExecAllocatorOptions[:],
        chromedp.Flag("headless", false),
    )

    ctx, cancel := chromedp.NewExecAllocator(context.Background(), opts...)
    defer cancel()

    ctx, cancel = chromedp.NewContext(ctx)
    defer cancel()

    htmlContent := `<h1>Hello World</h1>`
    if err := chromedp.Run(ctx,
        chromedp.Navigate("about:blank"),
        loadHTMLFromStringActionFunc(htmlContent),
    ); err != nil {
        log.Fatal(err)
    }
}

func loadHTMLFromStringActionFunc(content string) chromedp.ActionFunc {
    return chromedp.ActionFunc(func(ctx context.Context) error {
        ch := make(chan bool, 1)
        defer close(ch)

        go chromedp.ListenTarget(ctx, func(ev interface{}) {
            if _, ok := ev.(*page.EventLoadEventFired); ok {
                ch <- true
            }
        })

        frameTree, err := page.GetFrameTree().Do(ctx)
        if err != nil {
            return err
        }

        if err := page.SetDocumentContent(frameTree.Frame.ID, content).Do(ctx); err != nil {
            return err
        }

        select {
        case <-ch:
            return nil
        case <-ctx.Done():
            return context.DeadlineExceeded
        }
    })
}

Upvotes: 0

Zeke Lu
Zeke Lu

Reputation: 7475

There are two options:

1. Serve the content from an HTTP server

package main

import (
    "context"
    "log"
    "net/http"
    "net/http/httptest"
    "time"

    "github.com/chromedp/chromedp"
)

func main() {
    s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("<h1>Hello World</h1>"))
    }))
    defer s.Close()

    opts := append(chromedp.DefaultExecAllocatorOptions[:],
        chromedp.Flag("headless", false),
    )

    ctx, cancel := chromedp.NewExecAllocator(context.Background(), opts...)
    defer cancel()

    ctx, cancel = chromedp.NewContext(ctx)
    defer cancel()

    if err := chromedp.Run(ctx,
        chromedp.Navigate(s.URL),
        chromedp.Sleep(10*time.Second),
    ); err != nil {
        log.Print(err)
    }
}

2. Use page.SetDocumentContent to modify the page directly

package main

import (
    "context"
    "log"
    "time"

    "github.com/chromedp/cdproto/page"
    "github.com/chromedp/chromedp"
)

func main() {
    opts := append(chromedp.DefaultExecAllocatorOptions[:],
        chromedp.Flag("headless", false),
    )

    ctx, cancel := chromedp.NewExecAllocator(context.Background(), opts...)
    defer cancel()

    ctx, cancel = chromedp.NewContext(ctx)
    defer cancel()

    html := `<h1>Hello World</h1>`
    if err := chromedp.Run(ctx,
        chromedp.Navigate("about:blank"),
        chromedp.ActionFunc(func(ctx context.Context) error {
            frameTree, err := page.GetFrameTree().Do(ctx)
            if err != nil {
                return err
            }
            return page.SetDocumentContent(frameTree.Frame.ID, html).Do(ctx)
        }),
        chromedp.Sleep(10*time.Second),
    ); err != nil {
        log.Fatal(err)
    }
}

See https://github.com/chromedp/chromedp/issues/941#issuecomment-961181348

Upvotes: 2

Related Questions