Skip to content

Instantly share code, notes, and snippets.

@mperezguendulain
Created February 21, 2020 22:07
Show Gist options
  • Save mperezguendulain/a07c179759cb855b6464c0ef6d1b3d00 to your computer and use it in GitHub Desktop.
Save mperezguendulain/a07c179759cb855b6464c0ef6d1b3d00 to your computer and use it in GitHub Desktop.
Application to generate a pdf file of the netflix web page
package main
import (
"context"
"fmt"
"io/ioutil"
"log"
"time"
"github.com/mafredri/cdp"
"github.com/mafredri/cdp/devtool"
"github.com/mafredri/cdp/protocol/page"
"github.com/mafredri/cdp/rpcc"
)
func main() {
err := run(15 * time.Second)
if err != nil {
log.Fatal(err)
}
}
func run(timeout time.Duration) error {
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
// Initialize cdp
c, conn, err := initCDP(ctx, timeout)
if err != nil {
return err
}
defer conn.Close() // Leaving connections open will leak memory.
// Enable lifecycle events...
err = c.Page.SetLifecycleEventsEnabled(ctx, page.NewSetLifecycleEventsEnabledArgs(true))
if err != nil {
return err
}
events, err := c.Page.LifecycleEvent(ctx)
if err != nil {
return err
}
defer events.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.
// url := "https://www.google.com"
url := "https://www.netflix.com/mx/"
navArgs := page.NewNavigateArgs(url)
nav, err := c.Page.Navigate(ctx, navArgs)
if err != nil {
return err
}
for {
ev, err := events.Recv()
if err != nil {
return err
}
fmt.Println(ev.Name)
if ev.Name == "networkIdle" {
break
}
}
fmt.Printf("Page loaded with frame ID: %s\n", nav.FrameID)
// Generating the pdf
printPDF(ctx, c)
return nil
}
func printPDF(ctx context.Context, c *cdp.Client) error {
pdfName := "output.pdf"
printToPDFArgs := page.NewPrintToPDFArgs().
SetPrintBackground(true).
SetLandscape(true).
SetMarginTop(0).
SetMarginBottom(0).
SetMarginLeft(0).
SetMarginRight(0)
print, _ := c.Page.PrintToPDF(ctx, printToPDFArgs)
if err := ioutil.WriteFile(pdfName, print.Data, 0644); err != nil {
return err
}
fmt.Printf("Saved pdf: %s\n", pdfName)
return nil
}
func initCDP(ctx context.Context, timeout time.Duration) (*cdp.Client, *rpcc.Conn, error) {
// 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 nil, nil, err
}
}
// Initiate a new RPC connection to the Chrome DevTools Protocol target.
conn, err := rpcc.DialContext(ctx, pt.WebSocketDebuggerURL)
if err != nil {
return nil, nil, err
}
c := cdp.NewClient(conn)
return c, conn, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment