cdp

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 15, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package cdp is a minimal Chrome DevTools Protocol client.

It speaks raw JSON over a single WebSocket (no type generation, no event registry) — just enough to drive a Scrapfly-hosted Chromium through a small action vocabulary (open / snapshot / click / type / scroll / screenshot / eval). For heavier workloads, prefer chromedp + cdproto.

The client is goroutine-safe for Call. A single reader pump dispatches responses back to the caller via id-keyed channels; events are buffered and delivered through WaitEvent.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AXNode

type AXNode struct {
	Ref           string   `json:"ref"`        // e1, e2, ...
	AXNodeID      string   `json:"ax_node_id"` // raw CDP Accessibility.AXNodeId
	Role          string   `json:"role,omitempty"`
	Name          string   `json:"name,omitempty"`
	Value         string   `json:"value,omitempty"`
	Description   string   `json:"description,omitempty"`
	BackendNodeID int64    `json:"backend_node_id,omitempty"`
	ChildRefs     []string `json:"children,omitempty"`
}

AXNode is a compact view over a single Accessibility node. Fields mirror the CDP `AXNode` shape but only what the model needs to reason.

AXNodeID is the raw CDP accessibility-tree node id. Pass it directly as {type:"axNodeId", query: ax_node_id} to Antibot commands to skip DOM resolution.

type AXVal

type AXVal struct {
	Type  string          `json:"type"`
	Value json.RawMessage `json:"value,omitempty"`
}

AXVal mirrors CDP's AXValue — a typed wrapper around a string/number/bool.

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client is a CDP session over a single WebSocket.

func Dial

func Dial(ctx context.Context, wsURL string) (*Client, error)

Dial connects to a CDP WebSocket URL (typically wss://browser.scrapfly.io/ ?api_key=...). Pass a derived ctx for dial cancellation.

func (*Client) Call

func (c *Client) Call(ctx context.Context, method string, params any, sessionID string) (json.RawMessage, error)

Call sends method+params and waits for the matching response.

func (*Client) Close

func (c *Client) Close() error

Close closes the underlying WebSocket. Any pending Call returns the close error.

func (*Client) WaitEvent

func (c *Client) WaitEvent(ctx context.Context, method string, match func(json.RawMessage) bool) (json.RawMessage, error)

WaitEvent blocks until an event with the given method (and optional predicate match) is observed. Buffered events are drained first.

type Message

type Message struct {
	ID        int             `json:"id,omitempty"`
	Method    string          `json:"method,omitempty"`
	Params    json.RawMessage `json:"params,omitempty"`
	Result    json.RawMessage `json:"result,omitempty"`
	Error     *RPCError       `json:"error,omitempty"`
	SessionID string          `json:"sessionId,omitempty"`
}

Message is the on-wire envelope for both calls and events. Responses carry ID + Result (or Error). Events carry Method + Params (no ID).

type RPCError

type RPCError struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
	Data    string `json:"data,omitempty"`
}

RPCError mirrors the CDP error envelope.

func (*RPCError) Error

func (e *RPCError) Error() string

type Selector

type Selector struct {
	Type  string `json:"type"` // "css" | "xpath" | "axNodeId" | "coord"
	Query string `json:"query"`
}

Selector is Antibot's element locator shape: {type, query}.

func CSSSelector

func CSSSelector(q string) Selector

CSSSelector returns a Selector for a CSS query.

func XPathSelector

func XPathSelector(q string) Selector

XPathSelector returns a Selector for an XPath query.

type Session

type Session struct {
	Client    *Client
	TargetID  string
	SessionID string

	// RefTable maps model-facing refs ("e1", "e2", ...) to the backend DOM node
	// IDs captured by the most recent Snapshot. Refs are stable only until the
	// next Snapshot call.
	RefTable map[string]int64
}

Session is a CDP page-level context: browser connection + attached target (tab) session id + a rolling AXTree ref table for action references.

func Attach

func Attach(ctx context.Context, c *Client) (*Session, error)

Attach opens a fresh page target and attaches a flat session to it, ready for Page/DOM/Input/Accessibility calls. The caller must hold onto the returned Session for subsequent actions.

func (*Session) BackendIDForRef

func (s *Session) BackendIDForRef(ref string) (int64, bool)

BackendIDForRef looks up the CDP backendNodeId previously captured for a snapshot ref. Returns (0, false) if the ref is unknown.

func (*Session) Call

func (s *Session) Call(ctx context.Context, method string, params any) (json.RawMessage, error)

Call proxies a CDP call scoped to this session.

func (*Session) Click

func (s *Session) Click(ctx context.Context, locator string) (map[string]any, error)

Click performs a left-button press+release at the locator's center. Locator is either an AXTree ref ("e3") or a CSS selector (e.g. "button[type=submit]").

CSS selectors go through Antibot.clickOn for human-like timing; refs use the raw Input.dispatchMouseEvent path (no Antibot axNodeId translation yet since our RefTable keys are DOM backend ids, not AX ids).

func (*Session) ClickAndSlide

func (s *Session) ClickAndSlide(ctx context.Context, source Selector, opts SlideOptions) (map[string]any, error)

func (*Session) ClickAntibot

func (s *Session) ClickAntibot(ctx context.Context, sel Selector, button string, clickCount int) (map[string]any, error)

ClickAntibot performs a human-like click on the matched element.

func (*Session) Detach

func (s *Session) Detach(ctx context.Context) error

Detach closes the tab. The browser session itself stays alive (stop it with `scrapfly browser close <session-id>`).

func (*Session) Eval

func (s *Session) Eval(ctx context.Context, js string) (any, error)

Eval runs Runtime.evaluate and returns the result (string representation).

func (*Session) Fill

func (s *Session) Fill(ctx context.Context, locator, text string) (map[string]any, error)

Fill focuses the locator and inserts text. Locator is an AXTree ref ("e3") or a CSS selector.

CSS selectors use Antibot.fill (click + clear + char-by-char typing with human WPM). Refs fall back to Input.insertText.

func (*Session) FillAntibot

func (s *Session) FillAntibot(ctx context.Context, sel Selector, text string, clear bool, wpm float64) (map[string]any, error)

FillAntibot types into the matched element with human-like WPM timing via the Scrapfly Antibot domain. Clears first when clear=true.

func (*Session) Open

func (s *Session) Open(ctx context.Context, url string) (map[string]any, error)

Open navigates the attached page to url and waits for the load event.

func (*Session) RenderedContent

func (s *Session) RenderedContent(ctx context.Context, renderIframes bool) (content, contentType string, err error)

RenderedContent returns the fully rendered page content — HTML with iframes inlined for text types; base64 bytes for binaries. Default is renderIframe=true.

func (*Session) Screenshot

func (s *Session) Screenshot(ctx context.Context, fullPage bool) ([]byte, error)

Screenshot returns the PNG bytes of the viewport.

func (*Session) Scroll

func (s *Session) Scroll(ctx context.Context, direction string, amount float64, locator string) (map[string]any, error)

Scroll dispatches a wheel event; direction "down"/"up"/"left"/"right", amount in CSS pixels. If ref is non-empty, scrolls with that element as anchor; otherwise uses the viewport center.

func (*Session) Snapshot

func (s *Session) Snapshot(ctx context.Context) ([]AXNode, error)

Snapshot captures the current page's full accessibility tree, builds a compact ref table (e1, e2, ...), and returns the flat list in document order. The Session's RefTable is replaced.

func (*Session) WaitForElement

func (s *Session) WaitForElement(ctx context.Context, sel Selector, timeoutMs int, visible bool) (map[string]any, error)

WaitForElement polls natively (no JS) until the selector resolves. timeout defaults to 10s server-side. visible adds display/opacity check.

type SlideOptions

type SlideOptions struct {
	Target         *Selector
	Distance       float64 // px, used if Target is nil
	VerticalOffset float64
	Button         string
	Overshoot      bool
}

ClickAndSlide runs the "slider captcha" primitive: press-and-hold on the source element, slide to target, release. One of {Distance, Target} must be set.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL