如何在Golang中使用chromedp从字符串HTML导航页面

huangapple go评论98阅读模式
英文:

How to navigate page from string html golang in chromedp

问题

如何在不将x保存为文件的情况下,使用chromedp导航到x

英文:
var x = `<h1>Hello World</h1>`

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

答案1

得分: 2

有两种选项:

1. 从HTTP服务器提供内容

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. 使用page.SetDocumentContent直接修改页面

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

请参阅https://github.com/chromedp/chromedp/issues/941#issuecomment-961181348

英文:

There are two options:

1. Serve the content from an HTTP server

package main

import (
	&quot;context&quot;
	&quot;log&quot;
	&quot;net/http&quot;
	&quot;net/http/httptest&quot;
	&quot;time&quot;

	&quot;github.com/chromedp/chromedp&quot;
)

func main() {
	s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte(&quot;&lt;h1&gt;Hello World&lt;/h1&gt;&quot;))
	}))
	defer s.Close()

	opts := append(chromedp.DefaultExecAllocatorOptions[:],
		chromedp.Flag(&quot;headless&quot;, 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 (
	&quot;context&quot;
	&quot;log&quot;
	&quot;time&quot;

	&quot;github.com/chromedp/cdproto/page&quot;
	&quot;github.com/chromedp/chromedp&quot;
)

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

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

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

	html := `&lt;h1&gt;Hello World&lt;/h1&gt;`
	if err := chromedp.Run(ctx,
		chromedp.Navigate(&quot;about:blank&quot;),
		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

答案2

得分: 0

这对我来说很好..非常感谢关键字@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
		}
	})
}
英文:

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

package main
import (
&quot;context&quot;
&quot;log&quot;
&quot;github.com/chromedp/cdproto/page&quot;
&quot;github.com/chromedp/chromedp&quot;
)
func main() {
opts := append(chromedp.DefaultExecAllocatorOptions[:],
chromedp.Flag(&quot;headless&quot;, false),
)
ctx, cancel := chromedp.NewExecAllocator(context.Background(), opts...)
defer cancel()
ctx, cancel = chromedp.NewContext(ctx)
defer cancel()
htmlContent := `&lt;h1&gt;Hello World&lt;/h1&gt;`
if err := chromedp.Run(ctx,
chromedp.Navigate(&quot;about:blank&quot;),
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 &lt;- 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 &lt;-ch:
return nil
case &lt;-ctx.Done():
return context.DeadlineExceeded
}
})
}

huangapple
  • 本文由 发表于 2022年8月18日 21:52:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/73404279.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定