Backend Development 8 min read

Using Go and chromedp for Headless Chrome Screenshot, PDF Export, and Device Emulation

This article demonstrates how to leverage Go and the chromedp library to control a headless Chrome instance for tasks such as element screenshots, full‑page captures, PDF generation, and device emulation, offering a lightweight alternative to Selenium‑based solutions.

360 Quality & Efficiency
360 Quality & Efficiency
360 Quality & Efficiency
Using Go and chromedp for Headless Chrome Screenshot, PDF Export, and Device Emulation

The author, inspired by a 360 Tech article about server‑side browser screenshot using Selenium/Python, explores using Go to drive a headless Chrome for crawling, screenshot, and automated testing.

Drawbacks of Selenium include the need to install Selenium or PhantomJS (which is no longer maintained), dependence on chromedriver matching the Chrome version, and additional JavaScript libraries like html2canvas, making environment setup cumbersome.

Using Go with the chromedp library solves these issues: only Chrome needs to be installed, and the Go binary can be compiled and run anywhere.

Installation command: go get -u github.com/chromedp/chromedp

Element screenshot example: package main import ( "context" "io/ioutil" "log" cdp "github.com/chromedp/chromedp" ) func main() { ctx, cancel := cdp.NewContext(context.Background()) defer cancel() urlstr := `https://www.so.com/` var buf []byte selector := `#main` if err := cdp.Run(ctx, elementScreenshot(urlstr, selector, &buf)); err != nil { log.Fatal(err) } if err := ioutil.WriteFile("360_so.png", buf, 0644); err != nil { log.Fatal(err) } } func elementScreenshot(urlstr, sel string, res *[]byte) cdp.Tasks { return cdp.Tasks{ cdp.Navigate(urlstr), cdp.WaitVisible(sel, cdp.ByID), cdp.Screenshot(sel, res, cdp.NodeVisible, cdp.ByID), } }

Export PDF example: func elementPDFPrint(urlstr, sel string, res *[]byte) cdp.Tasks { var err error return cdp.Tasks{ cdp.Navigate(urlstr), cdp.Sleep(time.Duration(5) * time.Second), cdp.ActionFunc(func(ctx context.Context) error { *res, _, err = page.PrintToPDF().Do(ctx) if err != nil { return err } return nil }), } }

Full‑screen screenshot example: func fullScreenshot(urlstr string, quality int64, res *[]byte) cdp.Tasks { return cdp.Tasks{ cdp.Navigate(urlstr), cdp.ActionFunc(func(ctx context.Context) error { _, _, contentSize, err := page.GetLayoutMetrics().Do(ctx) if err != nil { return err } width, height := int64(math.Ceil(contentSize.Width)), int64(math.Ceil(contentSize.Height)) err = emulation.SetDeviceMetricsOverride(width, height, 1, false). WithScreenOrientation(&emulation.ScreenOrientation{Type: emulation.OrientationTypePortraitPrimary, Angle: 0}). Do(ctx) if err != nil { return err } *res, err = page.CaptureScreenshot(). WithQuality(quality). WithClip(&page.Viewport{X: contentSize.X, Y: contentSize.Y, Width: contentSize.Width, Height: contentSize.Height, Scale: 1}). Do(ctx) if err != nil { return err } return nil }), } }

Device emulation (iPhone 7) example: func main() { ctx, cancel := cdp.NewContext(context.Background()) defer cancel() var b []byte if err := cdp.Run(ctx, cdp.Emulate(device.IPhone7landscape), cdp.Navigate(`https://www.whatsmyua.info/`), cdp.CaptureScreenshot(&b), ); err != nil { log.Fatal(err) } if err := ioutil.WriteFile("iphone7_ua.png", b, 0644); err != nil { log.Fatal(err) } }

In conclusion, by using Go and the chromedp framework, developers can perform almost all browser operations—including element screenshots, full‑page captures, PDF generation, and device emulation—on a headless Chrome with minimal dependencies and straightforward code.

AutomationGoPDFScreenshotheadless-chromechromedp
360 Quality & Efficiency
Written by

360 Quality & Efficiency

360 Quality & Efficiency focuses on seamlessly integrating quality and efficiency in R&D, sharing 360’s internal best practices with industry peers to foster collaboration among Chinese enterprises and drive greater efficiency value.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.