/example_test.go
https://github.com/mafredri/cdp · Go · 139 lines · 103 code · 24 blank · 12 comment · 35 complexity · b22b34315ecaa8c8d6fb31b3d0fcba0f MD5 · raw file
- package cdp_test
- import (
- "bufio"
- "context"
- "fmt"
- "io/ioutil"
- "log"
- "os"
- "time"
- "github.com/mafredri/cdp"
- "github.com/mafredri/cdp/devtool"
- "github.com/mafredri/cdp/protocol/dom"
- "github.com/mafredri/cdp/protocol/page"
- "github.com/mafredri/cdp/rpcc"
- )
- func Example() {
- err := run(5 * time.Second)
- if err != nil {
- log.Fatal(err)
- }
- }
- func run(timeout time.Duration) error {
- ctx, cancel := context.WithTimeout(context.Background(), timeout)
- defer cancel()
- // Use the DevTools HTTP/JSON API to manage targets (e.g. pages, webworkers).
- devt := devtool.New("http://127.0.0.1:9222")
- pt, err := devt.Get(ctx, devtool.Page)
- if err != nil {
- pt, err = devt.Create(ctx)
- if err != nil {
- return err
- }
- }
- // Initiate a new RPC connection to the Chrome DevTools Protocol target.
- conn, err := rpcc.DialContext(ctx, pt.WebSocketDebuggerURL)
- if err != nil {
- return err
- }
- defer conn.Close() // Leaving connections open will leak memory.
- c := cdp.NewClient(conn)
- // Open a DOMContentEventFired client to buffer this event.
- domContent, err := c.Page.DOMContentEventFired(ctx)
- if err != nil {
- return err
- }
- defer domContent.Close()
- // Enable events on the Page domain, it's often preferrable to create
- // event clients before enabling events so that we don't miss any.
- if err = c.Page.Enable(ctx); err != nil {
- return err
- }
- // Create the Navigate arguments with the optional Referrer field set.
- navArgs := page.NewNavigateArgs("https://www.google.com").
- SetReferrer("https://duckduckgo.com")
- nav, err := c.Page.Navigate(ctx, navArgs)
- if err != nil {
- return err
- }
- // Wait until we have a DOMContentEventFired event.
- if _, err = domContent.Recv(); err != nil {
- return err
- }
- fmt.Printf("Page loaded with frame ID: %s\n", nav.FrameID)
- // Fetch the document root node. We can pass nil here
- // since this method only takes optional arguments.
- doc, err := c.DOM.GetDocument(ctx, nil)
- if err != nil {
- return err
- }
- // Get the outer HTML for the page.
- result, err := c.DOM.GetOuterHTML(ctx, &dom.GetOuterHTMLArgs{
- NodeID: &doc.Root.NodeID,
- })
- if err != nil {
- return err
- }
- fmt.Printf("HTML: %s\n", result.OuterHTML)
- // Capture a screenshot of the current page.
- screenshotName := "screenshot.jpg"
- screenshotArgs := page.NewCaptureScreenshotArgs().
- SetFormat("jpeg").
- SetQuality(80)
- screenshot, err := c.Page.CaptureScreenshot(ctx, screenshotArgs)
- if err != nil {
- return err
- }
- if err = ioutil.WriteFile(screenshotName, screenshot.Data, 0644); err != nil {
- return err
- }
- fmt.Printf("Saved screenshot: %s\n", screenshotName)
- pdfName := "page.pdf"
- f, err := os.Create(pdfName)
- if err != nil {
- return err
- }
- pdfArgs := page.NewPrintToPDFArgs().
- SetTransferMode("ReturnAsStream") // Request stream.
- pdfData, err := c.Page.PrintToPDF(ctx, pdfArgs)
- if err != nil {
- return err
- }
- sr := c.NewIOStreamReader(ctx, *pdfData.Stream)
- r := bufio.NewReader(sr)
- // Write to file in ~r.Size() chunks.
- _, err = r.WriteTo(f)
- if err != nil {
- return err
- }
- err = f.Close()
- if err != nil {
- return err
- }
- fmt.Printf("Saved PDF: %s\n", pdfName)
- return nil
- }