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

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

How to navigate page from string html golang in chromedp

问题

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

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

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

答案1

得分: 2

有两种选项:

1. 从HTTP服务器提供内容

  1. package main
  2. import (
  3. "context"
  4. "log"
  5. "net/http"
  6. "net/http/httptest"
  7. "time"
  8. "github.com/chromedp/chromedp"
  9. )
  10. func main() {
  11. s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  12. w.Write([]byte("<h1>Hello World</h1>"))
  13. }))
  14. defer s.Close()
  15. opts := append(chromedp.DefaultExecAllocatorOptions[:],
  16. chromedp.Flag("headless", false),
  17. )
  18. ctx, cancel := chromedp.NewExecAllocator(context.Background(), opts...)
  19. defer cancel()
  20. ctx, cancel = chromedp.NewContext(ctx)
  21. defer cancel()
  22. if err := chromedp.Run(ctx,
  23. chromedp.Navigate(s.URL),
  24. chromedp.Sleep(10*time.Second),
  25. ); err != nil {
  26. log.Print(err)
  27. }
  28. }

2. 使用page.SetDocumentContent直接修改页面

  1. package main
  2. import (
  3. "context"
  4. "log"
  5. "time"
  6. "github.com/chromedp/cdproto/page"
  7. "github.com/chromedp/chromedp"
  8. )
  9. func main() {
  10. opts := append(chromedp.DefaultExecAllocatorOptions[:],
  11. chromedp.Flag("headless", false),
  12. )
  13. ctx, cancel := chromedp.NewExecAllocator(context.Background(), opts...)
  14. defer cancel()
  15. ctx, cancel = chromedp.NewContext(ctx)
  16. defer cancel()
  17. html := `<h1>Hello World</h1>`
  18. if err := chromedp.Run(ctx,
  19. chromedp.Navigate("about:blank"),
  20. chromedp.ActionFunc(func(ctx context.Context) error {
  21. frameTree, err := page.GetFrameTree().Do(ctx)
  22. if err != nil {
  23. return err
  24. }
  25. return page.SetDocumentContent(frameTree.Frame.ID, html).Do(ctx)
  26. }),
  27. chromedp.Sleep(10*time.Second),
  28. ); err != nil {
  29. log.Fatal(err)
  30. }
  31. }

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

英文:

There are two options:

1. Serve the content from an HTTP server

  1. package main
  2. import (
  3. &quot;context&quot;
  4. &quot;log&quot;
  5. &quot;net/http&quot;
  6. &quot;net/http/httptest&quot;
  7. &quot;time&quot;
  8. &quot;github.com/chromedp/chromedp&quot;
  9. )
  10. func main() {
  11. s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  12. w.Write([]byte(&quot;&lt;h1&gt;Hello World&lt;/h1&gt;&quot;))
  13. }))
  14. defer s.Close()
  15. opts := append(chromedp.DefaultExecAllocatorOptions[:],
  16. chromedp.Flag(&quot;headless&quot;, false),
  17. )
  18. ctx, cancel := chromedp.NewExecAllocator(context.Background(), opts...)
  19. defer cancel()
  20. ctx, cancel = chromedp.NewContext(ctx)
  21. defer cancel()
  22. if err := chromedp.Run(ctx,
  23. chromedp.Navigate(s.URL),
  24. chromedp.Sleep(10*time.Second),
  25. ); err != nil {
  26. log.Print(err)
  27. }
  28. }

2. Use page.SetDocumentContent to modify the page directly

  1. package main
  2. import (
  3. &quot;context&quot;
  4. &quot;log&quot;
  5. &quot;time&quot;
  6. &quot;github.com/chromedp/cdproto/page&quot;
  7. &quot;github.com/chromedp/chromedp&quot;
  8. )
  9. func main() {
  10. opts := append(chromedp.DefaultExecAllocatorOptions[:],
  11. chromedp.Flag(&quot;headless&quot;, false),
  12. )
  13. ctx, cancel := chromedp.NewExecAllocator(context.Background(), opts...)
  14. defer cancel()
  15. ctx, cancel = chromedp.NewContext(ctx)
  16. defer cancel()
  17. html := `&lt;h1&gt;Hello World&lt;/h1&gt;`
  18. if err := chromedp.Run(ctx,
  19. chromedp.Navigate(&quot;about:blank&quot;),
  20. chromedp.ActionFunc(func(ctx context.Context) error {
  21. frameTree, err := page.GetFrameTree().Do(ctx)
  22. if err != nil {
  23. return err
  24. }
  25. return page.SetDocumentContent(frameTree.Frame.ID, html).Do(ctx)
  26. }),
  27. chromedp.Sleep(10*time.Second),
  28. ); err != nil {
  29. log.Fatal(err)
  30. }
  31. }

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

答案2

得分: 0

这对我来说很好..非常感谢关键字@Zeke Lu

  1. package main
  2. import (
  3. "context"
  4. "log"
  5. "github.com/chromedp/cdproto/page"
  6. "github.com/chromedp/chromedp"
  7. )
  8. func main() {
  9. opts := append(chromedp.DefaultExecAllocatorOptions[:],
  10. chromedp.Flag("headless", false),
  11. )
  12. ctx, cancel := chromedp.NewExecAllocator(context.Background(), opts...)
  13. defer cancel()
  14. ctx, cancel = chromedp.NewContext(ctx)
  15. defer cancel()
  16. htmlContent := `<h1>Hello World</h1>`
  17. if err := chromedp.Run(ctx,
  18. chromedp.Navigate("about:blank"),
  19. loadHTMLFromStringActionFunc(htmlContent),
  20. ); err != nil {
  21. log.Fatal(err)
  22. }
  23. }
  24. func loadHTMLFromStringActionFunc(content string) chromedp.ActionFunc {
  25. return chromedp.ActionFunc(func(ctx context.Context) error {
  26. ch := make(chan bool, 1)
  27. defer close(ch)
  28. go chromedp.ListenTarget(ctx, func(ev interface{}) {
  29. if _, ok := ev.(*page.EventLoadEventFired); ok {
  30. ch <- true
  31. }
  32. })
  33. frameTree, err := page.GetFrameTree().Do(ctx)
  34. if err != nil {
  35. return err
  36. }
  37. if err := page.SetDocumentContent(frameTree.Frame.ID, content).Do(ctx); err != nil {
  38. return err
  39. }
  40. select {
  41. case <-ch:
  42. return nil
  43. case <-ctx.Done():
  44. return context.DeadlineExceeded
  45. }
  46. })
  47. }
英文:

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

  1. package main
  2. import (
  3. &quot;context&quot;
  4. &quot;log&quot;
  5. &quot;github.com/chromedp/cdproto/page&quot;
  6. &quot;github.com/chromedp/chromedp&quot;
  7. )
  8. func main() {
  9. opts := append(chromedp.DefaultExecAllocatorOptions[:],
  10. chromedp.Flag(&quot;headless&quot;, false),
  11. )
  12. ctx, cancel := chromedp.NewExecAllocator(context.Background(), opts...)
  13. defer cancel()
  14. ctx, cancel = chromedp.NewContext(ctx)
  15. defer cancel()
  16. htmlContent := `&lt;h1&gt;Hello World&lt;/h1&gt;`
  17. if err := chromedp.Run(ctx,
  18. chromedp.Navigate(&quot;about:blank&quot;),
  19. loadHTMLFromStringActionFunc(htmlContent),
  20. ); err != nil {
  21. log.Fatal(err)
  22. }
  23. }
  24. func loadHTMLFromStringActionFunc(content string) chromedp.ActionFunc {
  25. return chromedp.ActionFunc(func(ctx context.Context) error {
  26. ch := make(chan bool, 1)
  27. defer close(ch)
  28. go chromedp.ListenTarget(ctx, func(ev interface{}) {
  29. if _, ok := ev.(*page.EventLoadEventFired); ok {
  30. ch &lt;- true
  31. }
  32. })
  33. frameTree, err := page.GetFrameTree().Do(ctx)
  34. if err != nil {
  35. return err
  36. }
  37. if err := page.SetDocumentContent(frameTree.Frame.ID, content).Do(ctx); err != nil {
  38. return err
  39. }
  40. select {
  41. case &lt;-ch:
  42. return nil
  43. case &lt;-ctx.Done():
  44. return context.DeadlineExceeded
  45. }
  46. })
  47. }

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:

确定