Documentation
¶
Overview ¶
Package chromedp is a high level Chrome DevTools Protocol client. It drives browsers to scrape web pages, to test them, and to profile them.
chromedp needs no external driver. It implements the asynchronous protocol in Go.
This package includes a number of simple examples. The module chromedp/examples has more complex examples. The module chromedp/termcast draws the screen of a page in a terminal that shows images.
Example (DocumentDump) ¶
package main
import (
"context"
"fmt"
"io"
"log"
"net/http"
"net/http/httptest"
"strings"
"github.com/chromedp/chromedp"
)
func writeHTML(content string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html")
io.WriteString(w, strings.TrimSpace(content))
})
}
func main() {
ctx, cancel := chromedp.NewContext(context.Background())
defer cancel()
ts := httptest.NewServer(writeHTML(`<!doctype html>
<html>
<body>
<div id="content" style="display:block;">the content</div>
</body>
</html>`))
defer ts.Close()
const expr = `(function(d, id, v) {
var b = d.querySelector('body');
var el = d.createElement('div');
el.id = id;
el.innerText = v;
b.insertBefore(el, b.childNodes[0]);
})(document, %q, %q);`
s := fmt.Sprintf(expr, "thing", "a new thing!")
if err := chromedp.Do(ctx, chromedp.Navigate(ts.URL)); err != nil {
log.Fatal(err)
}
nodes, err := chromedp.Run(ctx, chromedp.Nodes(chromedp.JSPath(`document`),
chromedp.Populate(-1, true)))
if err != nil {
log.Fatal(err)
}
if err := chromedp.Do(ctx,
chromedp.WaitVisible(`#content`),
chromedp.Evaluate[chromedp.Void](s),
chromedp.WaitVisible(`#thing`),
); err != nil {
log.Fatal(err)
}
fmt.Println("Document tree:")
fmt.Print(nodes[0].Dump(" ", " ", false))
}
Output: Document tree: #document <Document> html <DocumentType> html head body div#thing #text "a new thing!" div#content [style="display:block;"] #text "the content"
Example (Dump) ¶
package main
import (
"bytes"
"context"
"fmt"
"io"
"log"
"net/http"
"net/http/httptest"
"strings"
"github.com/chromedp/chromedp"
)
func writeHTML(content string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html")
io.WriteString(w, strings.TrimSpace(content))
})
}
func main() {
ctx, cancel := chromedp.NewContext(context.Background())
defer cancel()
ts := httptest.NewServer(writeHTML(`<!doctype html>
<html>
<body>
<div id="content" style="display:block;">the content</div>
</body>
</html>`))
defer ts.Close()
const expr = `(function(d, id, v) {
var b = d.querySelector('body');
var el = d.createElement('div');
el.id = id;
el.innerText = v;
b.insertBefore(el, b.childNodes[0]);
})(document, %q, %q);`
s := fmt.Sprintf(expr, "thing", "a new thing!")
var buf bytes.Buffer
if err := chromedp.Do(ctx,
chromedp.Navigate(ts.URL),
chromedp.WaitVisible(`#content`),
chromedp.Evaluate[chromedp.Void](s),
chromedp.WaitVisible(`#thing`),
chromedp.Dump(chromedp.JSPath(`document`), &buf),
); err != nil {
log.Fatal(err)
}
fmt.Println("Document tree:")
fmt.Print(buf.String())
}
Output: Document tree: #document <Document> html <DocumentType> html head body div#thing #text "a new thing!" div#content [style="display:block;"] #text "the content"
Example (RetrieveHTML) ¶
package main
import (
"context"
"fmt"
"io"
"log"
"net/http"
"net/http/httptest"
"strings"
"github.com/chromedp/chromedp"
)
func writeHTML(content string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html")
io.WriteString(w, strings.TrimSpace(content))
})
}
func main() {
ctx, cancel := chromedp.NewContext(context.Background())
defer cancel()
ts := httptest.NewServer(writeHTML(`
<body>
<p id="content" onclick="changeText()">Original content.</p>
<script>
function changeText() {
document.getElementById("content").textContent = "New content!"
}
</script>
</body>
`))
defer ts.Close()
if err := chromedp.Do(ctx, chromedp.Navigate(ts.URL)); err != nil {
log.Fatal(err)
}
outerBefore, err := chromedp.Run(ctx, chromedp.OuterHTML(chromedp.CSS("#content")))
if err != nil {
log.Fatal(err)
}
if err := chromedp.Do(ctx, chromedp.Click(chromedp.CSS("#content"))); err != nil {
log.Fatal(err)
}
outerAfter, err := chromedp.Run(ctx, chromedp.OuterHTML(chromedp.CSS("#content")))
if err != nil {
log.Fatal(err)
}
fmt.Println("OuterHTML before clicking:")
fmt.Println(outerBefore)
fmt.Println("OuterHTML after clicking:")
fmt.Println(outerAfter)
}
Output: OuterHTML before clicking: <p id="content" onclick="changeText()">Original content.</p> OuterHTML after clicking: <p id="content" onclick="changeText()">New content!</p>
Index ¶
- Constants
- Variables
- func BrowserEvents[E any](ctx context.Context, ev cdp.Event[E]) iter.Seq2[E, error]
- func ButtonLeft(p *input.DispatchMouseEventParams)
- func ButtonMiddle(p *input.DispatchMouseEventParams)
- func ButtonNone(p *input.DispatchMouseEventParams)
- func ButtonRight(p *input.DispatchMouseEventParams)
- func Call[P, R any](ctx context.Context, cmd cdp.Command[P, R], params P) (R, error)
- func CallBrowser[P, R any](ctx context.Context, cmd cdp.Command[P, R], params P) (R, error)
- func Cancel(ctx context.Context) error
- func Console(ctx context.Context) iter.Seq2[ConsoleMessage, error]
- func DisableGPU(a *ExecAllocator)
- func Do(ctx context.Context, steps ...Action[Void]) error
- func EmulateLandscape(p1 *emulation.SetDeviceMetricsOverrideParams, ...)
- func EmulateMobile(p1 *emulation.SetDeviceMetricsOverrideParams, ...)
- func EmulatePortrait(p1 *emulation.SetDeviceMetricsOverrideParams, ...)
- func EmulateTouch(p1 *emulation.SetDeviceMetricsOverrideParams, ...)
- func EvalAsValue(p *runtime.EvaluateParams)
- func EvalAwaitPromise(p *runtime.EvaluateParams)
- func EvalIgnoreExceptions(p *runtime.EvaluateParams)
- func EvalWithCommandLineAPI(p *runtime.EvaluateParams)
- func Events[E any](ctx context.Context, ev cdp.Event[E]) iter.Seq2[E, error]
- func Headless(a *ExecAllocator)
- func IgnoreCertErrors(a *ExecAllocator)
- func KeepOpen(a *ExecAllocator)
- func KeptOpen(ctx context.Context) (wsURL, userDataDir string)
- func NewAllocatorContext(parent context.Context, a Allocator) (context.Context, context.CancelFunc)
- func NewContext(parent context.Context, opts ...ContextOption) (context.Context, context.CancelFunc)
- func NewExecAllocator(parent context.Context, opts ...ExecAllocatorOption) (context.Context, context.CancelFunc)
- func NoDefaultBrowserCheck(a *ExecAllocator)
- func NoFirstRun(a *ExecAllocator)
- func NoInheritEnv(a *ExecAllocator)
- func NoSandbox(a *ExecAllocator)
- func NodeEnabled(s *Selector)
- func NodeNotPresent(s *Selector)
- func NodeNotVisible(s *Selector)
- func NodeReady(s *Selector)
- func NodeSelected(s *Selector)
- func NodeVisible(s *Selector)
- func Run[T any](ctx context.Context, a Action[T]) (T, error)
- func RunResponse(ctx context.Context, steps ...Action[Void]) (*network.Response, error)
- func Targets(ctx context.Context) ([]*target.Info, error)
- func VisibleWindow(a *ExecAllocator)
- func WaitClosed(ctx context.Context) error
- func WaitNewTarget(ctx context.Context, fn func(*target.Info) bool) <-chan target.ID
- type Action
- func AttributeValue[S Selectable](sel S, name string, opts ...QueryOption) Action[AttributeResult]
- func Attributes[S Selectable](sel S, opts ...QueryOption) Action[map[string]string]
- func AttributesAll[S Selectable](sel S, opts ...QueryOption) Action[[]map[string]string]
- func Blur[S Selectable](sel S, opts ...QueryOption) Action[Void]
- func CallFunctionOn[T any](functionDeclaration string, opt CallOption, args ...any) Action[T]
- func CaptureScreenshot() Action[[]byte]
- func Clear[S Selectable](sel S, opts ...QueryOption) Action[Void]
- func Click[S Selectable](sel S, opts ...QueryOption) Action[Void]
- func ComputedStyle[S Selectable](sel S, opts ...QueryOption) Action[[]*css.ComputedStyleProperty]
- func Dimensions[S Selectable](sel S, opts ...QueryOption) Action[*dom.BoxModel]
- func DoubleClick[S Selectable](sel S, opts ...QueryOption) Action[Void]
- func DragAndDrop[S, T Selectable](from S, to T, opts ...QueryOption) Action[Void]
- func DragAndDropXY(fromX, fromY, toX, toY float64, steps ...int) Action[Void]
- func Dump[S Selectable](sel S, w io.Writer, opts ...QueryOption) Action[Void]
- func DumpTo[S Selectable](sel S, w io.Writer, prefix, indent string, nodeIDs bool, depth int64, ...) Action[Void]
- func Emulate(device Device) Action[Void]
- func EmulateReset() Action[Void]
- func EmulateViewport(width, height int64, opts ...EmulateViewportOption) Action[Void]
- func Evaluate[T any](expression string, opts ...EvaluateOption) Action[T]
- func EvaluateAsDevTools[T any](expression string, opts ...EvaluateOption) Action[T]
- func ExposeFunc[A, R any](name string, fn func(ctx context.Context, arg A) (R, error)) Action[Void]
- func Focus[S Selectable](sel S, opts ...QueryOption) Action[Void]
- func FullScreenshot(quality int) Action[[]byte]
- func Func(f func(ctx context.Context, t *Target) error) Action[Void]
- func InnerHTML[S Selectable](sel S, opts ...QueryOption) Action[string]
- func JavascriptAttribute[T any, S Selectable](sel S, name string, opts ...QueryOption) Action[T]
- func KeyEvent(keys string, opts ...KeyOption) Action[Void]
- func KeyEventNode(n *Node, keys string, opts ...KeyOption) Action[Void]
- func Legacy(a OldAction) Action[Void]
- func Location() Action[string]
- func MatchedStyle[S Selectable](sel S, opts ...QueryOption) Action[*css.GetMatchedStylesForNodeResult]
- func MouseClickNode(n *Node, opts ...MouseOption) Action[Void]
- func MouseClickXY(x, y float64, opts ...MouseOption) Action[Void]
- func MouseEvent(typ input.DispatchMouseEventType, x, y float64, opts ...MouseOption) Action[Void]
- func Navigate(urlstr string) Action[Void]
- func NavigateBack() Action[Void]
- func NavigateForward() Action[Void]
- func NavigateResponse(urlstr string) Action[*network.Response]
- func NavigateToHistoryEntry(entryID int64) Action[Void]
- func NavigationEntries() Action[page.GetNavigationHistoryResult]
- func Nodes[S Selectable](sel S, opts ...QueryOption) Action[[]*Node]
- func OuterHTML[S Selectable](sel S, opts ...QueryOption) Action[string]
- func Poll[T any](expression string, opts ...PollOption) Action[T]
- func PollFunction[T any](pageFunction string, opts ...PollOption) Action[T]
- func PrintToPDF(opts ...PDFOption) Action[[]byte]
- func Query[S Selectable](sel S, opts ...QueryOption) Action[Void]
- func QueryAfter[T any, S Selectable](sel S, f func(ctx context.Context, t *Target, nodes []*Node) (T, error), ...) Action[T]
- func QueryNodeIDs[S Selectable](sel S, opts ...QueryOption) Action[[]cdp.NodeID]
- func Reload() Action[Void]
- func RemoveAttribute[S Selectable](sel S, name string, opts ...QueryOption) Action[Void]
- func Reset[S Selectable](sel S, opts ...QueryOption) Action[Void]
- func ResetViewport() Action[Void]
- func Screenshot[S Selectable](sel S, opts ...QueryOption) Action[[]byte]
- func ScreenshotNodes(nodes []*Node, scale float64) Action[[]byte]
- func ScreenshotScale[S Selectable](sel S, scale float64, opts ...QueryOption) Action[[]byte]
- func ScrollIntoView[S Selectable](sel S, opts ...QueryOption) Action[Void]
- func SendKeys[S Selectable](sel S, v string, opts ...QueryOption) Action[Void]
- func SetAttributeValue[S Selectable](sel S, name, value string, opts ...QueryOption) Action[Void]
- func SetAttributes[S Selectable](sel S, attributes map[string]string, opts ...QueryOption) Action[Void]
- func SetJavascriptAttribute[S Selectable](sel S, name, value string, opts ...QueryOption) Action[Void]
- func SetUploadFiles[S Selectable](sel S, files []string, opts ...QueryOption) Action[Void]
- func SetValue[S Selectable](sel S, value string, opts ...QueryOption) Action[Void]
- func Sleep(d time.Duration) Action[Void]
- func Steps(steps ...Action[Void]) Action[Void]
- func Stop() Action[Void]
- func Submit[S Selectable](sel S, opts ...QueryOption) Action[Void]
- func Tap[S Selectable](sel S, opts ...QueryOption) Action[Void]
- func TapXY(x, y float64) Action[Void]
- func Text[S Selectable](sel S, opts ...QueryOption) Action[string]
- func TextContent[S Selectable](sel S, opts ...QueryOption) Action[string]
- func Title() Action[string]
- func Value[S Selectable](sel S, opts ...QueryOption) Action[string]
- func WaitEnabled[S Selectable](sel S, opts ...QueryOption) Action[Void]
- func WaitEvent[E, T any](ev cdp.Event[E], match func(E) bool, trigger Action[T]) Action[E]
- func WaitNotPresent[S Selectable](sel S, opts ...QueryOption) Action[Void]
- func WaitNotVisible[S Selectable](sel S, opts ...QueryOption) Action[Void]
- func WaitReady[S Selectable](sel S, opts ...QueryOption) Action[Void]
- func WaitSelected[S Selectable](sel S, opts ...QueryOption) Action[Void]
- func WaitVisible[S Selectable](sel S, opts ...QueryOption) Action[Void]
- type Allocator
- type Attacher
- type AttributeResult
- type Browser
- type BrowserOption
- type CSS
- type CSSAll
- type CallOption
- type ConsoleMessage
- type ConsoleType
- type Context
- type ContextOption
- func WithAllocatorOptions(opts ...ExecAllocatorOption) ContextOption
- func WithBrowserOption(opts ...BrowserOption) ContextOption
- func WithDebugf(f func(string, ...any)) ContextOption
- func WithDetachOnCancel() ContextOption
- func WithErrorf(f func(string, ...any)) ContextOption
- func WithExistingBrowserContext(id cdp.BrowserContextID) ContextOption
- func WithLogf(f func(string, ...any)) ContextOption
- func WithNewBrowserContext(options ...CreateBrowserContextOption) ContextOption
- func WithNewWindow(newWindow bool) ContextOption
- func WithTargetID(id target.ID) ContextOption
- func WithVisibleWindow() ContextOption
- type CreateBrowserContextOption
- type Device
- type Dialer
- type EmulateViewportOption
- type Error
- type EvaluateOption
- type ExceptionError
- type ExecAllocator
- type ExecAllocatorOption
- func CombinedOutput(w io.Writer) ExecAllocatorOption
- func Env(vars ...string) ExecAllocatorOption
- func ExecPath(path string) ExecAllocatorOption
- func Flag(name string, value any) ExecAllocatorOption
- func ModifyCmdFunc(f func(cmd *exec.Cmd)) ExecAllocatorOption
- func ProxyServer(proxy string) ExecAllocatorOption
- func UserAgent(userAgent string) ExecAllocatorOption
- func UserDataDir(dir string) ExecAllocatorOption
- func WSURLReadTimeout(t time.Duration) ExecAllocatorOption
- func WindowSize(width, height int) ExecAllocatorOption
- func WithDialer(d Dialer) ExecAllocatorOption
- type Frame
- type FrameState
- type ID
- type JSPath
- type KeyOption
- type LoadError
- type Modifier
- type MouseOption
- type Node
- func (n *Node) Attribute(name string) (string, bool)
- func (n *Node) AttributeValue(name string) string
- func (n *Node) Dump(prefix, indent string, nodeIDs bool) string
- func (n *Node) FullXPath() string
- func (n *Node) FullXPathByID() string
- func (n *Node) PartialXPath() string
- func (n *Node) PartialXPathByID() string
- func (n *Node) WriteTo(w io.Writer, prefix, indent string, nodeIDs bool) (int, error)
- type NodeIDs
- type NodeState
- type NodeType
- type OldAction
- type PDFOption
- func PDFFooterTemplate(html string) PDFOption
- func PDFHeaderTemplate(html string) PDFOption
- func PDFLandscape() PDFOption
- func PDFMargin(inches float64) PDFOption
- func PDFMargins(top, right, bottom, left float64) PDFOption
- func PDFOutlineAndTagged() PDFOption
- func PDFPageRanges(ranges string) PDFOption
- func PDFPaper(size PaperSize) PDFOption
- func PDFPreferCSSPageSize() PDFOption
- func PDFPrintBackground() PDFOption
- func PDFScale(scale float64) PDFOption
- func PDFStream() PDFOption
- type PaperSize
- type PipeConn
- type PipeOption
- type PollOption
- type PopulateOption
- type QueryOption
- func After(f func(ctx context.Context, t *Target, nodes []*Node) error) QueryOption
- func AtLeast(n int) QueryOption
- func ByFunc(f func(context.Context, *Target, *Node) ([]cdp.NodeID, error)) QueryOption
- func FromNode(node *Node) QueryOption
- func Populate(depth int64, pierce bool, opts ...PopulateOption) QueryOption
- func RetryInterval(interval time.Duration) QueryOption
- func WaitFunc(...) QueryOption
- type Search
- type Selectable
- type Selector
- type Target
- type Transport
- type Void
Examples ¶
- Package (DocumentDump)
- Package (Dump)
- Package (RetrieveHTML)
- Call
- Click
- Emulate
- Evaluate
- Events (AcceptAlert)
- Events (ConsoleLog)
- Events (Network)
- ExecAllocator
- FromNode
- FullScreenshot
- JSPath
- Legacy
- NewContext (ManyTabs)
- NewContext (ReuseBrowser)
- PrintToPDF
- PrintToPDF (Options)
- RunResponse
- Selectable
- SendKeys
- Title
- VisibleWindow
- WaitNewTarget
- WithVisibleWindow
Constants ¶
const ( MousePressed = input.DispatchMouseEventTypeMousePressed MouseReleased = input.DispatchMouseEventTypeMouseReleased MouseMoved = input.DispatchMouseEventTypeMouseMoved MouseWheel = input.DispatchMouseEventTypeMouseWheel )
Mouse event types for MouseEvent.
const ( ModifierNone = kb.ModifierNone ModifierAlt = kb.ModifierAlt ModifierCtrl = kb.ModifierCtrl ModifierMeta = kb.ModifierMeta ModifierShift = kb.ModifierShift ModifierCommand = kb.ModifierCommand )
Modifier values.
const ( NodeTypeElement = 1 NodeTypeAttribute = 2 NodeTypeText = 3 NodeTypeCDATA = 4 NodeTypeEntityReference = 5 NodeTypeEntity = 6 NodeTypeProcessingInstruction = 7 NodeTypeComment = 8 NodeTypeDocument = 9 NodeTypeDocumentType = 10 NodeTypeDocumentFragment = 11 NodeTypeNotation = 12 )
NodeType values.
const EmptyFrameID = cdp.FrameID("")
EmptyFrameID is the "non-existent" frame id.
const EmptyNodeID = cdp.NodeID(0)
EmptyNodeID is the "non-existent" node id.
Variables ¶
var ( // DefaultUnmarshalOptions are default unmarshal options. DefaultUnmarshalOptions = jsonv2.JoinOptions( jsonv2.DefaultOptionsV2(), jsonv2.AllowInvalidUTF8(true), ) // DefaultMarshalOptions are default marshal options. DefaultMarshalOptions = jsonv2.JoinOptions( jsonv2.DefaultOptionsV2(), jsonv2.AllowInvalidUTF8(true), ) )
var ( PaperLetter = PaperSize{8.5, 11} PaperLegal = PaperSize{8.5, 14} PaperTabloid = PaperSize{11, 17} PaperA3 = PaperSize{11.69, 16.54} PaperA4 = PaperSize{8.27, 11.69} PaperA5 = PaperSize{5.83, 8.27} )
Common paper sizes, in inches.
var DefaultExecAllocatorOptions = [...]ExecAllocatorOption{ NoFirstRun, NoDefaultBrowserCheck, Headless, Flag("disable-background-networking", true), Flag("enable-features", "NetworkService,NetworkServiceInProcess"), Flag("disable-background-timer-throttling", true), Flag("disable-backgrounding-occluded-windows", true), Flag("disable-breakpad", true), Flag("disable-client-side-phishing-detection", true), Flag("disable-default-apps", true), Flag("disable-dev-shm-usage", true), Flag("disable-extensions", true), Flag("disable-features", "Translate,BlinkGenPropertyTrees"), Flag("disable-hang-monitor", true), Flag("disable-ipc-flooding-protection", true), Flag("disable-popup-blocking", true), Flag("disable-prompt-on-repost", true), Flag("disable-renderer-backgrounding", true), Flag("disable-sync", true), Flag("force-color-profile", "srgb"), Flag("metrics-recording-only", true), Flag("safebrowsing-disable-auto-update", true), Flag("enable-automation", true), Flag("password-store", "basic"), Flag("use-mock-keychain", true), }
DefaultExecAllocatorOptions are the ExecAllocator options that NewContext uses when the parent context has no allocator. Do not modify this global. Use NewExecAllocator instead. See ExampleExecAllocator.
The list runs the browser in headless mode. To get a visible window, add VisibleWindow to a copy of the list, or give WithVisibleWindow to NewContext.
The list sets disable-dev-shm-usage to true. Chrome then keeps the files of its shared memory in the temporary directory, such as /tmp, and not in /dev/shm. The flag is on because /dev/shm is small in many containers, for example 64 MB in a default Docker container, and Chrome crashes when it fills the space. The cost is that these files are file-backed memory in the temporary directory, which can be slower, and which a program that runs for a long time and opens many pages can see as growing memory. If /dev/shm is large enough, turn the flag off with Flag("disable-dev-shm-usage", false) after the default options:
opts := append(chromedp.DefaultExecAllocatorOptions[:],
chromedp.Flag("disable-dev-shm-usage", false),
)
Functions ¶
func BrowserEvents ¶ added in v0.17.0
BrowserEvents is like Events for the events of the browser, such as the events of the target domain. It replaces ListenBrowser.
func ButtonLeft ¶
func ButtonLeft(p *input.DispatchMouseEventParams)
ButtonLeft is a mouse action option to set the button clicked as the left mouse button.
func ButtonMiddle ¶
func ButtonMiddle(p *input.DispatchMouseEventParams)
ButtonMiddle is a mouse action option to set the button clicked as the middle mouse button.
func ButtonNone ¶
func ButtonNone(p *input.DispatchMouseEventParams)
ButtonNone is a mouse action option to set the button clicked as none (used for mouse movements).
func ButtonRight ¶
func ButtonRight(p *input.DispatchMouseEventParams)
ButtonRight is a mouse action option to set the button clicked as the right mouse button.
func Call ¶ added in v0.17.0
Call runs the protocol command with the params on the target of the chromedp context, and returns its result. As Run does, it starts the browser and opens the target when the context has none yet.
Use it where only the context is at hand, for example in code that runs under Legacy. An Action receives its target, and calls cdp.Call with it:
res, err := chromedp.Call(ctx, page.Navigate, page.NavigateParams{URL: urlstr})
It returns ErrInvalidContext when ctx is not a chromedp context.
Example ¶
package main
import (
"context"
"fmt"
"io"
"log"
"net/http"
"net/http/httptest"
"strings"
"github.com/chromedp/cdproto/cdp"
"github.com/chromedp/cdproto/page"
"github.com/chromedp/chromedp"
)
func writeHTML(content string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html")
io.WriteString(w, strings.TrimSpace(content))
})
}
func main() {
ctx, cancel := chromedp.NewContext(context.Background())
defer cancel()
ts := httptest.NewServer(writeHTML(`<title>called</title>`))
defer ts.Close()
// Any protocol command runs on the target of an action. The target is
// a cdp.Session, so cdp.Call takes it as is.
frameTree := func(ctx context.Context, t *chromedp.Target) (*page.FrameTree, error) {
res, err := cdp.Call(ctx, t, page.GetFrameTree, cdp.Empty{})
return res.FrameTree, err
}
if err := chromedp.Do(ctx, chromedp.Navigate(ts.URL)); err != nil {
log.Fatal(err)
}
tree, err := chromedp.Run(ctx, frameTree)
if err != nil {
log.Fatal(err)
}
fmt.Println(strings.TrimPrefix(tree.Frame.URL, ts.URL) == "/")
// Outside an action, use chromedp.Call with the context.
res, err := chromedp.Call(ctx, page.GetFrameTree, cdp.Empty{})
if err != nil {
log.Fatal(err)
}
fmt.Println(res.FrameTree.Frame.ID == tree.Frame.ID)
}
Output: true true
func CallBrowser ¶ added in v0.17.0
CallBrowser runs the protocol command with the params on the browser of the chromedp context, and returns its result. Use it for the commands of the browser and target domains. As Run does, it starts the browser when the context has none yet.
It returns ErrInvalidContext when ctx is not a chromedp context.
func Cancel ¶ added in v0.2.0
Cancel cancels a chromedp context, waits until the context frees its resources, and returns any error that occurred.
If the context allocated a browser, Cancel closes the browser gracefully. To limit how long Cancel waits for the browser to close, give the context a timeout:
tctx, tcancel := context.WithTimeout(ctx, 10 * time.Second) defer tcancel() chromedp.Cancel(tctx)
A "defer cancel()" is enough in most cases. Use Cancel to close a browser gracefully, or to get the errors that occur during the cancellation.
func Console ¶ added in v0.19.0
Console subscribes to the console of the target of the context, and returns an iterator over its messages. A message is a call of the console API such as console.log, an uncaught exception, an unhandled promise rejection, or an entry of the browser log. The iterator keeps the order of the messages.
Console reads the events runtime.ConsoleAPICalled, runtime.ExceptionThrown and log.EntryAdded. Events gives the same events one by one, as the protocol sends them, and Console joins them in one stream of simple values. The old API used [ListenTarget] with a func that tested the type of each event.
As Events does, Console subscribes when it returns, and not when the caller starts to range. A caller can subscribe, run the actions, and then range, so that no message is lost:
messages := chromedp.Console(ctx)
if err := chromedp.Do(ctx, chromedp.Navigate(url)); err != nil {
return err
}
for m, err := range messages {
if err != nil {
break
}
fmt.Println(m)
}
A browser sends the messages only from the moment that the target exists, so a message that the page wrote before the first call of Console or of Run is lost. If the browser cannot start, the iterator yields the error. See cdp.Events for the rules about ending the iteration.
To stop, cancel the context or break out of the loop. Both end the subscription and free its queue, also when the program never ranged over the iterator.
The queue of the messages has no limit, so that a slow reader never blocks the page. The page keeps working when the program does not read the messages, but the queue grows with each message until the subscription ends. A program that reads slowly or stops to read must cancel the context or break out of the loop.
func DisableGPU ¶ added in v0.2.0
func DisableGPU(a *ExecAllocator)
DisableGPU is the command line option to disable the GPU process.
The --disable-gpu option is a temporary workaround for a few bugs in headless mode. The references below say that it is no longer required:
- https://bugs.chromium.org/p/chromium/issues/detail?id=737678
- https://github.com/puppeteer/puppeteer/pull/2908
- https://github.com/puppeteer/puppeteer/pull/4523
But this issue says that it is still required in some cases:
Chromium 139 and later has no fallback to Swiftshader, unless you pass the --enable-unsafe-swiftshader option:
func Do ¶ added in v0.17.0
Do runs the actions against the target of the context, in order. It stops at the first error. See Run for the rules about the context.
For example:
err := chromedp.Do(ctx,
chromedp.Navigate("https://example.com"),
chromedp.Click(chromedp.CSS("a")),
)
func EmulateLandscape ¶ added in v0.4.0
func EmulateLandscape(p1 *emulation.SetDeviceMetricsOverrideParams, p2 *emulation.SetTouchEmulationEnabledParams)
EmulateLandscape is an emulate viewport option to set the device viewport screen orientation in landscape primary mode and an angle of 90.
func EmulateMobile ¶ added in v0.4.0
func EmulateMobile(p1 *emulation.SetDeviceMetricsOverrideParams, p2 *emulation.SetTouchEmulationEnabledParams)
EmulateMobile is an emulate viewport option to toggle the device viewport to display as a mobile device.
func EmulatePortrait ¶ added in v0.4.0
func EmulatePortrait(p1 *emulation.SetDeviceMetricsOverrideParams, p2 *emulation.SetTouchEmulationEnabledParams)
EmulatePortrait is an emulate viewport option to set the device viewport screen orientation in portrait primary mode and an angle of 0.
func EmulateTouch ¶ added in v0.4.0
func EmulateTouch(p1 *emulation.SetDeviceMetricsOverrideParams, p2 *emulation.SetTouchEmulationEnabledParams)
EmulateTouch is an emulate viewport option to enable touch emulation.
func EvalAsValue ¶
func EvalAsValue(p *runtime.EvaluateParams)
EvalAsValue is an evaluate option that makes the evaluation encode the result of the expression as a JSON-encoded value.
func EvalAwaitPromise ¶ added in v0.19.0
func EvalAwaitPromise(p *runtime.EvaluateParams)
EvalAwaitPromise is an evaluate option that makes the evaluation wait for a promise that the expression returns, and use its result. A promise that is rejected makes the action return an *ExceptionError. Without the option, the result of an expression that returns a promise is the promise object, and not its value.
v, err := chromedp.Run(ctx, chromedp.Evaluate[string](`fetch("/api").then(r => r.text())`, chromedp.EvalAwaitPromise))
func EvalIgnoreExceptions ¶
func EvalIgnoreExceptions(p *runtime.EvaluateParams)
EvalIgnoreExceptions is an evaluate option that makes the evaluation ignore exceptions.
func EvalWithCommandLineAPI ¶
func EvalWithCommandLineAPI(p *runtime.EvaluateParams)
EvalWithCommandLineAPI is an evaluate option that makes the DevTools Command Line API available to the evaluated script.
See Evaluate for how evaluate actions work.
Note: do not use this with untrusted JavaScript.
func Events ¶ added in v0.17.0
Events subscribes to the event on the target of the context, and returns an iterator over its payloads. It replaces ListenTarget.
The subscription starts when Events returns, and not when the caller starts to range. A caller can subscribe, trigger the event, and then range, so that no event is lost:
events := chromedp.Events(ctx, page.LoadEventFired)
if err := chromedp.Do(ctx, chromedp.Navigate(url)); err != nil {
return err
}
for ev, err := range events {
...
}
As Run does, Events starts the browser and opens the target when the context has none yet. If that fails, the iterator yields the error. See cdp.Events for the rules about ending the iteration. To stop, cancel the context or break out of the loop. Both end the subscription, also when the program never ranged over the iterator. The queue of the events has no limit, so a reader that does not read makes it grow until the subscription ends.
Example (AcceptAlert) ¶
package main
import (
"context"
"fmt"
"io"
"log"
"net/http"
"net/http/httptest"
"strings"
"github.com/chromedp/cdproto/page"
"github.com/chromedp/chromedp"
)
func writeHTML(content string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html")
io.WriteString(w, strings.TrimSpace(content))
})
}
func main() {
ctx, cancel := chromedp.NewContext(context.Background())
defer cancel()
ts := httptest.NewServer(writeHTML(`
<input id='alert' type='button' value='alert' onclick='alert("alert text");'/>
`))
defer ts.Close()
// The page waits for the dialog, and so does the Click below. A second
// goroutine closes the dialog.
dialogs := chromedp.Events(ctx, page.JavascriptDialogOpening)
go func() {
for ev, err := range dialogs {
if err != nil {
return
}
fmt.Println("closing alert:", ev.Message)
_, err := chromedp.Call(ctx, page.HandleJavaScriptDialog, page.HandleJavaScriptDialogParams{Accept: true})
if err != nil {
log.Fatal(err)
}
}
}()
if err := chromedp.Do(ctx,
chromedp.Navigate(ts.URL),
chromedp.Click(chromedp.ID("alert")),
); err != nil {
log.Fatal(err)
}
}
Output: closing alert: alert text
Example (ConsoleLog) ¶
package main
import (
"context"
"fmt"
"io"
"log"
"net/http"
"net/http/httptest"
"strings"
"github.com/chromedp/cdproto/runtime"
"github.com/chromedp/chromedp"
)
func writeHTML(content string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html")
io.WriteString(w, strings.TrimSpace(content))
})
}
func main() {
ctx, cancel := chromedp.NewContext(context.Background())
defer cancel()
ts := httptest.NewServer(writeHTML(`
<body>
<script>
console.log("hello js world")
console.warn("scary warning", 123)
null.throwsException
</script>
</body>
`))
defer ts.Close()
// Subscribe first. The subscriptions buffer the events, so the loops
// below see the events of the navigation although they start later.
console := chromedp.Events(ctx, runtime.ConsoleAPICalled)
exceptions := chromedp.Events(ctx, runtime.ExceptionThrown)
if err := chromedp.Do(ctx, chromedp.Navigate(ts.URL)); err != nil {
log.Fatal(err)
}
calls := 0
for ev, err := range console {
if err != nil {
log.Fatal(err)
}
fmt.Printf("* console.%s call:\n", ev.Type)
for _, arg := range ev.Args {
fmt.Printf("%s - %s\n", arg.Type, arg.Value)
}
if calls++; calls == 2 {
break
}
}
for ev, err := range exceptions {
if err != nil {
log.Fatal(err)
}
// Since ts.URL uses a random port, replace it.
s := (&chromedp.ExceptionError{ExceptionDetails: ev.ExceptionDetails}).Error()
s = strings.ReplaceAll(s, ts.URL, "<server>")
// V8 changed the error messages for property access on null/undefined in version 9.3.310.
// see: https://chromium.googlesource.com/v8/v8/+/c0fd89c3c089e888c4f4e8582e56db7066fa779b
// https://github.com/chromium/chromium/commit/1735cbf94c98c70ff7554a1e9e01bb9a4f91beb6
// The test normalizes the message to stay compatible with the versions before this change.
s = strings.ReplaceAll(s, "Cannot read property 'throwsException' of null", "Cannot read properties of null (reading 'throwsException')")
fmt.Printf("* %s\n", s)
break
}
}
Output: * console.log call: string - "hello js world" * console.warning call: string - "scary warning" number - 123 * exception "Uncaught" (4:6): TypeError: Cannot read properties of null (reading 'throwsException') at <server>/:5:7
Example (Network) ¶
package main
import (
"context"
"fmt"
"io"
"log"
"net/http"
"net/http/httptest"
"strings"
"github.com/chromedp/cdproto/network"
"github.com/chromedp/chromedp"
)
func writeHTML(content string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html")
io.WriteString(w, strings.TrimSpace(content))
})
}
func main() {
ctx, cancel := chromedp.NewContext(context.Background())
defer cancel()
// The page has an image that does not exist.
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/" {
http.NotFound(w, r)
return
}
writeHTML(`<body><img src="/missing.png"/></body>`).ServeHTTP(w, r)
}))
defer ts.Close()
// Subscribe before the navigation. The loop below can start after it.
responses := chromedp.Events(ctx, network.ResponseReceived)
if err := chromedp.Do(ctx, chromedp.Navigate(ts.URL)); err != nil {
log.Fatal(err)
}
for ev, err := range responses {
if err != nil {
log.Fatal(err)
}
fmt.Println(strings.TrimPrefix(ev.Response.URL, ts.URL), ev.Response.Status)
if ev.Type == network.ResourceTypeImage {
break
}
}
}
Output: / 200 /missing.png 404
func Headless ¶ added in v0.2.0
func Headless(a *ExecAllocator)
Headless is the command line option to run in headless mode. It sets the headless flag, hides scrollbars, and mutes audio.
func IgnoreCertErrors ¶ added in v0.7.4
func IgnoreCertErrors(a *ExecAllocator)
IgnoreCertErrors is the command line option to ignore certificate errors. Use it to access an HTTPS website through a proxy.
func KeepOpen ¶ added in v0.17.0
func KeepOpen(a *ExecAllocator)
KeepOpen is an ExecAllocatorOption that leaves the browser open when the Go program ends or when the context is canceled. Use it to look at the page after the program is done. See also KeptOpen and VisibleWindow.
The allocator needs a dialer for a kept browser, as it connects with a websocket. Without one, Allocate returns ErrNoDialer. Add WithDialer, or WebSocket of the package github.com/chromedp/chromedp/remote, to the options. For the default allocator of NewContext, give the option WithKeepOpen of that package to NewContext.
The browser must outlive the program, so KeepOpen changes how the allocator starts it:
- The allocator uses the websocket and not the pipe, because the pipe closes when the Go process exits, and Chrome then exits too. It starts Chrome with --remote-debugging-port=0 and reads the address from the file DevToolsActivePort in the user data directory. The allocator of the remote package can connect to that address later.
- The process starts detached: in a new session on Unix, and detached from the console and in a new process group on Windows. A func from ModifyCmdFunc runs first, and the detach settings come after it.
- The allocator does not kill the process when the context ends. It waits for the process in a goroutine, so that no zombie process stays while the program runs.
- The allocator never removes the user data directory. Unless you set UserDataDir, the directory is "keepopen-PID" in the directory "chromedp" of os.UserCacheDir, where PID is the process ID of the Go program. Each program run leaves one such directory, and you must remove it yourself. Two browsers of one program share the directory, so set UserDataDir when a program keeps more than one browser open.
- Cancel does not close the browser. The output of the browser goes nowhere, so CombinedOutput has no effect. The library prints nothing. KeptOpen returns the address and the directory, so that the program can print them.
To close a kept browser, close its window, or kill its process. The process is available as Process of the Browser.
func KeptOpen ¶ added in v0.17.0
KeptOpen returns the websocket address of the browser of the context and the user data directory of the browser, so that a program can print them. Another program can attach to the address with the allocator of the package github.com/chromedp/chromedp/remote. The user can delete the directory when the browser is closed.
KeptOpen returns two empty strings when the context has no browser yet, or when the allocator did not start the browser with KeepOpen. The browser starts at the first Run, so call KeptOpen after it.
func NewAllocatorContext ¶ added in v0.18.0
NewAllocatorContext creates a new context that holds the allocator a. Use it with NewContext, as with the context of NewExecAllocator. It is for an Allocator that another package implements, such as the allocator of the package github.com/chromedp/chromedp/remote.
The cancel func cancels the context. It does not call the Wait method of a.
func NewContext ¶ added in v0.2.0
func NewContext(parent context.Context, opts ...ContextOption) (context.Context, context.CancelFunc)
NewContext creates a chromedp context from the parent context. The context inherits the Allocator of the parent. By default, that is an ExecAllocator with DefaultExecAllocatorOptions.
If the parent context holds an allocated Browser, the child context inherits it, and its first Run creates a new tab on that browser. Otherwise, its first Run allocates a new browser.
Canceling the returned context closes a tab or a whole browser, as the rules above describe. To cancel a context and read the errors, see Cancel.
NewContext does not allocate or start a browser. That happens the first time that you call Run on the context.
The lifetime of the browser ¶
The first call of Run on a context starts the browser, and it binds the life of the browser to the context that you pass to that call. When that context ends, the browser stops. So a context from context.WithTimeout that you use for the first Run closes the browser when the timeout ends, and every later call on the parent context fails with context.Canceled.
To limit one action, start the browser first with a context that has no timeout. Then run the action with a context that you derive from it:
if err := chromedp.Do(ctx); err != nil { // starts the browser
return err
}
tctx, cancel := context.WithTimeout(ctx, 5*time.Second)
defer cancel()
err := chromedp.Do(tctx, chromedp.Navigate(url))
When the timeout ends, Run returns an error that wraps context.DeadlineExceeded. The tab and the browser stay open, and ctx still works. Run has no option for the timeout of one action.
Use from several goroutines ¶
Contexts that share one browser run in separate tabs, and they are safe to use in parallel. To get them, call Run once on a parent context so that it has a browser, and then make a child context for each goroutine with NewContext. A child of a context that has no browser yet starts a browser of its own.
Do not share one context between goroutines. The actions of one context run in one tab, so they can race. For example, two Navigate actions on the same tab can fail. The first call of Run on a context starts the browser, and it must not run at the same time as another call on that context.
Example (ManyTabs) ¶
package main
import (
"context"
"fmt"
"log"
"github.com/chromedp/chromedp"
)
func main() {
// new browser, first tab
ctx1, cancel := chromedp.NewContext(context.Background())
defer cancel()
// make sure that the first tab is created
if err := chromedp.Do(ctx1); err != nil {
log.Fatal(err)
}
// same browser, second tab
ctx2, _ := chromedp.NewContext(ctx1)
// make sure that the second tab is created
if err := chromedp.Do(ctx2); err != nil {
log.Fatal(err)
}
c1 := chromedp.FromContext(ctx1)
c2 := chromedp.FromContext(ctx2)
fmt.Printf("Same browser: %t\n", c1.Browser == c2.Browser)
fmt.Printf("Same tab: %t\n", c1.Target == c2.Target)
}
Output: Same browser: true Same tab: false
Example (ReuseBrowser) ¶
package main
import (
"context"
"fmt"
"io"
"log"
"net/http"
"net/http/httptest"
"strings"
"time"
"github.com/chromedp/chromedp"
)
func writeHTML(content string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html")
io.WriteString(w, strings.TrimSpace(content))
})
}
func main() {
ts := httptest.NewServer(writeHTML(`
<body>
<script>
// Show the current cookies.
var p = document.createElement("p")
p.innerText = document.cookie
p.setAttribute("id", "cookies")
document.body.appendChild(p)
// Override the cookies.
document.cookie = "foo=bar"
</script>
</body>
`))
defer ts.Close()
// create a new browser
ctx, cancel := chromedp.NewContext(context.Background())
defer cancel()
// start the browser without a timeout
if err := chromedp.Do(ctx); err != nil {
log.Fatal(err)
}
for i := range 2 {
func() {
// A slow machine, such as a CI runner, can need more than a
// second.
ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
defer cancel()
ctx, cancel = chromedp.NewContext(ctx)
defer cancel()
if err := chromedp.Do(ctx, chromedp.Navigate(ts.URL)); err != nil {
log.Fatal(err)
}
cookies, err := chromedp.Run(ctx, chromedp.Text("#cookies"))
if err != nil {
log.Fatal(err)
}
fmt.Printf("Cookies at i=%d: %q\n", i, cookies)
}()
}
}
Output: Cookies at i=0: "" Cookies at i=1: "foo=bar"
func NewExecAllocator ¶ added in v0.2.0
func NewExecAllocator(parent context.Context, opts ...ExecAllocatorOption) (context.Context, context.CancelFunc)
NewExecAllocator creates a new context with an ExecAllocator. Use it with NewContext.
func NoDefaultBrowserCheck ¶ added in v0.2.0
func NoDefaultBrowserCheck(a *ExecAllocator)
NoDefaultBrowserCheck is the Chrome command line option to disable the default browser check.
func NoFirstRun ¶ added in v0.2.0
func NoFirstRun(a *ExecAllocator)
NoFirstRun is the Chrome command line option to disable the first run dialog.
func NoInheritEnv ¶ added in v0.19.0
func NoInheritEnv(a *ExecAllocator)
NoInheritEnv is an allocator option that starts the browser with only the variables that Env gives, and the variables that a func of ModifyCmdFunc sets in cmd.Env. The browser does not get the environment of the Go process. Use it to keep the secrets of the program away from the browser.
On Linux, the browser then starts with an empty environment. A program can want to pass HOME, PATH, DISPLAY (or WAYLAND_DISPLAY) for a headed browser, and XDG_RUNTIME_DIR. On Windows, os/exec adds SYSTEMROOT by itself, and a browser can also need TEMP, LOCALAPPDATA and USERPROFILE. Give each variable that the browser needs to Env. Without the option, the browser gets the whole environment of the Go process, as before.
func NoSandbox ¶ added in v0.2.0
func NoSandbox(a *ExecAllocator)
NoSandbox is the Chrome command line option to disable the sandbox.
func NodeEnabled ¶
func NodeEnabled(s *Selector)
NodeEnabled is an element query option that waits until the browser has sent all queried element nodes. The nodes must be enabled (that is, they have no 'disabled' attribute).
func NodeNotPresent ¶
func NodeNotPresent(s *Selector)
NodeNotPresent is an element query option that waits until no element matches the query.
Note: it sets the expected number of element nodes to 0.
func NodeNotVisible ¶
func NodeNotVisible(s *Selector)
NodeNotVisible is an element query option that waits until the browser has sent all queried element nodes and they are not visible.
func NodeReady ¶
func NodeReady(s *Selector)
NodeReady is an element query option that waits until the browser has sent all queried element nodes.
func NodeSelected ¶
func NodeSelected(s *Selector)
NodeSelected is an element query option that waits until the browser has sent all queried element nodes. The nodes must be selected (that is, they have a 'selected' attribute).
func NodeVisible ¶
func NodeVisible(s *Selector)
NodeVisible is an element query option that waits until the browser has sent all queried element nodes and they are visible.
func Run ¶ added in v0.2.0
Run runs the action against the target of the context, and returns its value. The context must be a chromedp context, typically made with NewContext.
The first time that you call Run on a context, Run allocates a browser with the Allocator, and the browser lives as long as the context of that call. Do not set a timeout on the context of that first call, because the timeout stops the whole browser. To limit one action, run it with a context that you derive with context.WithTimeout from a context that has run once. See NewContext.
For example:
title, err := chromedp.Run(ctx, chromedp.Title())
If the browser process dies while nobody has asked it to stop, for example when it crashes or when the system kills it for lack of memory, then Run returns an error that wraps the exit error of the process and the error of the context. Use errors.As with a pointer to an os/exec.ExitError to read the signal or the status.
Use Do to run several actions that return no value.
Contexts that share a browser run in separate tabs, so goroutines can call Run in parallel when each one has its own context. Actions on one context share one tab, so they can race. See NewContext.
func RunResponse ¶ added in v0.5.4
RunResponse is an alternative to Do for a list of actions that trigger a page navigation, such as a click on a link or a button.
RunResponse runs the actions and blocks until a page loads. Then it returns the HTTP response of the HTML document. Use it to wait for the page, or to catch 404 status codes.
If the actions trigger several navigations, RunResponse uses only the first. If the actions trigger no navigation, RunResponse blocks until the context is canceled.
Example ¶
package main
import (
"context"
"fmt"
"log"
"net/http"
"net/http/httptest"
"github.com/chromedp/chromedp"
)
func main() {
ctx, cancel := chromedp.NewContext(context.Background())
defer cancel()
// This server shows the URL path as the page title, and contains
// a link that points to /foo.
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html")
fmt.Fprintf(w, `
<head><title>%s</title></head>
<body><a id="foo" href="/foo">foo</a></body>
`, r.URL.Path)
}))
defer ts.Close()
// The Navigate action already waits until a page loads, so Title runs
// once the page is ready.
if err := chromedp.Do(ctx, chromedp.Navigate(ts.URL)); err != nil {
log.Fatal(err)
}
firstTitle, err := chromedp.Run(ctx, chromedp.Title())
if err != nil {
log.Fatal(err)
}
fmt.Println("first title:", firstTitle)
// However, actions like Click do not always trigger a page navigation,
// so they do not wait for a page load directly. Wrapping them with
// RunResponse does that waiting, and also obtains the HTTP response.
resp, err := chromedp.RunResponse(ctx, chromedp.Click(chromedp.ID("foo")))
if err != nil {
log.Fatal(err)
}
fmt.Println("second status code:", resp.Status)
// Getting the title again works, because the page finished loading once
// more.
secondTitle, err := chromedp.Run(ctx, chromedp.Title())
if err != nil {
log.Fatal(err)
}
fmt.Println("second title:", secondTitle)
// You can also wrap Navigate with RunResponse to get the response
// information for that case too.
resp, err = chromedp.RunResponse(ctx, chromedp.Navigate(ts.URL+"/bar"))
if err != nil {
log.Fatal(err)
}
fmt.Println("third status code:", resp.Status)
// NavigateResponse is a shorter way to do the same.
resp, err = chromedp.Run(ctx, chromedp.NavigateResponse(ts.URL+"/baz"))
if err != nil {
log.Fatal(err)
}
fmt.Println("fourth status code:", resp.Status)
}
Output: first title: / second status code: 200 second title: /foo third status code: 200 fourth status code: 200
func VisibleWindow ¶ added in v0.17.0
func VisibleWindow(a *ExecAllocator)
VisibleWindow is the command line option to run the browser with a visible window. It removes the flags that make the browser quiet or hidden, and it starts the window maximized.
It removes these flags: headless, hide-scrollbars, mute-audio, enable-automation (the infobar that says that software controls the browser) and disable-extensions. It keeps every other flag, and it adds start-maximized. It does not open the developer tools. To open them for every tab, add Flag("auto-open-devtools-for-tabs", true).
Add VisibleWindow after the options that it must change. It only removes the flags that exist when it runs. For example:
opts := append(chromedp.DefaultExecAllocatorOptions[:], chromedp.VisibleWindow) ctx, cancel := chromedp.NewExecAllocator(context.Background(), opts...)
On Linux, Allocate returns ErrNoDisplay when the environment variables DISPLAY and WAYLAND_DISPLAY are both empty. The allocator never falls back to headless mode. Allocate does no such check on macOS and Windows.
Example ¶
This example shows the allocator options. They work with NewExecAllocator, when the program makes its own allocator.
package main
import (
"context"
"log"
"github.com/chromedp/chromedp"
)
func main() {
opts := append(chromedp.DefaultExecAllocatorOptions[:],
chromedp.VisibleWindow,
chromedp.Flag("auto-open-devtools-for-tabs", true),
)
allocCtx, cancel := chromedp.NewExecAllocator(context.Background(), opts...)
defer cancel()
ctx, cancel := chromedp.NewContext(allocCtx)
defer cancel()
if err := chromedp.Do(ctx, chromedp.Navigate("https://example.com")); err != nil {
log.Fatal(err)
}
chromedp.WaitClosed(ctx)
}
Output:
func WaitClosed ¶ added in v0.17.0
WaitClosed blocks until the browser process of the context exits, for example when the user closes the last window, or until ctx ends. It returns nil when the process exited, and the error of ctx otherwise. Use it in a program that must stay alive while the user looks at the window.
If the context has no browser yet, WaitClosed starts one, as Run does. For a browser that an allocator of the remote package reaches, WaitClosed waits until the connection drops, because there is no process to watch.
func WaitNewTarget ¶ added in v0.4.0
WaitNewTarget waits for the current target to open a new target. When fn matches a new target that is not attached, WaitNewTarget sends its target ID on the returned channel. The channel closes without a value when the context has no valid target.
Example ¶
package main
import (
"context"
"fmt"
"io"
"log"
"net/http"
"net/http/httptest"
"strings"
"github.com/chromedp/cdproto/target"
"github.com/chromedp/chromedp"
)
func writeHTML(content string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html")
io.WriteString(w, strings.TrimSpace(content))
})
}
func main() {
ctx, cancel := chromedp.NewContext(context.Background())
defer cancel()
mux := http.NewServeMux()
mux.Handle("/first", writeHTML(`
<input id='newtab' type='button' value='open' onclick='window.open("/second", "_blank");'/>
`))
mux.Handle("/second", writeHTML(``))
ts := httptest.NewServer(mux)
defer ts.Close()
// Grab the first spawned tab that is not blank.
ch := chromedp.WaitNewTarget(ctx, func(info *target.Info) bool {
return info.URL != ""
})
if err := chromedp.Do(ctx,
chromedp.Navigate(ts.URL+"/first"),
chromedp.Click(chromedp.ID("newtab")),
); err != nil {
log.Fatal(err)
}
newCtx, cancel := chromedp.NewContext(ctx, chromedp.WithTargetID(<-ch))
defer cancel()
urlstr, err := chromedp.Run(newCtx, chromedp.Location())
if err != nil {
log.Fatal(err)
}
fmt.Println("new tab's path:", strings.TrimPrefix(urlstr, ts.URL))
}
Output: new tab's path: /second
Types ¶
type Action ¶
Action is a step that runs against the target of a chromedp context and returns a value of the type T. An action that returns no value has the type Action[Void].
An action is a plain func, so a program can write its own:
title := func(ctx context.Context, t *chromedp.Target) (string, error) {
res, err := cdp.Call(ctx, t, runtime.Evaluate, runtime.EvaluateParams{
Expression: "document.title",
ReturnByValue: ptr(true),
})
...
}
The target t is a cdp.Session. Use it with cdp.Call to send a protocol command, and with cdp.Events to receive protocol events.
func AttributeValue ¶
func AttributeValue[S Selectable](sel S, name string, opts ...QueryOption) Action[AttributeResult]
AttributeValue is an element query action that retrieves the element attribute value for the first element node matching the selector. The result tells whether the attribute exists.
func Attributes ¶
func Attributes[S Selectable](sel S, opts ...QueryOption) Action[map[string]string]
Attributes is an element query action that retrieves the element attributes for the first element node matching the selector.
func AttributesAll ¶
func AttributesAll[S Selectable](sel S, opts ...QueryOption) Action[[]map[string]string]
AttributesAll is an element query action that retrieves the element attributes for all element nodes matching the selector. Note: use it with a CSSAll selector.
func Blur ¶
func Blur[S Selectable](sel S, opts ...QueryOption) Action[Void]
Blur is an element query action that unfocuses (blurs) the first element node matching the selector.
func CallFunctionOn ¶ added in v0.7.4
func CallFunctionOn[T any](functionDeclaration string, opt CallOption, args ...any) Action[T]
CallFunctionOn is an action that calls a JavaScript function and decodes the result of the function into the type T.
T is handled as in Evaluate. A function that returns null gives ErrJSNull when T cannot be nil.
Do not set these fields of runtime.CallFunctionOnParams:
- ReturnByValue: CallFunctionOn sets it from the type T.
- Arguments: pass the arguments with args instead.
If the function throws an exception, CallFunctionOn returns it as an error.
func CaptureScreenshot ¶
CaptureScreenshot is an action that takes a screenshot of the current browser viewport.
It acts like the command "Capture screenshot" in Chrome. See the behavior notes of Screenshot for more information.
To take a screenshot of one element, use the Screenshot action.
For an example that takes a screenshot of the entire page, see screenshot.
func Clear ¶
func Clear[S Selectable](sel S, opts ...QueryOption) Action[Void]
Clear is an element query action that clears the values of any input/textarea element nodes matching the selector.
func Click ¶
func Click[S Selectable](sel S, opts ...QueryOption) Action[Void]
Click is an element query action that sends a mouse click event to the first element node matching the selector.
Example ¶
package main
import (
"context"
"fmt"
"log"
"net/http"
"net/http/httptest"
"github.com/chromedp/cdproto/page"
"github.com/chromedp/chromedp"
)
func main() {
ctx, cancel := chromedp.NewContext(context.Background())
defer cancel()
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html")
fmt.Fprintf(w, `<head><title>%s</title></head><body><a id="next" href="/next">next</a></body>`, r.URL.Path)
}))
defer ts.Close()
// Click does not wait for a page load. So WaitEvent subscribes to the
// load event first, then runs the click, and returns the first event
// that comes after it. No event is lost between the click and the wait.
if err := chromedp.Do(ctx, chromedp.Navigate(ts.URL)); err != nil {
log.Fatal(err)
}
_, err := chromedp.Run(ctx, chromedp.WaitEvent(page.LoadEventFired, nil,
chromedp.Click(chromedp.ID("next"))))
if err != nil {
log.Fatal(err)
}
title, err := chromedp.Run(ctx, chromedp.Title())
if err != nil {
log.Fatal(err)
}
fmt.Println("title after the click:", title)
}
Output: title after the click: /next
func ComputedStyle ¶
func ComputedStyle[S Selectable](sel S, opts ...QueryOption) Action[[]*css.ComputedStyleProperty]
ComputedStyle is an element query action that retrieves the computed style of the first element node matching the selector.
func Dimensions ¶
func Dimensions[S Selectable](sel S, opts ...QueryOption) Action[*dom.BoxModel]
Dimensions is an element query action that retrieves the box model dimensions for the first element node matching the selector.
func DoubleClick ¶
func DoubleClick[S Selectable](sel S, opts ...QueryOption) Action[Void]
DoubleClick is an element query action that sends a mouse double click event to the first element node matching the selector.
func DragAndDrop ¶ added in v0.19.0
func DragAndDrop[S, T Selectable](from S, to T, opts ...QueryOption) Action[Void]
DragAndDrop is an element query action that drags the first element node that matches from, and drops it on the first element node that matches to. It presses the left mouse button at the center of the first node, moves the mouse to the center of the second node in several steps, and releases the button. See DragAndDropXY for the details.
The two selectors can have different types. The query options apply to both queries. Both nodes must be in the viewport at the same time, because the action does not scroll while it drags. When they do not fit, the action returns ErrDragOutsideViewport and does not drag.
For example, to move a handle to the end of a slider:
err := chromedp.Do(ctx, chromedp.DragAndDrop(chromedp.CSS("#handle"), chromedp.CSS("#end")))
func DragAndDropXY ¶ added in v0.19.0
DragAndDropXY is an action that drags from the point fromX, fromY and drops at the point toX, toY. The points are in CSS pixels, relative to the viewport. The optional steps value is the number of mouse moves between the two points. The default is 10, and a value below 1 means 1.
The action works for two kinds of page. It handles both with the same calls, and the page decides which one it is:
- A page that listens for mouse events, such as a slider, a drag handle or a sortable list, gets a mousePressed event, the mouseMoved events and a mouseReleased event.
- A page that uses HTML5 drag and drop, with draggable elements and the events dragstart, dragover and drop, gets the same mouse events up to the start of the drag. Then the browser starts a native drag, which a headless browser does not always finish with mouse events. So the action turns on input.SetInterceptDrags, reads the data of the drag from the event input.DragIntercepted, and sends the events dragEnter, dragOver and drop with input.DispatchDragEvent. The page sees them as the real events, with a DataTransfer that holds the data of the drag.
The action turns the interception off when it returns. When an error ends the drag after the mouse button went down, for example when the context ends, the action still releases the button at the last point of the mouse. It uses a new context with a limit of 5 seconds for the release, and ignores an error of the release. A drag that a page starts with a distance that is shorter than the drag threshold of the browser, a few pixels, does not start. Use points that are at least 10 pixels apart.
func Dump ¶ added in v0.9.5
func Dump[S Selectable](sel S, w io.Writer, opts ...QueryOption) Action[Void]
Dump is an element query action that writes a readable tree of the first element node matching the selector and its children. The tree ends at the specified depth.
See DumpTo for more options, which include the sleep wait timeout.
func DumpTo ¶ added in v0.9.5
func DumpTo[S Selectable](sel S, w io.Writer, prefix, indent string, nodeIDs bool, depth int64, pierce bool, wait time.Duration, opts ...QueryOption) Action[Void]
DumpTo is an element query action that writes a readable tree of the first element node matching the selector and its children. The tree ends at the specified depth.
See Dump for a simpler interface.
func Emulate ¶ added in v0.4.0
Emulate is an action to emulate a specific device.
See device for a set of ready-made devices and modes.
Example ¶
package main
import (
"context"
"log"
"os"
"github.com/chromedp/chromedp"
"github.com/chromedp/chromedp/device"
)
func main() {
ctx, cancel := chromedp.NewContext(context.Background())
defer cancel()
if err := chromedp.Do(ctx,
chromedp.Emulate(device.IPhone7),
chromedp.Navigate(`https://duckduckgo.com/`),
chromedp.SendKeys(`textarea[name=q]`, "what's my user agent?\n"),
chromedp.WaitVisible(chromedp.ID(`zci-answer`)),
); err != nil {
log.Fatal(err)
}
buf, err := chromedp.Run(ctx, chromedp.CaptureScreenshot())
if err != nil {
log.Fatal(err)
}
if err := os.WriteFile("iphone7-ua.png", buf, 0o644); err != nil {
log.Fatal(err)
}
// This example uses a live website and writes a file, so it has no
// Output comment: go test builds it and does not run it. A live website
// can change or be slow, and the example made the tests fail on CI.
}
Output:
func EmulateReset ¶ added in v0.4.0
EmulateReset is an action that resets the device emulation.
It resets the viewport, the screen orientation, the user agent, and the mobile and touch emulation. The new values are the original values from the start of the browser.
func EmulateViewport ¶ added in v0.4.0
func EmulateViewport(width, height int64, opts ...EmulateViewportOption) Action[Void]
EmulateViewport is an action that changes the browser viewport.
It wraps calls to emulation.SetDeviceMetricsOverride and emulation.SetTouchEmulationEnabled.
Note: by default, this action sets the screen orientation to landscape and disables mobile and touch emulation. To change that, use the emulate viewport options EmulateOrientation (or EmulateLandscape or EmulatePortrait), EmulateMobile, and EmulateTouch.
func Evaluate ¶
func Evaluate[T any](expression string, opts ...EvaluateOption) Action[T]
Evaluate is an action that evaluates the JavaScript expression and decodes the result of the script into the type T.
When T is Void, Evaluate ignores the script result.
When T is []byte, the result is the raw JSON-encoded value of the script result.
When T is *runtime.RemoteObject, the result is the low-level protocol type, and Evaluate does not convert it. The original objects can stay in memory until the page navigates or closes. Use `runtime.ReleaseObject` or `runtime.ReleaseObjectGroup` to ask the browser to release them.
For all other types, the script returns the result "by value" (that is, JSON-encoded). Evaluate then decodes it into a value of type T. Only a chan, func, interface, map, pointer, or slice type can be nil. When the script result is "undefined" or "null" and T cannot be nil, the action returns ErrJSUndefined or ErrJSNull respectively. The expression `null` gives ErrJSNull for an int, and a nil pointer for a *int. The expression `Promise.resolve(1)` needs the option EvalAwaitPromise.
For example:
n, err := chromedp.Run(ctx, chromedp.Evaluate[int](`1 + 2`))
Example ¶
package main
import (
"context"
"fmt"
"log"
"github.com/chromedp/cdproto/runtime"
"github.com/chromedp/chromedp"
)
func main() {
ctx, cancel := chromedp.NewContext(context.Background())
defer cancel()
// Ignore the result:
{
if err := chromedp.Do(ctx, chromedp.Evaluate[chromedp.Void](`window.scrollTo(0, 100)`)); err != nil {
log.Fatal(err)
}
}
// Receive a primary value:
{
sum, err := chromedp.Run(ctx, chromedp.Evaluate[int](`1+2`))
if err != nil {
log.Fatal(err)
}
fmt.Println(sum)
}
// ErrJSUndefined:
{
if _, err := chromedp.Run(ctx, chromedp.Evaluate[int](`undefined`)); err != nil {
fmt.Println(err)
}
}
// ErrJSNull:
{
if _, err := chromedp.Run(ctx, chromedp.Evaluate[int](`null`)); err != nil {
fmt.Println(err)
}
}
// Accept undefined/null result:
{
val, err := chromedp.Run(ctx, chromedp.Evaluate[*int](`undefined`))
if err != nil {
log.Fatal(err)
}
fmt.Println(val)
}
// Receive an array value:
{
val, err := chromedp.Run(ctx, chromedp.Evaluate[[]int](`[1,2]`))
if err != nil {
log.Fatal(err)
}
fmt.Println(val)
}
// Map and Slice accept undefined/null:
{
val, err := chromedp.Run(ctx, chromedp.Evaluate[[]int](`null`))
if err != nil {
log.Fatal(err)
}
fmt.Println("slice is nil:", val == nil)
}
// Receive the raw bytes:
{
buf, err := chromedp.Run(ctx, chromedp.Evaluate[[]byte](`alert`))
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s\n", buf)
}
// Receive the RemoteObject:
{
res, err := chromedp.Run(ctx, chromedp.Evaluate[*runtime.RemoteObject](`alert`))
if err != nil {
log.Fatal(err)
}
if res.ObjectID != "" {
fmt.Println("objectId is present")
}
}
}
Output: 3 encountered an undefined value encountered a null value <nil> [1 2] slice is nil: true {} objectId is present
func EvaluateAsDevTools ¶
func EvaluateAsDevTools[T any](expression string, opts ...EvaluateOption) Action[T]
EvaluateAsDevTools is an action that evaluates a JavaScript expression as Chrome DevTools does. It evaluates the expression in the "console" context and makes the Command Line API available to the script.
See Evaluate for how the expressions are evaluated.
Note: do not use this with untrusted JavaScript.
func ExposeFunc ¶ added in v0.19.0
ExposeFunc is an action that makes the Go func fn available to the page as window.<name>. A page script calls it like an async function. The call returns a promise that the browser settles with the result of fn, or rejects with an Error when fn returns an error. It is like exposeFunction in Puppeteer.
The function is there in the current document and in every document that the target loads later, for the main frame and for every iframe of the same site, so it survives a navigation. An iframe of another site runs in another process and is another target, so the function is not there. It stays until the target ends. The listener for the calls stops when the context of the target ends. A second call of ExposeFunc with the same name on the same target returns an error. So does a name that is empty, that is not valid UTF-8, or that starts with "__chromedp_", the prefix of the private names of the package.
A script passes its arguments as JSON, so a value such as a function or a DOM node does not work. How the arguments reach fn depends on the type A:
- When A is a slice type, such as []any or []float64, fn gets all the arguments of the call in the slice. Use it for a call with several arguments, or with none.
- For every other A, the call must have one argument, and the action decodes it into A. Use a struct for an object, or a basic type. A call with no argument gives the zero value of A, and a call with more than one argument is an error that rejects the promise.
The action encodes the result of fn as JSON for the page. When R is Void, the promise resolves with undefined.
The action runs fn in a new goroutine for each call, so fn can run several times at the same time and must be safe for that. The ctx of fn has the values of the context that ExposeFunc received, and it ends when the target ends. If fn panics, the promise rejects with an Error whose message is "panic:" and the panic value, for example "panic: boom". The message of an error that fn returns replaces each byte that is not valid UTF-8 with U+FFFD.
For example, a page that calls window.square(7):
err := chromedp.Do(ctx,
chromedp.ExposeFunc("square", func(ctx context.Context, n float64) (float64, error) {
return n * n, nil
}),
chromedp.Navigate(url),
)
func Focus ¶
func Focus[S Selectable](sel S, opts ...QueryOption) Action[Void]
Focus is an element query action that focuses the first element node matching the selector.
func FullScreenshot ¶ added in v0.7.0
FullScreenshot takes a full screenshot of the entire browser viewport, with the given image quality.
It acts like the command "Capture full size screenshot" in Chrome. See the behavior notes of Screenshot for more information.
The valid range of the compression quality is [0..100]. When the quality is 100, the image format is png. Otherwise the image format is jpeg.
Example ¶
package main
import (
"context"
"fmt"
"log"
"os"
"github.com/chromedp/chromedp"
)
func main() {
ctx, cancel := chromedp.NewContext(context.Background())
defer cancel()
if err := chromedp.Do(ctx, chromedp.Navigate(`https://google.com`)); err != nil {
log.Fatal(err)
}
buf, err := chromedp.Run(ctx, chromedp.FullScreenshot(90))
if err != nil {
log.Fatal(err)
}
if err := os.WriteFile("fullScreenshot.jpeg", buf, 0o644); err != nil {
log.Fatal(err)
}
fmt.Println("wrote fullScreenshot.jpeg")
}
Output: wrote fullScreenshot.jpeg
func Func ¶ added in v0.17.0
Func makes an action that returns no value from a func that returns only an error.
func InnerHTML ¶
func InnerHTML[S Selectable](sel S, opts ...QueryOption) Action[string]
InnerHTML is an element query action that retrieves the inner html of the first element node matching the selector.
func JavascriptAttribute ¶
func JavascriptAttribute[T any, S Selectable](sel S, name string, opts ...QueryOption) Action[T]
JavascriptAttribute is an element query action that retrieves the JavaScript attribute for the first element node matching the selector. It decodes the attribute into the type T, as Evaluate does, with one difference. When the attribute is null, for example "onclick" with no handler, JavascriptAttribute returns the zero value of T and no error, and it does not return ErrJSNull. An attribute that the element does not have is undefined, and the action returns an error that wraps ErrJSUndefined for a type that cannot be nil.
func KeyEvent ¶ added in v0.4.0
KeyEvent is a key action that synthesizes a keyDown, char, and keyUp event for each rune in keys, with any key options.
Only well-known, "printable" characters get char events. A key with the modifier Ctrl, Alt or Meta gets no char event, because the char event types the character on top of the shortcut. For example, Ctrl+A selects the text and types no "a". A key with the modifier Shift keeps its char event.
See the SendKeys action to synthesize key events for a specific element node.
See the kb package for implementation details and a list of well-known keys.
func KeyEventNode ¶ added in v0.4.0
KeyEventNode is a key action that dispatches a key event on an element node.
func Legacy ¶ added in v0.17.0
Legacy makes an action from an action of the previous version. The old action receives the same context, so Call and CallBrowser work inside it.
Example ¶
package main
import (
"context"
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"net/http/httptest"
"strings"
"github.com/chromedp/cdproto/runtime"
"github.com/chromedp/chromedp"
)
func writeHTML(content string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html")
io.WriteString(w, strings.TrimSpace(content))
})
}
// oldTitle is an action of the previous version of chromedp. It has a Do
// method.
type oldTitle struct{ res *string }
func (a oldTitle) Do(ctx context.Context) error {
res, err := chromedp.Call(ctx, runtime.Evaluate, runtime.EvaluateParams{
Expression: "document.title",
ReturnByValue: ptr(true),
})
if err != nil {
return err
}
return json.Unmarshal(res.Result.Value, a.res)
}
func main() {
ctx, cancel := chromedp.NewContext(context.Background())
defer cancel()
ts := httptest.NewServer(writeHTML(`<title>old action</title>`))
defer ts.Close()
var title string
if err := chromedp.Do(ctx,
chromedp.Navigate(ts.URL),
chromedp.Legacy(oldTitle{&title}),
); err != nil {
log.Fatal(err)
}
fmt.Println(title)
}
// ptr returns a pointer to a copy of v. It sets the optional fields of the
// protocol types, which are pointers.
func ptr[T any](v T) *T {
return &v
}
Output: old action
func MatchedStyle ¶
func MatchedStyle[S Selectable](sel S, opts ...QueryOption) Action[*css.GetMatchedStylesForNodeResult]
MatchedStyle is an element query action that retrieves the matched style information for the first element node matching the selector.
func MouseClickNode ¶
func MouseClickNode(n *Node, opts ...MouseOption) Action[Void]
MouseClickNode is an action that dispatches a left mouse button click event at the center of a node.
Note: the action scrolls the window if the node is not within the viewport of the window.
func MouseClickXY ¶
func MouseClickXY(x, y float64, opts ...MouseOption) Action[Void]
MouseClickXY is an action that sends a left mouse button click (that is, a mousePressed and a mouseReleased event) to the X, Y location.
func MouseEvent ¶ added in v0.4.0
func MouseEvent(typ input.DispatchMouseEventType, x, y float64, opts ...MouseOption) Action[Void]
MouseEvent is a mouse event action to dispatch the specified mouse event type at coordinates x, y.
func Navigate ¶
Navigate is an action that navigates the current frame and waits for the page to load.
This action does not collect HTTP response information. To get it, use NavigateResponse or RunResponse.
func NavigateBack ¶
NavigateBack is an action that navigates the current frame backwards in its history, and waits for the page to load.
func NavigateForward ¶
NavigateForward is an action that navigates the current frame forwards in its history, and waits for the page to load.
func NavigateResponse ¶ added in v0.17.0
NavigateResponse is like Navigate, and returns the HTTP response of the HTML document.
func NavigateToHistoryEntry ¶
NavigateToHistoryEntry is an action to navigate to the specified navigation entry, and wait for the page to load.
func NavigationEntries ¶
func NavigationEntries() Action[page.GetNavigationHistoryResult]
NavigationEntries is an action that retrieves the page's navigation history entries. The result holds the index of the current entry and the entries.
func Nodes ¶
func Nodes[S Selectable](sel S, opts ...QueryOption) Action[[]*Node]
Nodes is an element query action that retrieves the document element nodes matching the selector.
func OuterHTML ¶
func OuterHTML[S Selectable](sel S, opts ...QueryOption) Action[string]
OuterHTML is an element query action that retrieves the outer html of the first element node matching the selector.
func Poll ¶ added in v0.6.11
func Poll[T any](expression string, opts ...PollOption) Action[T]
Poll is a poll action that waits for a general JavaScript predicate. It builds the predicate from a JavaScript expression.
This is a copy of page.waitForFunction of puppeteer. It is named Poll on purpose, so that it does not mix with the Wait* query actions. The behavior is not guaranteed to be compatible. For example, in our implementation the poll task does not survive a navigation. In this case the action returns an error (see unit test TestPoll/NotSurviveNavigation).
Polling Options ¶
The default polling mode is "raf". It runs pageFunction in a requestAnimationFrame callback all the time. This is the tightest polling mode, and it is suitable to observe styling changes. The WithPollingInterval option polls the predicate at a given interval. The WithPollingMutation option polls the predicate on every DOM mutation.
The WithPollingTimeout option sets the maximum time to wait until the predicate returns a truthy value. It defaults to 30 seconds. Pass 0 to disable the timeout.
The WithPollingInFrame option sets the frame in which to evaluate the predicate. Without it, the action evaluates the predicate in the root page of the current tab.
The WithPollingArgs option gives extra arguments to the predicate. Use this option only when the predicate is built from a function. See PollFunction.
The action returns the truthy value of the predicate, decoded into the type T. T is handled as in Evaluate. Use Void when the value does not matter.
func PollFunction ¶ added in v0.6.11
func PollFunction[T any](pageFunction string, opts ...PollOption) Action[T]
PollFunction is a poll action that waits for a general JavaScript predicate. It builds the predicate from a JavaScript function.
See Poll for how to build poll tasks.
func PrintToPDF ¶ added in v0.19.0
PrintToPDF is an action that prints the page to a PDF file, and returns the bytes of the file. With no option, the browser prints on Letter paper, in portrait, with the margins of 1 cm, and with no header, footer or background.
A length is in inches, and a CSS pixel is 1/96 of an inch. For example, a landscape A4 page with a header and a page number:
buf, err := chromedp.Run(ctx, chromedp.PrintToPDF( chromedp.PDFPaper(chromedp.PaperA4), chromedp.PDFLandscape(), chromedp.PDFMargin(0.5), chromedp.PDFPrintBackground(), chromedp.PDFHeaderTemplate(`<div style="font-size:8px"><span class="title"></span></div>`), chromedp.PDFFooterTemplate(`<div style="font-size:8px"><span class="pageNumber"></span></div>`), ))
For a field that no option sets, send page.PrintToPDF yourself with cdp.Call, and give an option that changes the parameters. An option is a func, so it can do that:
func(p *page.PrintToPDFParams) { p.TransferMode = page.PrintToPDFTransferModeReturnAsStream }
The browser returns an error when the page ranges select no page. Wait for the page to load before the call.
Example ¶
package main
import (
"context"
"log"
"os"
"github.com/chromedp/cdproto/cdp"
"github.com/chromedp/cdproto/page"
"github.com/chromedp/chromedp"
)
func main() {
ctx, cancel := chromedp.NewContext(context.Background())
defer cancel()
// A custom action sends the protocol command with cdp.Call. It returns
// the bytes of the PDF file.
printToPDF := func(ctx context.Context, t *chromedp.Target) ([]byte, error) {
res, err := cdp.Call(ctx, t, page.PrintToPDF, page.PrintToPDFParams{
DisplayHeaderFooter: ptr(false),
Landscape: ptr(true),
})
return res.Data, err
}
if err := chromedp.Do(ctx, chromedp.Navigate(`https://pkg.go.dev/github.com/chromedp/chromedp`)); err != nil {
log.Fatal(err)
}
buf, err := chromedp.Run(ctx, printToPDF)
if err != nil {
log.Fatal(err)
}
if err := os.WriteFile("page.pdf", buf, 0o644); err != nil {
log.Fatal(err)
}
// This example uses a live website and writes a file, so it has no
// Output comment: go test builds it and does not run it. A live website
// can change or be slow, and the example made the tests fail on CI.
}
// ptr returns a pointer to a copy of v. It sets the optional fields of the
// protocol types, which are pointers.
func ptr[T any](v T) *T {
return &v
}
Output:
Example (Options) ¶
package main
import (
"context"
"log"
"os"
"github.com/chromedp/chromedp"
)
func main() {
ctx, cancel := chromedp.NewContext(context.Background())
defer cancel()
if err := chromedp.Do(ctx, chromedp.Navigate(`https://pkg.go.dev/github.com/chromedp/chromedp`)); err != nil {
log.Fatal(err)
}
// The options replace the page.PrintToPDFParams of the example above.
buf, err := chromedp.Run(ctx, chromedp.PrintToPDF(
chromedp.PDFPaper(chromedp.PaperA4),
chromedp.PDFLandscape(),
chromedp.PDFMargin(0.5),
chromedp.PDFPrintBackground(),
chromedp.PDFFooterTemplate(`<div style="font-size:8px"><span class="pageNumber"></span> / <span class="totalPages"></span></div>`),
))
if err != nil {
log.Fatal(err)
}
if err := os.WriteFile("page.pdf", buf, 0o644); err != nil {
log.Fatal(err)
}
// This example uses a live website and writes a file, so it has no
// Output comment.
}
Output:
func Query ¶
func Query[S Selectable](sel S, opts ...QueryOption) Action[Void]
Query is an action that queries the browser for element nodes that match the criteria, and waits until they meet the node conditions. It returns no value. To get the nodes, see Nodes.
Query actions that target element nodes share one selector. Use the After option or QueryAfter to read data from the selected elements or to change them.
For example:
chromedp.Do(ctx, chromedp.SendKeys(chromedp.ID("thing"), "hello"))
This runs a SendKeys action on the first element that has the id "thing".
Element selection queries work with specific actions. They are the main way to automate steps in the browser. They have this form:
Action(selector[, parameter1, ...parameterN][, queryOptions...])
Where:
- Action - the action to run
- selector - the element query, a Selectable value. The action applies to every node that matches it.
- parameter[1-N] - the parameters that the action needs (if any)
- queryOptions - change how the query runs, or how it waits for nodes
An action that reads a value returns it. For example, Text returns the text as a string.
Selectors ¶
The type of the selector chooses the lookup that the browser runs. A plain string, or any other string type that this package does not define, is a Search.
The Search type (the default) queries elements by plain text, CSS selector, or XPath query. It wraps DOM.performSearch.
The ID type queries a single element by its CSS ID. It wraps DOM.querySelector. ID is like document.querySelector('#' + ID) in the browser.
The CSS type queries a single element with a CSS selector. It wraps DOM.querySelector. CSS is like document.querySelector() in the browser.
The CSSAll type queries elements with a CSS selector. It wraps DOM.querySelectorAll. CSSAll is like document.querySelectorAll() in the browser.
The JSPath type queries a single element by its "JS Path" value. It wraps Runtime.evaluate. JSPath is like a JavaScript snippet that returns an element in the browser. Use it only with trusted element queries. chromedp passes the query directly to Runtime.evaluate and does not sanitize it. The type is useful for DOM elements that the other types cannot retrieve, such as ShadowDOM elements. The expression can give a node, an array or a NodeList of nodes, or null or undefined. Null, undefined and an empty list select no element, so WaitNotPresent succeeds and the other waits keep waiting. Any other value is an error, and the query returns it at once.
The NodeIDs type selects the elements with the given node IDs. It uses DOM.requestChildNodes to retrieve them.
A type outside the Selectable set, such as an int or a *Node, does not compile.
Query Options ¶
The Node* options set node conditions. The query waits until the condition is true. Without a Node* option, the query uses the NodeReady condition.
The AtLeast option sets the minimum number of nodes that the query must return. The default is 1.
The After option sets a func that runs after the query returns one or more elements and the node condition is true.
The ByFunc option replaces the lookup of the selector with a custom func.
Node Options ¶
The NodeReady option (the default) makes the query wait until the browser has returned all element nodes that match the selector.
The NodeVisible option makes the query wait until the browser has returned all element nodes that match the selector, and they are visible.
The NodeNotVisible option makes the query wait until the browser has returned all element nodes that match the selector, and they are not visible.
The NodeEnabled option makes the query wait until the browser has returned all element nodes that match the selector. The nodes must be enabled (that is, they have no 'disabled' attribute).
The NodeSelected option makes the query wait until the browser has returned all element nodes that match the selector. The nodes must be selected (that is, they have a 'selected' attribute).
The NodeNotPresent option makes the query wait until no element node matches the selector.
func QueryAfter ¶
func QueryAfter[T any, S Selectable](sel S, f func(ctx context.Context, t *Target, nodes []*Node) (T, error), opts ...QueryOption) Action[T]
QueryAfter is an element query action that queries the browser for selector sel. It waits until the node conditions of the query are met, then runs f and returns its value.
func QueryNodeIDs ¶ added in v0.17.0
func QueryNodeIDs[S Selectable](sel S, opts ...QueryOption) Action[[]cdp.NodeID]
QueryNodeIDs is an element query action that retrieves the element node IDs matching the selector.
func RemoveAttribute ¶
func RemoveAttribute[S Selectable](sel S, name string, opts ...QueryOption) Action[Void]
RemoveAttribute is an element query action that removes the element attribute with name from the first element node matching the selector.
func Reset ¶
func Reset[S Selectable](sel S, opts ...QueryOption) Action[Void]
Reset is an element query action that resets the parent form of the first element node matching the selector.
func ResetViewport ¶ added in v0.4.0
ResetViewport is an action that resets the browser viewport to the values that the browser started with.
Note: it does not change the emulated User-Agent of the browser, if any.
func Screenshot ¶
func Screenshot[S Selectable](sel S, opts ...QueryOption) Action[[]byte]
Screenshot is an element query action that takes a screenshot of the first element node that matches the selector.
It acts like the command "Capture node screenshot" in Chrome.
Behavior notes: the Protocol Monitor shows that the command also sends these protocol commands:
- Emulation.clearDeviceMetricsOverride
- Network.setUserAgentOverride with {"userAgent": ""}
- Overlay.setShowViewportSizeOnResize with {"show": false}
chromedp does not send these protocol commands. If the result is not what you expect, send them yourself.
To capture the browser viewport, see CaptureScreenshot.
For an example that takes a screenshot of the entire page, see screenshot.
func ScreenshotNodes ¶ added in v0.9.4
ScreenshotNodes is an action that takes a screenshot of the specified nodes. It calculates the extents from the top most left node and the bottom most right node.
func ScreenshotScale ¶ added in v0.9.3
func ScreenshotScale[S Selectable](sel S, scale float64, opts ...QueryOption) Action[[]byte]
ScreenshotScale is like Screenshot but takes a scale parameter, which is the page scale factor.
func ScrollIntoView ¶
func ScrollIntoView[S Selectable](sel S, opts ...QueryOption) Action[Void]
ScrollIntoView is an element query action that scrolls the window to the first element node matching the selector.
func SendKeys ¶
func SendKeys[S Selectable](sel S, v string, opts ...QueryOption) Action[Void]
SendKeys is an element query action that sends key events to the first element node that matches the selector. It synthesizes the key down, char, and key up events that the runes in v need.
See keys for a complete example of how to use SendKeys.
Note: when the element query matches an input[type="file"] node, SendKeys uses dom.SetFileInputFiles to set the upload path of the input node to v.
A "\n" in v is the Enter key. SendKeys sends it as "\r", which is the same as kb.Enter: a keyDown event, a char event with the text "\r", and a keyUp event. An editor that handles Enter on keydown and cancels the default, such as Lexical, can then insert two line breaks, because the char event inserts one more. To send the Enter key with no char event, send a rawKeyDown event and a keyUp event with the command input.DispatchKeyEvent:
enter := chromedp.Func(func(ctx context.Context, t *chromedp.Target) error {
for _, typ := range []input.DispatchKeyEventType{
input.DispatchKeyEventTypeRawKeyDown, input.DispatchKeyEventTypeKeyUp,
} {
_, err := cdp.Call(ctx, t, input.DispatchKeyEvent, input.DispatchKeyEventParams{
Type: typ, Key: "Enter", Code: "Enter",
WindowsVirtualKeyCode: 13, NativeVirtualKeyCode: 13,
})
if err != nil {
return err
}
}
return nil
})
err := chromedp.Do(ctx,
chromedp.SendKeys(sel, "Hello"),
enter,
chromedp.SendKeys(sel, "World"),
)
Example ¶
package main
import (
"context"
"fmt"
"io"
"log"
"net/http"
"net/http/httptest"
"strings"
"github.com/chromedp/chromedp"
)
func writeHTML(content string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html")
io.WriteString(w, strings.TrimSpace(content))
})
}
func main() {
ctx, cancel := chromedp.NewContext(context.Background())
defer cancel()
ts := httptest.NewServer(writeHTML(`
<body>
<form id="form"><input id="name" name="name"/><input id="color" name="color"/></form>
</body>
`))
defer ts.Close()
if err := chromedp.Do(ctx,
chromedp.Navigate(ts.URL),
chromedp.SendKeys(chromedp.ID("name"), "Ada"),
chromedp.SetValue(chromedp.ID("color"), "green"),
); err != nil {
log.Fatal(err)
}
name, err := chromedp.Run(ctx, chromedp.Value(chromedp.ID("name")))
if err != nil {
log.Fatal(err)
}
color, err := chromedp.Run(ctx, chromedp.Value(chromedp.ID("color")))
if err != nil {
log.Fatal(err)
}
fmt.Println(name, color)
}
Output: Ada green
func SetAttributeValue ¶
func SetAttributeValue[S Selectable](sel S, name, value string, opts ...QueryOption) Action[Void]
SetAttributeValue is an element query action that sets the element attribute with name to value for the first element node matching the selector.
func SetAttributes ¶
func SetAttributes[S Selectable](sel S, attributes map[string]string, opts ...QueryOption) Action[Void]
SetAttributes is an element query action that sets the element attributes for the first element node matching the selector.
func SetJavascriptAttribute ¶
func SetJavascriptAttribute[S Selectable](sel S, name, value string, opts ...QueryOption) Action[Void]
SetJavascriptAttribute is an element query action that sets the JavaScript attribute for the first element node matching the selector.
func SetUploadFiles ¶
func SetUploadFiles[S Selectable](sel S, files []string, opts ...QueryOption) Action[Void]
SetUploadFiles is an element query action that sets the files to upload for the first element node matching the selector. The node must be an input[type="file"] node.
func SetValue ¶
func SetValue[S Selectable](sel S, value string, opts ...QueryOption) Action[Void]
SetValue is an element query action that sets the JavaScript value of the first element node matching the selector.
Use it to set the JavaScript value of a form, input, textarea, select, or other element with a '.value' field.
func Steps ¶ added in v0.17.0
Steps joins the actions into one action that runs them in order and stops at the first error. It replaces the type Tasks.
func Submit ¶
func Submit[S Selectable](sel S, opts ...QueryOption) Action[Void]
Submit is an element query action that submits the parent form of the first element node matching the selector.
func Tap ¶ added in v0.19.0
func Tap[S Selectable](sel S, opts ...QueryOption) Action[Void]
Tap is an element query action that sends a touch tap to the center of the first element node matching the selector. The action scrolls the node into view, and then sends a touchStart event and a touchEnd event. See TapXY.
The browser sends the touch events and the click event to the page only when touch emulation is on. Use EmulateViewport with EmulateTouch for it.
func TapXY ¶ added in v0.19.0
TapXY is an action that sends a touch tap to the X, Y location. It sends a touchStart event and then a touchEnd event with one touch point. The browser turns the touch into a click event, if the page runs with touch emulation. See EmulateTouch.
func Text ¶
func Text[S Selectable](sel S, opts ...QueryOption) Action[string]
Text is an element query action that retrieves the visible text of the first element node matching the selector.
func TextContent ¶ added in v0.4.1
func TextContent[S Selectable](sel S, opts ...QueryOption) Action[string]
TextContent is an element query action that retrieves the text content of the first element node matching the selector.
func Title ¶
Title is an action that retrieves the document title.
Example ¶
package main
import (
"context"
"fmt"
"io"
"log"
"net/http"
"net/http/httptest"
"strings"
"github.com/chromedp/chromedp"
)
func writeHTML(content string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html")
io.WriteString(w, strings.TrimSpace(content))
})
}
func main() {
ctx, cancel := chromedp.NewContext(context.Background())
defer cancel()
ts := httptest.NewServer(writeHTML(`
<head>
<title>fancy website title</title>
</head>
<body>
<div id="content"></div>
</body>
`))
defer ts.Close()
if err := chromedp.Do(ctx, chromedp.Navigate(ts.URL)); err != nil {
log.Fatal(err)
}
title, err := chromedp.Run(ctx, chromedp.Title())
if err != nil {
log.Fatal(err)
}
fmt.Println(title)
}
Output: fancy website title
func Value ¶
func Value[S Selectable](sel S, opts ...QueryOption) Action[string]
Value is an element query action that retrieves the JavaScript value field of the first element node matching the selector.
Use it to read the JavaScript value of a form, input, textarea, select, or other element with a '.value' field.
Value follows JavascriptAttribute. An element without a '.value' field gives an error that wraps ErrJSUndefined.
func WaitEnabled ¶
func WaitEnabled[S Selectable](sel S, opts ...QueryOption) Action[Void]
WaitEnabled is an element query action that waits until the element that matches the selector is enabled (that is, it has no attribute 'disabled').
func WaitEvent ¶ added in v0.17.0
WaitEvent makes an action that waits for an event. It subscribes to the event, runs the trigger action, and then returns the first payload for which match returns true. A nil match accepts every payload. The trigger runs after the subscription, so the event cannot arrive too early.
For example, to wait for the load event that a click causes:
_, err := chromedp.Run(ctx, chromedp.WaitEvent(page.LoadEventFired, nil,
chromedp.Click(chromedp.CSS("a"))))
When the context ends before a matching event arrives, WaitEvent returns the error of the context.
func WaitNotPresent ¶
func WaitNotPresent[S Selectable](sel S, opts ...QueryOption) Action[Void]
WaitNotPresent is an element query action that waits until no element that matches the selector is present.
func WaitNotVisible ¶
func WaitNotVisible[S Selectable](sel S, opts ...QueryOption) Action[Void]
WaitNotVisible is an element query action that waits until the element matching the selector is not visible.
func WaitReady ¶
func WaitReady[S Selectable](sel S, opts ...QueryOption) Action[Void]
WaitReady is an element query action that waits until the element that matches the selector is ready (that is, "loaded").
func WaitSelected ¶
func WaitSelected[S Selectable](sel S, opts ...QueryOption) Action[Void]
WaitSelected is an element query action that waits until the element that matches the selector is selected (that is, it has the attribute 'selected').
func WaitVisible ¶
func WaitVisible[S Selectable](sel S, opts ...QueryOption) Action[Void]
WaitVisible is an element query action that waits until the element matching the selector is visible.
type Allocator ¶ added in v0.2.0
type Allocator interface {
// Allocate creates a new browser. Canceling the provided context frees all
// resources of the browser, such as temporary directories.
Allocate(context.Context, ...BrowserOption) (*Browser, error)
// Wait blocks until the allocator has freed all of its resources.
// Canceling the allocator context does this too, so normally you do not
// need to call Wait.
Wait()
}
An Allocator creates and manages a number of browsers.
This interface hides how the browser process runs. For example, an Allocator can reuse browser processes, or connect to browsers that already run on remote machines.
type Attacher ¶ added in v0.18.0
type Attacher interface {
// Attaches reports whether the allocator attaches to a browser that
// runs already.
Attaches() bool
}
An Attacher is an optional interface of an Allocator. An allocator that implements it connects to a browser that already runs, and it does not start the browser itself. NewContext then treats the context of such an allocator as a new tab of that browser, and not as the owner of a browser process. The allocator of the package github.com/chromedp/chromedp/remote implements it.
type AttributeResult ¶ added in v0.17.0
type AttributeResult struct {
// Value is the value of the attribute. It is empty when the attribute
// does not exist.
Value string
// Exists is true when the element has the attribute.
Exists bool
}
AttributeResult is the result of the AttributeValue action.
type Browser ¶ added in v0.2.0
type Browser struct {
// LostConnection is closed when the connection to Chrome drops. The
// connection is a pipe or a websocket.
// Use it to make sure that the context of the Browser is canceled (and the
// handler stopped) after the connection fails.
LostConnection chan struct{}
// contains filtered or unexported fields
}
Browser manages a browser through the Chrome DevTools Protocol. It handles the browser process runner, the connection to the browser, the targets, and the network, page, and DOM events. The connection is a pipe or a websocket.
func NewBrowserTransport ¶ added in v0.17.0
func NewBrowserTransport(ctx context.Context, tr Transport, opts ...BrowserOption) (*Browser, error)
NewBrowserTransport creates a new browser that uses tr, a connection to a browser that is already open, such as a *PipeConn. The browser closes tr when it stops. Typically you do not call it directly, because the Allocator interface does it.
func (*Browser) Call ¶ added in v0.17.0
Call sends the command to the browser, waits for the response, and decodes the result into res. It satisfies cdp.Session.
Call returns a browser error as a *cdproto.Error. It returns an error when the connection to the browser is lost, also when ctx never ends. The error wraps the reason of the loss and context.Canceled.
func (*Browser) Process ¶ added in v0.7.2
Process returns the process object of the browser.
It is nil when the browser was allocated by an allocator that attaches to a browser that runs already, such as the allocator of the remote package. A monitoring system can use it to collect process metrics of the browser process (see prometheus.NewProcessCollector for an example).
Example:
if process := chromedp.FromContext(ctx).Browser.Process(); process != nil {
fmt.Printf("Browser PID: %v", process.Pid)
}
type BrowserOption ¶ added in v0.2.0
type BrowserOption = func(*Browser)
BrowserOption is a browser option.
func WithBrowserDebugf ¶ added in v0.2.0
func WithBrowserDebugf(f func(string, ...any)) BrowserOption
WithBrowserDebugf is a browser option that sets the func that receives the protocol messages.
func WithBrowserErrorf ¶ added in v0.2.0
func WithBrowserErrorf(f func(string, ...any)) BrowserOption
WithBrowserErrorf is a browser option that sets the func that receives error messages.
func WithBrowserLogf ¶ added in v0.2.0
func WithBrowserLogf(f func(string, ...any)) BrowserOption
WithBrowserLogf is a browser option that sets the func that receives general log messages.
func WithConsolef ¶
func WithConsolef(f func(string, ...any)) BrowserOption
WithConsolef is a browser option that sets the func that receives chrome log events.
Note: it is not implemented yet.
type CSS ¶ added in v0.17.0
type CSS string
CSS is a selector for the first element that matches a CSS selector. It uses DOM.querySelector.
type CSSAll ¶ added in v0.17.0
type CSSAll string
CSSAll is a selector for every element that matches a CSS selector. It uses DOM.querySelectorAll.
type CallOption ¶ added in v0.7.4
type CallOption = func(params *runtime.CallFunctionOnParams)
CallOption is a func that changes the runtime.CallFunctionOnParams of a call.
type ConsoleMessage ¶ added in v0.19.0
type ConsoleMessage struct {
// Type is the kind of the message. An uncaught exception and an unhandled
// promise rejection have the type [ConsoleException]. An entry of the browser
// log has the type "debug", "info", "warning" or "error", for the levels
// verbose, info, warning and error.
Type ConsoleType
// Text is the text that the DevTools console shows. A string argument is
// there as it is, and another value has its description or a short form of
// its properties. A format such as %s and %d in the first argument takes the
// arguments that follow it. For an exception, the text is the error and its
// message, and the stack is in Stack.
Text string
// Args are the arguments of the call to the console API, as the protocol
// reports them. The objects have no value, only a description and a
// preview. Use [runtime.GetProperties] with the object id to read one. Args
// is empty for an exception and for an entry of the browser log.
Args []*runtime.RemoteObject
// Time is the time of the message, as the browser reports it.
Time time.Time
// URL, Line and Column tell where the message came from. A call of the
// console API has the place of the call. An exception has the place of the
// throw. They can be empty. The line and the column start at 0, as in the
// protocol.
URL string
Line int64
Column int64
// Stack is the stack trace of the call or of the exception. It is nil when
// the browser reports none.
Stack *runtime.StackTrace
// Exception holds the details of an exception, and it is nil for another
// message.
Exception *runtime.ExceptionDetails
// Source tells which part of the browser wrote a message of the browser
// log, for example "network" or "security". It is empty for a call of the
// console API and for an exception.
Source string
}
ConsoleMessage is a message that the page wrote to the console. It is a call of the console API, an exception that nothing caught, or an entry of the browser log.
func (ConsoleMessage) IsException ¶ added in v0.19.0
func (m ConsoleMessage) IsException() bool
IsException reports whether the message is an uncaught exception or an unhandled promise rejection.
func (ConsoleMessage) String ¶ added in v0.19.0
func (m ConsoleMessage) String() string
String returns the type and the text of the message.
type ConsoleType ¶ added in v0.19.0
type ConsoleType string
ConsoleType is the kind of a ConsoleMessage. The values for a call of the console API are the names of the protocol, such as "log", "warning" and "error". The package defines a constant for the common ones.
const ( ConsoleLog ConsoleType = "log" ConsoleDebug ConsoleType = "debug" ConsoleInfo ConsoleType = "info" ConsoleWarning ConsoleType = "warning" ConsoleError ConsoleType = "error" ConsoleException ConsoleType = "exception" )
Console message types.
type Context ¶ added in v0.2.0
type Context struct {
// Allocator creates new browsers. A child context inherits it from the
// parent context.
Allocator Allocator
// Browser is the browser of the context. A child context inherits it from
// the parent context.
Browser *Browser
// Target is the target that actions run against. A child context does not
// inherit it. Typically each context has its own Target, which points to a
// separate browser tab (page).
Target *Target
// BrowserContextID is set by WithExistingBrowserContext.
//
// Otherwise, BrowserContextID is not empty in these cases:
//
// 1. The context was made with WithNewBrowserContext. Its first run creates
// a new BrowserContext, and BrowserContextID holds the id of that
// BrowserContext.
//
// 2. The context was not made with WithTargetID, and the parent context
// has a BrowserContextID that is not empty. The context copies it from the
// parent context.
BrowserContextID cdp.BrowserContextID
// contains filtered or unexported fields
}
Context is the data that NewContext stores in a context.Context. Run needs it.
func FromContext ¶ added in v0.2.0
FromContext returns the Context that a context.Context holds, or nil.
type ContextOption ¶ added in v0.2.0
type ContextOption = func(*Context)
ContextOption is a context option.
func WithAllocatorOptions ¶ added in v0.18.0
func WithAllocatorOptions(opts ...ExecAllocatorOption) ContextOption
WithAllocatorOptions makes NewContext add opts to the options of the default allocator, after DefaultExecAllocatorOptions and after VisibleWindow. The package github.com/chromedp/chromedp/remote uses it for its own WithKeepOpen.
The option only applies when the parent context has no allocator. It has no effect on an allocator that the caller made, and it has no effect on a context that inherits a browser. For an allocator that you make, add the options to NewExecAllocator instead.
func WithBrowserOption ¶ added in v0.2.0
func WithBrowserOption(opts ...BrowserOption) ContextOption
WithBrowserOption passes browser options to the allocator when it allocates a new browser. As a result, you can use this option only when the context allocates a new browser.
func WithDebugf ¶
func WithDebugf(f func(string, ...any)) ContextOption
WithDebugf is a shortcut for WithBrowserOption(WithBrowserDebugf(f)).
func WithDetachOnCancel ¶ added in v0.19.0
func WithDetachOnCancel() ContextOption
WithDetachOnCancel makes the cancellation of the context detach from its tab and leave the tab open. By default, the cancellation closes the tab that the context created or attached to with WithTargetID, and it disposes of a BrowserContext that WithNewBrowserContext made.
Use it with a remote browser that keeps its tabs when a client leaves, so that a later client can attach to the tab again with WithTargetID. Read the ID of the tab from the Target field of FromContext after the first Run. With this option, the context also keeps a BrowserContext that it owns, because disposing of it closes the tab. It creates that BrowserContext without the setting disposeOnDetach. The program must dispose of it with the command target.DisposeBrowserContext when it no longer needs it.
The option has no effect on the first context of a browser that the exec allocator starts, because the cancellation stops that browser. It is not inherited by a child context.
func WithErrorf ¶
func WithErrorf(f func(string, ...any)) ContextOption
WithErrorf is a shortcut for WithBrowserOption(WithBrowserErrorf(f)).
func WithExistingBrowserContext ¶ added in v0.8.8
func WithExistingBrowserContext(id cdp.BrowserContextID) ContextOption
WithExistingBrowserContext makes a context create a new target in the given BrowserContext.
func WithLogf ¶
func WithLogf(f func(string, ...any)) ContextOption
WithLogf is a shortcut for WithBrowserOption(WithBrowserLogf(f)).
func WithNewBrowserContext ¶ added in v0.8.8
func WithNewBrowserContext(options ...CreateBrowserContextOption) ContextOption
WithNewBrowserContext makes a context create a new BrowserContext and a new target in it. A child context creates its target in this BrowserContext too, unless another option applies. The context disposes the new BrowserContext when the context is done.
func WithNewWindow ¶ added in v0.18.0
func WithNewWindow(newWindow bool) ContextOption
WithNewWindow chooses where a new tab opens. By default, the first Run of a context that creates a tab opens it in a new window, so that each tab is visible and gets animation frames. WithNewWindow(false) opens the tab in the window of the browser, as a real tab. A child context inherits the choice.
Chrome hides every tab of a window except the active one, and a hidden page gets no animation frames. So an action that waits for a frame, such as Poll and the actions that use it, can wait for ever on a tab that is not active. Make a tab active with the command target.ActivateTarget, or with page.BringToFront in the tab, before you run such an action on it.
WithNewWindow has no effect on the first context of a browser, which uses the tab that the browser opens, or on a context that attaches to an existing target with WithTargetID.
func WithTargetID ¶ added in v0.3.0
func WithTargetID(id target.ID) ContextOption
WithTargetID makes a context attach to an existing target, and not create a new one.
It also works for an iframe from another site (a cross-site iframe). Chrome runs such an iframe in its own process, and lists it as a target of the type "iframe" in Targets. FromNode and the DOM tree of the page do not reach it, and the network events of the iframe do not arrive in the context of the page, because chromedp does not attach to the iframe by itself. A context that WithTargetID attaches to the iframe runs actions in the iframe and gets its events. The parent context must have run already, so that it has a browser. For example:
infos, _ := chromedp.Targets(ctx)
for _, info := range infos {
if info.Type == "iframe" && strings.HasPrefix(info.URL, "https://other.example/") {
frameCtx, cancel := chromedp.NewContext(ctx, chromedp.WithTargetID(info.TargetID))
defer cancel()
text, err := chromedp.Run(frameCtx, chromedp.Text(chromedp.CSS("#inner")))
}
}
The other way is to turn off site isolation in the browser. Give the exec allocator Flag("disable-features", "SitePerProcess,IsolateOrigins") and Flag("disable-site-isolation-trials", true). The iframe then stays in the page process, and FromNode and the events of the page reach it. This turns off a security feature of Chrome. See docs/decisions/2026-10-04-keep-site-isolation-on.md.
func WithVisibleWindow ¶ added in v0.17.0
func WithVisibleWindow() ContextOption
WithVisibleWindow makes NewContext build the default allocator with VisibleWindow and without Headless, so that the browser opens a visible window. The window stays open until the context ends. See also KeepOpen and WaitClosed.
The environment variable CHROMEDP_VISIBLEWINDOW has the same effect with no change in the code. Any value other than the empty string, "false" and "0" turns it on.
The option only applies when the parent context has no allocator, because then NewContext builds the allocator. It has no effect on an allocator that the caller made, and it has no effect on a context that inherits a browser. For an allocator that you make, add VisibleWindow to the options of NewExecAllocator instead.
On Linux, the first Run returns ErrNoDisplay when the environment has no display.
Example ¶
This example opens a visible window and waits until the user closes it. The variable CHROMEDP_VISIBLEWINDOW=1 has the same effect as the option.
package main
import (
"context"
"log"
"github.com/chromedp/chromedp"
)
func main() {
ctx, cancel := chromedp.NewContext(context.Background(), chromedp.WithVisibleWindow())
defer cancel()
if err := chromedp.Do(ctx, chromedp.Navigate("https://example.com")); err != nil {
log.Fatal(err)
}
// Block until the user closes the window.
chromedp.WaitClosed(ctx)
}
Output:
type CreateBrowserContextOption ¶ added in v0.8.8
type CreateBrowserContextOption = func(*target.CreateBrowserContextParams)
CreateBrowserContextOption is an option for the creation of a BrowserContext.
type Device ¶ added in v0.4.0
Device is the shared interface for known device types.
See device for a set of ready-made devices and modes.
type Dialer ¶ added in v0.18.0
A Dialer connects to the websocket address of a browser and returns the connection as a Transport. The package github.com/chromedp/chromedp/remote has a Dialer. See WithDialer.
type EmulateViewportOption ¶ added in v0.4.0
type EmulateViewportOption = func(*emulation.SetDeviceMetricsOverrideParams, *emulation.SetTouchEmulationEnabledParams)
EmulateViewportOption is the type for emulate viewport options.
func EmulateOrientation ¶ added in v0.4.0
func EmulateOrientation(orientation emulation.ScreenOrientationType, angle int64) EmulateViewportOption
EmulateOrientation is an emulate viewport option to set the device viewport screen orientation.
func EmulateScale ¶ added in v0.4.0
func EmulateScale(scale float64) EmulateViewportOption
EmulateScale is an emulate viewport option to set the device viewport scaling factor.
type Error ¶
type Error string
Error is a chromedp error.
const ( // ErrNoDialer is the error of an ExecAllocator that needs a websocket and // has no dialer. See [WithDialer]. ErrNoDialer Error = "" /* 143-byte string literal not displayed */ // ErrInvalidDimensions is the invalid dimensions error. ErrInvalidDimensions Error = "invalid dimensions" // ErrNoResults is the no results error. ErrNoResults Error = "no results" // ErrHasResults is the has results error. ErrHasResults Error = "has results" // ErrNotVisible is the not visible error. ErrNotVisible Error = "not visible" // ErrVisible is the visible error. ErrVisible Error = "visible" // ErrDisabled is the disabled error. ErrDisabled Error = "disabled" // ErrNotSelected is the not selected error. ErrNotSelected Error = "not selected" // ErrInvalidBoxModel is the invalid box model error. ErrInvalidBoxModel Error = "invalid box model" // ErrChannelClosed is the channel closed error. ErrChannelClosed Error = "channel closed" // ErrInvalidTarget is the invalid target error. ErrInvalidTarget Error = "invalid target" // ErrPageLoad is the error that every [LoadError] wraps. ErrPageLoad Error = "page load error" // ErrNoDisplay is the error when a visible window is requested on Linux // and the environment has no display. ErrNoDisplay Error = "" /* 190-byte string literal not displayed */ // ErrInvalidContext is the invalid context error. ErrInvalidContext Error = "invalid context" // ErrPollingTimeout is the error when the timeout ends before the pageFunction returns a truthy value. ErrPollingTimeout Error = "waiting for function failed: timeout" // ErrJSUndefined is the error that the type of RemoteObject is "undefined". ErrJSUndefined Error = "encountered an undefined value" // ErrJSNull is the error that the value of RemoteObject is null. ErrJSNull Error = "encountered a null value" )
Error types.
const ErrDragOutsideViewport Error = "the nodes of the drag are not in the viewport at the same time"
ErrDragOutsideViewport is the error of DragAndDrop when the two nodes do not fit in the viewport at the same time. The action does not scroll while it drags, so a drag between two such nodes does nothing.
type EvaluateOption ¶
type EvaluateOption = func(*runtime.EvaluateParams)
EvaluateOption is the type for JavaScript evaluation options.
func EvalObjectGroup ¶
func EvalObjectGroup(objectGroup string) EvaluateOption
EvalObjectGroup is an evaluate option to set the object group.
type ExceptionError ¶ added in v0.17.0
type ExceptionError struct {
*runtime.ExceptionDetails
}
ExceptionError is the error for a JavaScript exception. It wraps the protocol details of the exception.
func (*ExceptionError) Error ¶ added in v0.17.0
func (e *ExceptionError) Error() string
Error satisfies the error interface.
type ExecAllocator ¶ added in v0.2.0
type ExecAllocator struct {
// contains filtered or unexported fields
}
ExecAllocator is an Allocator which starts new browser processes on the host machine.
Example ¶
package main
import (
"context"
"fmt"
"log"
"os"
"time"
"github.com/chromedp/chromedp"
)
func main() {
dir, err := os.MkdirTemp("", "chromedp-example")
if err != nil {
log.Fatal(err)
}
defer func() {
// The child processes of Chrome can still write in the directory for
// a short time after the browser stops. Then RemoveAll fails with
// "directory not empty", so try again.
for range 50 {
if err := os.RemoveAll(dir); err == nil {
return
}
time.Sleep(100 * time.Millisecond)
}
}()
opts := append(chromedp.DefaultExecAllocatorOptions[:],
chromedp.DisableGPU,
chromedp.UserDataDir(dir),
)
allocCtx, cancel := chromedp.NewExecAllocator(context.Background(), opts...)
defer cancel()
// also set up a custom logger
taskCtx, cancel := chromedp.NewContext(allocCtx, chromedp.WithLogf(log.Printf))
defer cancel()
sum, err := chromedp.Run(taskCtx, chromedp.Evaluate[int](`1 + 2`))
if err != nil {
log.Fatal(err)
}
fmt.Println(sum)
}
Output: 3
func (*ExecAllocator) Allocate ¶ added in v0.2.0
func (a *ExecAllocator) Allocate(ctx context.Context, opts ...BrowserOption) (*Browser, error)
Allocate satisfies the Allocator interface. It returns ErrNoDialer when the allocator needs a websocket and has no dialer.
func (*ExecAllocator) Wait ¶ added in v0.2.0
func (a *ExecAllocator) Wait()
Wait satisfies the Allocator interface.
type ExecAllocatorOption ¶ added in v0.2.0
type ExecAllocatorOption = func(*ExecAllocator)
ExecAllocatorOption is an exec allocator option.
func CombinedOutput ¶ added in v0.4.0
func CombinedOutput(w io.Writer) ExecAllocatorOption
CombinedOutput sets the io.Writer that receives the stdout and stderr of the browser.
func Env ¶ added in v0.4.1
func Env(vars ...string) ExecAllocatorOption
Env sets environment variables, in the form NAME=value, for the new Chrome process. They add to the environment of the Go process, which os.Environ returns. To start the browser with only these variables, add NoInheritEnv.
func ExecPath ¶ added in v0.2.0
func ExecPath(path string) ExecAllocatorOption
ExecPath returns an ExecAllocatorOption that uses the given path to run browser processes. The path can be an absolute path to a binary, or the name of a program that exec.LookPath finds.
func Flag ¶ added in v0.2.0
func Flag(name string, value any) ExecAllocatorOption
Flag is a generic command line option that passes a flag to Chrome. If the value is a string, Flag passes --name=value. If it is a boolean, Flag passes --name when the value is true.
The flags go to Chrome in the order of the options. Set a flag again, and it keeps its first place with the new value. This order matters for the flags --flag-switches-begin and --flag-switches-end, which must surround the switches that Chrome takes as the switches of chrome://flags. When you add to a copy of DefaultExecAllocatorOptions, the default flags come first.
func ModifyCmdFunc ¶ added in v0.7.3
func ModifyCmdFunc(f func(cmd *exec.Cmd)) ExecAllocatorOption
ModifyCmdFunc runs a func on the exec.Cmd of the browser. It replaces the default func, which sends SIGKILL to any open browsers when the Go program exits.
func ProxyServer ¶ added in v0.2.0
func ProxyServer(proxy string) ExecAllocatorOption
ProxyServer is the command line option to set the outbound proxy server.
func UserAgent ¶ added in v0.2.0
func UserAgent(userAgent string) ExecAllocatorOption
UserAgent is the command line option to set the default User-Agent header.
func UserDataDir ¶ added in v0.2.0
func UserDataDir(dir string) ExecAllocatorOption
UserDataDir is the command line option to set the user data directory. Use it to choose the profile directory of Chrome. Without it, ExecAllocator creates a default path in the /tmp directory.
func WSURLReadTimeout ¶ added in v0.8.4
func WSURLReadTimeout(t time.Duration) ExecAllocatorOption
WSURLReadTimeout sets how long ExecAllocator waits to read the WebSocket URL. The default is 20 seconds. It only applies to the websocket mode, see WithDialer.
func WindowSize ¶ added in v0.2.0
func WindowSize(width, height int) ExecAllocatorOption
WindowSize is the command line option to set the initial window size.
func WithDialer ¶ added in v0.18.0
func WithDialer(d Dialer) ExecAllocatorOption
WithDialer is an ExecAllocatorOption that makes the allocator connect to the browser with a websocket, as chromedp did before the pipe became the default. The allocator starts the browser with a debugging port, reads the websocket address, and calls d to connect to it.
The core module has no websocket code, so it needs a dialer. The function WebSocket of the package github.com/chromedp/chromedp/remote makes the ExecAllocatorOption that sets one. Use a dialer when the browser must open a debugging port, for example to let a second program connect to it. The Flag options "remote-debugging-port" and "remote-debugging-address" also need a dialer.
type Frame ¶ added in v0.17.0
type Frame struct {
*cdp.Frame
// State is the state of the frame.
State FrameState
// Root is the document root of the frame.
Root *Node
// Nodes holds the nodes of the frame by node id.
Nodes map[cdp.NodeID]*Node
sync.RWMutex
}
Frame is a frame of a page. It embeds the protocol frame and adds the node tree of the frame and the state that chromedp keeps up to date from the browser events.
Hold the lock of a Frame before you read a field that chromedp updates.
type FrameState ¶ added in v0.17.0
type FrameState uint16
FrameState is the state of a Frame.
const ( FrameDOMContentEventFired FrameState = 1 << (15 - iota) FrameLoadEventFired FrameAttached FrameLoading )
FrameState enum values.
func (FrameState) String ¶ added in v0.17.0
func (fs FrameState) String() string
String satisfies stringer interface.
type ID ¶ added in v0.17.0
type ID string
ID is a selector for the element with this id. A leading "#" is optional. It uses DOM.querySelector.
type JSPath ¶ added in v0.17.0
type JSPath string
JSPath is a selector for the elements that a JavaScript expression gives. It uses Runtime.evaluate. Use it only with trusted values, because chromedp passes the expression to the browser without a check.
Example ¶
package main
import (
"context"
"fmt"
"io"
"log"
"net/http"
"net/http/httptest"
"strings"
"github.com/chromedp/cdproto/dom"
"github.com/chromedp/chromedp"
)
func writeHTML(content string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html")
io.WriteString(w, strings.TrimSpace(content))
})
}
func main() {
ctx, cancel := chromedp.NewContext(context.Background())
defer cancel()
ts := httptest.NewServer(writeHTML(`
<body>
<div id="content">cool content</div>
</body>
`))
defer ts.Close()
if err := chromedp.Do(ctx, chromedp.Navigate(ts.URL)); err != nil {
log.Fatal(err)
}
ids, err := chromedp.Run(ctx, chromedp.QueryNodeIDs(chromedp.JSPath(`document`)))
if err != nil {
log.Fatal(err)
}
res, err := chromedp.Call(ctx, dom.GetOuterHTML, dom.GetOuterHTMLParams{NodeID: ids[0]})
if err != nil {
log.Fatal(err)
}
fmt.Println("Outer HTML:")
fmt.Println(res.OuterHTML)
}
Output: Outer HTML: <html><head></head><body> <div id="content">cool content</div> </body></html>
type KeyOption ¶
type KeyOption = func(*input.DispatchKeyEventParams)
KeyOption is a key action option.
func KeyModifiers ¶
KeyModifiers is a key action option to add modifiers to the key press.
type LoadError ¶ added in v0.18.0
type LoadError struct {
// ErrorText is the error text of the browser, such as
// "net::ERR_NAME_NOT_RESOLVED". Chromium lists these texts in
// net/base/net_error_list.h.
ErrorText string
}
LoadError is the error for a page that did not load. Navigate and RunResponse return it when the browser reports an error for the request of the page, for example when the host name does not exist. Use errors.As to read the text of the browser, or errors.Is with ErrPageLoad to test for any load error.
type MouseOption ¶
type MouseOption = func(*input.DispatchMouseEventParams)
MouseOption is a mouse action option.
func Button ¶
func Button(btn string) MouseOption
Button is a mouse action option to set the button to click from a string.
func ButtonModifiers ¶
func ButtonModifiers(modifiers ...Modifier) MouseOption
ButtonModifiers is a mouse action option to add input modifiers for a button click.
func ButtonType ¶
func ButtonType(button input.MouseButton) MouseOption
ButtonType is a mouse action option to set the button to click.
func ClickCount ¶
func ClickCount(n int) MouseOption
ClickCount is a mouse action option to set the click count.
type Node ¶ added in v0.17.0
type Node struct {
*cdp.Node
// Parent is the parent node.
Parent *Node
// Children shadows the Children field of the protocol node.
Children []*Node
// ContentDocument shadows the ContentDocument field of the protocol node.
ContentDocument *Node
// ShadowRoots shadows the ShadowRoots field of the protocol node.
ShadowRoots []*Node
// TemplateContent shadows the TemplateContent field of the protocol node.
TemplateContent *Node
// PseudoElements shadows the PseudoElements field of the protocol node.
PseudoElements []*Node
// Invalidated is closed when the node is no longer valid.
Invalidated chan struct{}
// State is the state of the node.
State NodeState
sync.RWMutex
}
Node is a DOM node in the node tree of a frame. It embeds the protocol node and adds the tree links and the state that chromedp keeps up to date from the browser events.
Hold the lock of a Node before you read a field of the tree.
func (*Node) Attribute ¶ added in v0.17.0
Attribute returns the named attribute for the node and if it exists.
func (*Node) AttributeValue ¶ added in v0.17.0
AttributeValue returns the named attribute for the node.
func (*Node) Dump ¶ added in v0.17.0
Dump builds a printable string representation of the node and its children.
func (*Node) FullXPath ¶ added in v0.17.0
FullXPath returns the full XPath for the node. It stops only at the top most document root.
func (*Node) FullXPathByID ¶ added in v0.17.0
FullXPathByID returns the full XPath for the node. It stops at the top most document root or at the closest parent node with an id attribute.
func (*Node) PartialXPath ¶ added in v0.17.0
PartialXPath returns the partial XPath for the node. It stops at the nearest parent document node.
func (*Node) PartialXPathByID ¶ added in v0.17.0
PartialXPathByID returns the partial XPath for the node. It stops at the first parent with an id attribute or at the nearest parent document node.
type NodeState ¶ added in v0.17.0
type NodeState uint8
NodeState is the state of a DOM node.
NodeState enum values.
type NodeType ¶ added in v0.17.0
type NodeType int64
NodeType is the type of a DOM node. It is the value of the NodeType field of the protocol node.
type OldAction ¶ added in v0.17.0
type OldAction interface {
// Do runs the action. The context holds the chromedp context.
Do(context.Context) error
}
OldAction is the interface of an action of the previous version of chromedp. The previous version named it Action.
type PDFOption ¶ added in v0.19.0
type PDFOption = func(*page.PrintToPDFParams)
PDFOption is an option of PrintToPDF. It changes the parameters of the protocol command page.PrintToPDF.
func PDFFooterTemplate ¶ added in v0.19.0
PDFFooterTemplate is like PDFHeaderTemplate for the footer.
func PDFHeaderTemplate ¶ added in v0.19.0
PDFHeaderTemplate is an option of PrintToPDF that sets the HTML of the header, and turns on the header and the footer. The template can use these classes, and the browser puts the value in an element that has one: date, title, url, pageNumber and totalPages. The font size of the browser for a header is 0, so the template must set one. The header and the footer use the page margins, so a margin that is too small hides them.
When you give only a header, the browser prints its own footer. Give PDFFooterTemplate with `<span></span>` to print no footer.
func PDFLandscape ¶ added in v0.19.0
func PDFLandscape() PDFOption
PDFLandscape is an option of PrintToPDF that prints in landscape. The width and the height of the paper swap.
func PDFMargin ¶ added in v0.19.0
PDFMargin is an option of PrintToPDF that sets the four margins to the same length in inches. The default is 1 cm, which is about 0.4 inches. A margin of 0 is valid.
func PDFMargins ¶ added in v0.19.0
PDFMargins is an option of PrintToPDF that sets the margins in inches. The order is the same as in CSS: top, right, bottom and left.
func PDFOutlineAndTagged ¶ added in v0.19.0
func PDFOutlineAndTagged() PDFOption
PDFOutlineAndTagged is an option of PrintToPDF that adds the outline of the document, which is a table of contents that a PDF viewer shows for the headings, and that makes a tagged PDF, which holds the structure of the document for a screen reader. Chrome 154 and later make a tagged PDF by default, so with them the option adds the outline.
func PDFPageRanges ¶ added in v0.19.0
PDFPageRanges is an option of PrintToPDF that selects the pages to print, for example "1-3, 5". The numbers start at 1. The default is all pages.
func PDFPaper ¶ added in v0.19.0
PDFPaper is an option of PrintToPDF that sets the size of the paper. Give one of the sizes of the package, such as PaperA4, or a PaperSize of your own. The default is PaperLetter. A zero width or height gives the default for that side, so PDFPaper(PaperSize{}) changes nothing. The size is for portrait, and PDFLandscape swaps it.
func PDFPreferCSSPageSize ¶ added in v0.19.0
func PDFPreferCSSPageSize() PDFOption
PDFPreferCSSPageSize is an option of PrintToPDF that uses the page size of the CSS rule @page, when the page has one. Otherwise the browser scales the content to fit the paper.
func PDFPrintBackground ¶ added in v0.19.0
func PDFPrintBackground() PDFOption
PDFPrintBackground is an option of PrintToPDF that prints the background colors and images. By default, the browser leaves them out.
func PDFScale ¶ added in v0.19.0
PDFScale is an option of PrintToPDF that sets the scale of the page. The default is 1, and 0 gives the default, so PDFScale(0) changes nothing. The browser accepts 0.1 to 2.
func PDFStream ¶ added in v0.19.0
func PDFStream() PDFOption
PDFStream is an option of PrintToPDF that makes the browser send the file as a stream that the action reads in pieces, and not in one message. Use it for a large file. The result is the same.
type PaperSize ¶ added in v0.19.0
type PaperSize struct {
Width, Height float64
}
PaperSize is the size of a sheet of paper in inches. Use it with PDFPaper. A field that is 0 gives the default of the browser for that field, so PaperSize{Width: 5} is 5 inches wide and 11 inches high, and the zero value is Letter paper.
type PipeConn ¶ added in v0.17.0
type PipeConn struct {
// contains filtered or unexported fields
}
PipeConn implements Transport with the two pipes of a browser that was started with the --remote-debugging-pipe flag.
On Unix, the browser reads the commands from its file descriptor 3 and writes the responses and the events to its file descriptor 4. On Windows, it uses two handles. Each JSON message ends with one zero byte, in both directions.
func NewPipeConn ¶ added in v0.17.0
func NewPipeConn(r io.ReadCloser, w io.WriteCloser, opts ...PipeOption) *PipeConn
NewPipeConn returns a Transport that reads the messages of the browser from r and writes the messages for the browser to w. Close closes both r and w.
func (*PipeConn) Close ¶ added in v0.17.0
Close satisfies the io.Closer interface. It closes both ends of the pipe, which makes the browser exit.
func (*PipeConn) Read ¶ added in v0.17.0
Read reads the next message. It returns io.EOF when the browser closes its end of the pipe.
type PipeOption ¶ added in v0.17.0
type PipeOption = func(*PipeConn)
PipeOption is an option of NewPipeConn.
func WithPipeDebugf ¶ added in v0.17.0
func WithPipeDebugf(f func(string, ...any)) PipeOption
WithPipeDebugf is a pipe option to set a protocol logger.
type PollOption ¶ added in v0.6.11
type PollOption = func(task *pollTask)
PollOption is a poll task option.
func WithPollingArgs ¶ added in v0.6.11
func WithPollingArgs(args ...any) PollOption
WithPollingArgs provides extra arguments to pass to the predicate.
func WithPollingInFrame ¶ added in v0.6.11
func WithPollingInFrame(frame *Node) PollOption
WithPollingInFrame sets the frame in which to evaluate the predicate. Without it, the action evaluates the predicate in the root page of the current tab.
func WithPollingInterval ¶ added in v0.6.11
func WithPollingInterval(interval time.Duration) PollOption
WithPollingInterval polls the predicate at the given interval.
func WithPollingMutation ¶ added in v0.6.11
func WithPollingMutation() PollOption
WithPollingMutation polls the predicate on every DOM mutation.
func WithPollingTimeout ¶ added in v0.6.11
func WithPollingTimeout(timeout time.Duration) PollOption
WithPollingTimeout sets the maximum time to wait until the predicate returns a truthy value. It defaults to 30 seconds. Pass 0 to disable the timeout.
type PopulateOption ¶ added in v0.9.5
PopulateOption is an element populate action option.
func PopulateWait ¶ added in v0.9.5
func PopulateWait(wait time.Duration) PopulateOption
PopulateWait is a populate option that sets a wait interval after the request for child nodes.
type QueryOption ¶
type QueryOption = func(*Selector)
QueryOption is an element query action option.
func After ¶
After is an element query option that sets a func to run when the browser has returned the matched nodes and the node condition is true.
func AtLeast ¶
func AtLeast(n int) QueryOption
AtLeast is an element query option that sets the minimum number of elements that the query must return.
By default, a query needs 1.
func ByFunc ¶
ByFunc is an element query action option that sets the func that selects elements. It replaces the lookup that the type of the selector chooses. The selector is then only a label in error messages, so pass "" or any string.
func FromNode ¶ added in v0.5.4
func FromNode(node *Node) QueryOption
FromNode is an element query action option that sets the node where the query runs. That is, the query looks only at the element sub-tree of the node. By default, or when you pass nil, the query uses the root element of the document.
Note: Search and JSPath selectors do not support FromNode now. The option is mainly useful for CSS selectors.
FromNode does not reach into an iframe from another site. Chrome runs such an iframe in its own process, as a separate target, and the node of the iframe element has no ContentDocument. A query from that node finds nothing and waits until its context ends. See WithTargetID for how to attach to the iframe.
Example ¶
package main
import (
"context"
"fmt"
"io"
"log"
"net/http"
"net/http/httptest"
"strings"
"github.com/chromedp/chromedp"
)
func writeHTML(content string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html")
io.WriteString(w, strings.TrimSpace(content))
})
}
func main() {
ctx, cancel := chromedp.NewContext(context.Background())
defer cancel()
ts := httptest.NewServer(writeHTML(`
<body>
<p class="content">outer content</p>
<div id="section"><p class="content">inner content</p></div>
</body>
`))
defer ts.Close()
if err := chromedp.Do(ctx, chromedp.Navigate(ts.URL)); err != nil {
log.Fatal(err)
}
nodes, err := chromedp.Run(ctx, chromedp.Nodes(chromedp.CSS("#section")))
if err != nil {
log.Fatal(err)
}
sectionNode := nodes[0]
// Queries run from the document root by default, so Text picks the
// first node that it finds.
queryRoot, err := chromedp.Run(ctx, chromedp.Text(chromedp.CSS(".content")))
if err != nil {
log.Fatal(err)
}
// We can choose a different node to run the query from. In this case,
// we can narrow the search to #section.
queryFromNode, err := chromedp.Run(ctx, chromedp.Text(chromedp.CSS(".content"), chromedp.FromNode(sectionNode)))
if err != nil {
log.Fatal(err)
}
// A CSS selector like "#section > .content" achieves the same here. But
// FromNode accepts a node from an entirely separate step, so it allows
// custom logic.
queryNestedSelector, err := chromedp.Run(ctx, chromedp.Text(chromedp.CSS("#section > .content")))
if err != nil {
log.Fatal(err)
}
fmt.Println("Simple query from the document root:", queryRoot)
fmt.Println("Simple query from the section node:", queryFromNode)
fmt.Println("Nested query from the document root:", queryNestedSelector)
}
Output: Simple query from the document root: outer content Simple query from the section node: inner content Nested query from the document root: inner content
func Populate ¶ added in v0.9.5
func Populate(depth int64, pierce bool, opts ...PopulateOption) QueryOption
Populate is an element query option that retrieves the queried nodes for later use. Use a depth of -1 to retrieve all child nodes. When pierce is true, it also pierces child containers (for example iframes).
NOTE: this can use a lot of resources. Use it only when necessary.
func RetryInterval ¶ added in v0.8.6
func RetryInterval(interval time.Duration) QueryOption
RetryInterval is an element query action option that sets how often the query retries when it fails to select the target elements.
The default is 5ms.
type Search ¶ added in v0.17.0
type Search string
Search is a selector that the browser resolves with DOM.performSearch. It matches nodes by plain text, CSS selector or XPath query. It is the lookup of a plain string.
type Selectable ¶ added in v0.17.0
Selectable is what an element query accepts as the selector. The type of the selector chooses the lookup. A plain string is a Search. A named string type that this package does not define also counts as a Search.
The set of selector types is closed. A type that you define cannot add a new lookup. For a custom lookup, use the option ByFunc. It replaces the lookup of the selector with a func that receives the Target of the tab and the Node where the query starts, and returns the node IDs of the elements. The target is a session for cdp.Call. The start node is the root of the document, or the node of FromNode. The selector is then only a label in error messages, so pass "" or any string. For example, this lookup finds the elements with a data-testid attribute:
func byTestID(id string) chromedp.QueryOption {
return chromedp.ByFunc(func(ctx context.Context, t *chromedp.Target, n *chromedp.Node) ([]cdp.NodeID, error) {
res, err := cdp.Call(ctx, t, dom.QuerySelectorAll, dom.QuerySelectorAllParams{
NodeID: n.NodeID,
Selector: fmt.Sprintf("[data-testid=%q]", id),
})
return res.NodeIDs, err
})
}
err := chromedp.Do(ctx, chromedp.Click("", byTestID("submit")))
Example ¶
package main
import (
"context"
"fmt"
"io"
"log"
"net/http"
"net/http/httptest"
"strings"
"github.com/chromedp/chromedp"
)
func writeHTML(content string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html")
io.WriteString(w, strings.TrimSpace(content))
})
}
func main() {
ctx, cancel := chromedp.NewContext(context.Background())
defer cancel()
ts := httptest.NewServer(writeHTML(`
<body>
<p id="a" class="item">first</p>
<p id="b" class="item">second</p>
</body>
`))
defer ts.Close()
if err := chromedp.Do(ctx, chromedp.Navigate(ts.URL)); err != nil {
log.Fatal(err)
}
// The type of the selector chooses the lookup. A plain string is a
// Search, which takes a CSS selector, an XPath query or text.
plain, err := chromedp.Run(ctx, chromedp.Text("#a"))
if err != nil {
log.Fatal(err)
}
// CSS selects the first match of a CSS selector.
css, err := chromedp.Run(ctx, chromedp.Text(chromedp.CSS(".item")))
if err != nil {
log.Fatal(err)
}
// CSSAll selects every match of a CSS selector.
all, err := chromedp.Run(ctx, chromedp.Nodes(chromedp.CSSAll(".item")))
if err != nil {
log.Fatal(err)
}
// ID selects the element with an id.
id, err := chromedp.Run(ctx, chromedp.Text(chromedp.ID("b")))
if err != nil {
log.Fatal(err)
}
// NodeIDs selects the nodes with these ids.
ids, err := chromedp.Run(ctx, chromedp.QueryNodeIDs(chromedp.CSSAll(".item")))
if err != nil {
log.Fatal(err)
}
byNodeIDs, err := chromedp.Run(ctx, chromedp.Text(chromedp.NodeIDs(ids[1:])))
if err != nil {
log.Fatal(err)
}
fmt.Println(plain, css, len(all), id, byNodeIDs)
// A type outside of the Selectable set does not compile. Both calls
// below are errors at build time, not at run time:
//
// chromedp.Click(42)
// chromedp.Click(node)
}
Output: first first 2 second second
type Selector ¶
type Selector struct {
// contains filtered or unexported fields
}
Selector holds the data of an element selection query.
See Query for how to build an element selector and its options.
type Target ¶ added in v0.2.0
type Target struct {
SessionID target.SessionID
TargetID target.ID
// contains filtered or unexported fields
}
Target manages a Chrome DevTools Protocol target.
func (*Target) Call ¶ added in v0.17.0
Call sends the command to the target, waits for the response, and decodes the result into res. It satisfies cdp.Session.
Call returns a browser error as a *cdproto.Error. It returns an error when the connection to the browser is lost, also when ctx never ends. The error wraps the reason of the loss and context.Canceled.
type Transport ¶ added in v0.2.0
type Transport interface {
Read(context.Context, *cdproto.Message) error
Write(context.Context, *cdproto.Message) error
io.Closer
}
Transport is the common interface to send and receive the protocol messages of a browser. PipeConn implements it, and so does the websocket connection of the package github.com/chromedp/chromedp/remote. Browser reads and writes its messages through it, and NewBrowserTransport accepts any Transport.
A Transport can also have the method SetDebugf(func(string, ...any)). NewBrowserTransport then calls it with the protocol logger of the browser.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package device contains device emulation definitions for use with chromedp's Emulate action.
|
Package device contains device emulation definitions for use with chromedp's Emulate action. |
|
internal
|
|
|
chromedptest
Package chromedptest holds the helpers that the tests of the chromedp packages share.
|
Package chromedptest holds the helpers that the tests of the chromedp packages share. |
|
testenv
Package testenv reads the environment variables that change the tests of chromedp.
|
Package testenv reads the environment variables that change the tests of chromedp. |
|
Package kb provides keyboard mappings for Chrome DOM Keys for use with input events.
|
Package kb provides keyboard mappings for Chrome DOM Keys for use with input events. |
|
Package remote connects chromedp to a browser with a websocket.
|
Package remote connects chromedp to a browser with a websocket. |
|
internal/websocket
Package websocket is a WebSocket client as RFC 6455 defines it.
|
Package websocket is a WebSocket client as RFC 6455 defines it. |
|
internal/wstest
Package wstest is a minimal WebSocket server for tests.
|
Package wstest is a minimal WebSocket server for tests. |