crawler

package
v0.16.0 Latest Latest
Warning

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

Go to latest
Published: May 30, 2026 License: MIT Imports: 25 Imported by: 0

Documentation

Overview

Package crawler provides a reusable crawling service that fetches web pages, applies configurable rules, and emits normalized results. It supports proxy rotation, retry with backoff, rate limiting, platform-specific hooks, and extensible response handling through the ResponseHandler interface.

The package is also the public boundary for crawling-related HTTP, browser, and provider-aware proxy transport helpers used by client projects.

Index

Constants

View Source
const (
	// BrowserModeDirect uses Chrome's native proxy handling or a direct network
	// path.
	BrowserModeDirect = browsertransport.BrowserModeDirect
	// BrowserModeHTTPFetchAuth strips inline auth from an HTTP proxy URL and
	// supplies credentials through the Fetch domain.
	BrowserModeHTTPFetchAuth = browsertransport.BrowserModeHTTPFetchAuth
	// BrowserModeSOCKSForwarder bridges an authenticated SOCKS proxy through a
	// local unauthenticated forwarder Chrome can consume.
	BrowserModeSOCKSForwarder = browsertransport.BrowserModeSOCKSForwarder
)
View Source
const DefaultBrowserStealthScript = browsertransport.DefaultStealthScript

DefaultBrowserStealthScript is injected into rendered pages unless a caller supplies a browser-specific script.

View Source
const DefaultHTTPTimeout = httptransport.DefaultTimeout

DefaultHTTPTimeout is used when an HTTP client timeout is not explicitly provided.

Variables

View Source
var ErrProxyLeaseCandidatesExhausted = errors.New("crawler: proxy lease candidates exhausted")
View Source
var ErrProxyLeaseUnavailable = errors.New("crawler: proxy lease unavailable")

Functions

func AttachProxySelection added in v0.14.0

func AttachProxySelection(request *http.Request, selection ProxySelection)

AttachProxySelection records a selection on a request context.

func DefaultBrowserUserAgent added in v0.14.0

func DefaultBrowserUserAgent(execPath string) string

DefaultBrowserUserAgent returns a realistic Chrome User-Agent string whose major version matches the installed Chrome binary when it can be detected.

func DetectBrowserChromeVersion added in v0.14.0

func DetectBrowserChromeVersion(execPath string) string

DetectBrowserChromeVersion returns the major version of the Chrome binary at execPath, or tries common platform paths when execPath is empty.

func HTTPTimeoutOrDefault added in v0.14.0

func HTTPTimeoutOrDefault(timeout time.Duration) time.Duration

HTTPTimeoutOrDefault returns DefaultHTTPTimeout when timeout is not positive.

func IsSOCKSProxy added in v0.14.0

func IsSOCKSProxy(rawProxyURL string) bool

IsSOCKSProxy reports whether a proxy URL uses a supported SOCKS scheme.

func NewHTTPClient added in v0.14.0

func NewHTTPClient(httpProfile HTTPProfile, timeout time.Duration) (*http.Client, error)

NewHTTPClient builds an HTTP client bound to one transport profile.

func ProxyLeaseCandidatesExhaustedError added in v0.15.1

func ProxyLeaseCandidatesExhaustedError(candidateCount int) error

ProxyLeaseCandidatesExhaustedError wraps ErrProxyLeaseCandidatesExhausted with the attempted candidate count.

func ProxyLeaseCandidatesExhaustedErrorWithDiagnostics added in v0.16.0

func ProxyLeaseCandidatesExhaustedErrorWithDiagnostics(candidateCount int, diagnostics ...ProxyFailureDiagnostic) error

ProxyLeaseCandidatesExhaustedErrorWithDiagnostics wraps ErrProxyLeaseCandidatesExhausted with candidate count and reason buckets.

func SetPackageLogger added in v0.5.0

func SetPackageLogger(logger Logger)

SetPackageLogger replaces the package-level logger used by standalone functions.

Types

type BrowserConfig added in v0.14.0

type BrowserConfig = browsertransport.Config

BrowserConfig keeps the historical one-shot render surface used by jseval callers.

type BrowserLaunchOptions added in v0.14.0

type BrowserLaunchOptions = browsertransport.LaunchOptions

BrowserLaunchOptions controls browser process launch behavior.

type BrowserMode added in v0.14.0

type BrowserMode = browsertransport.BrowserMode

BrowserMode describes how a browser should reach the upstream network.

type BrowserPageRequest added in v0.14.0

type BrowserPageRequest = browsertransport.PageRequest

BrowserPageRequest describes a generic "navigate, wait, capture" render.

type BrowserProfile added in v0.14.0

type BrowserProfile = browsertransport.BrowserProfile

BrowserProfile describes how to launch a browser transport.

func InferBrowserProfile added in v0.14.0

func InferBrowserProfile(rawProxyURL string, ignoreCertErrors bool) (BrowserProfile, error)

InferBrowserProfile derives a browser profile from a raw proxy URL.

type BrowserResult added in v0.14.0

type BrowserResult = browsertransport.Result

BrowserResult holds the rendered page content.

func RenderBrowserPage added in v0.14.0

func RenderBrowserPage(ctx context.Context, targetURL string, config BrowserConfig) (*BrowserResult, error)

RenderBrowserPage launches a one-shot browser session and captures the rendered page.

func RenderBrowserPages added in v0.14.0

func RenderBrowserPages(ctx context.Context, targetURLs []string, config BrowserConfig) ([]*BrowserResult, []error)

RenderBrowserPages renders multiple URLs concurrently and returns results in input order.

type BrowserSession added in v0.14.0

type BrowserSession = browsertransport.Session

BrowserSession owns a browser instance bound to one browser transport profile.

func NewBrowserSession added in v0.14.0

func NewBrowserSession(ctx context.Context, browserProfile BrowserProfile, launchOptions BrowserLaunchOptions) (*BrowserSession, error)

NewBrowserSession launches a reusable browser session for the given profile.

type BrowserTabOptions added in v0.14.0

type BrowserTabOptions = browsertransport.TabOptions

BrowserTabOptions controls one render tab opened on an existing browser session.

type Config

type Config struct {
	// PlatformID identifies the target platform (for example "AMZN").
	PlatformID string

	// Scraper controls concurrency, retries, and network behaviour.
	Scraper ScraperConfig

	// Platform holds domain-specific settings such as allowed hosts.
	Platform PlatformConfig

	// OutputDirectory is optional; when supplied and FilePersister is nil the
	// crawler will persist downloaded artifacts under this path.
	OutputDirectory string

	// RunFolder scopes persisted artifacts for a single execution.
	RunFolder string

	// RuleEvaluator produces rule findings for a fetched document. Mandatory.
	RuleEvaluator RuleEvaluator

	// CookieGenerator returns cookies for a given domain. Optional.
	CookieGenerator CookieGenerator

	// FilePersister handles file persistence. Optional; a default implementation
	// is created when OutputDirectory is set.
	FilePersister FilePersister

	// PlatformHooks customise platform-specific behaviour. Optional.
	PlatformHooks PlatformHooks

	// RequestHeaders applies custom headers before each outbound request.
	RequestHeaders RequestHeaderProvider

	// RequestHook runs before each outbound request. Optional.
	RequestHook RequestHook

	// Logger receives debug/info/warning/error logs. Optional; a no-op logger is
	// used when nil.
	Logger Logger
}

Config wires the crawler service with platform metadata, scraping options, and effectful collaborators. All fields are mandatory unless marked as optional.

func (Config) Validate

func (cfg Config) Validate() error

Validate ensures required configuration is present and self-consistent.

type CookieGenerator added in v0.5.0

type CookieGenerator func(domain string) []*http.Cookie

CookieGenerator returns cookies for a specific domain.

type FilePersister added in v0.4.0

type FilePersister interface {
	Save(productID, fileName string, content []byte) error
	Close() error
}

FilePersister persists binary artifacts associated with a product.

type HTTPProfile added in v0.14.0

type HTTPProfile = httptransport.Profile

HTTPProfile describes how to build an HTTP client transport.

func InferHTTPProfile added in v0.14.0

func InferHTTPProfile(rawProxyURL string, ignoreCertErrors bool) (HTTPProfile, error)

InferHTTPProfile derives an HTTP transport profile from a raw proxy URL.

func NormalizeHTTPProfile added in v0.14.0

func NormalizeHTTPProfile(httpProfile HTTPProfile) (HTTPProfile, error)

NormalizeHTTPProfile trims and validates a profile before client creation.

type Logger

type Logger interface {
	Debug(format string, args ...interface{})
	Info(format string, args ...interface{})
	Warning(format string, args ...interface{})
	Error(format string, args ...interface{})
}

Logger emits structured diagnostic messages. Implementations should be safe for concurrent use. Methods follow fmt.Sprintf semantics.

func EnsureLogger added in v0.5.1

func EnsureLogger(logger Logger) Logger

EnsureLogger returns the provided logger if non-nil, otherwise a no-op logger.

type NoopResponseHandler added in v0.5.0

type NoopResponseHandler struct{}

NoopResponseHandler provides default no-op implementations of ResponseHandler.

func (NoopResponseHandler) AfterEvaluation added in v0.5.0

func (NoopResponseHandler) AfterEvaluation(*colly.Response, *goquery.Document, *Result)

AfterEvaluation does nothing.

func (NoopResponseHandler) BeforeEvaluation added in v0.5.0

func (NoopResponseHandler) BeforeEvaluation(*colly.Response, *goquery.Document)

BeforeEvaluation does nothing.

func (NoopResponseHandler) HandleBinaryResponse added in v0.5.0

func (NoopResponseHandler) HandleBinaryResponse(*colly.Response, string, string) bool

HandleBinaryResponse returns false, indicating the response was not handled.

type PlatformConfig added in v0.4.0

type PlatformConfig struct {
	AllowedDomains      []string
	CookieDomains       []string
	SkipRulesOnRedirect bool
}

PlatformConfig restricts the crawler to known domains and provides selectors.

func (PlatformConfig) Validate added in v0.4.0

func (cfg PlatformConfig) Validate() error

Validate ensures the platform configuration is usable.

type PlatformHooks added in v0.4.0

type PlatformHooks interface {
	NormalizeTitle(title string) string
	ShouldRetry(title string, document *goquery.Document) RetryDecision
	ExtractDOMTitle(document *goquery.Document) string
	IsContentComplete(document *goquery.Document) bool
	InferRedirect(productID, originalURL, finalURL, canonicalURL string) (redirected bool, redirectedProductID string)
}

PlatformHooks provide platform-specific normalisation, content validation, redirect detection, and retry logic. Implementations encapsulate all platform-specific behaviour so the core crawler remains generic.

type Product added in v0.5.0

type Product struct {
	ID          string
	Platform    string
	URL         string
	OriginalID  string
	OriginalURL string
}

Product describes a single page to crawl.

func NewProduct added in v0.5.0

func NewProduct(id, platform, url string, opts ...ProductOption) (Product, error)

NewProduct constructs a Product after validating mandatory fields.

type ProductOption added in v0.5.0

type ProductOption func(*Product)

ProductOption mutates optional fields on Product construction.

func WithOriginalID added in v0.5.0

func WithOriginalID(originalID string) ProductOption

WithOriginalID sets the original identifier when different from ID.

func WithOriginalURL added in v0.5.0

func WithOriginalURL(originalURL string) ProductOption

WithOriginalURL records the source URL before redirects.

type ProxyFailureDiagnostic added in v0.16.0

type ProxyFailureDiagnostic struct {
	Kind       ProxyFailureKind
	Reason     string
	StatusCode int
}

ProxyFailureDiagnostic captures structured proxy rotation diagnostics.

type ProxyFailureKind added in v0.16.0

type ProxyFailureKind string

ProxyFailureKind classifies why a proxy lease was rotated or marked unhealthy.

const (
	ProxyFailureKindUnknown         ProxyFailureKind = "unknown"
	ProxyFailureKindChallenge       ProxyFailureKind = "challenge"
	ProxyFailureKindTransport       ProxyFailureKind = "transport"
	ProxyFailureKindStatus          ProxyFailureKind = "status"
	ProxyFailureKindProviderAuth    ProxyFailureKind = "provider_auth"
	ProxyFailureKindProviderAccount ProxyFailureKind = "provider_account"
)

type ProxyLease added in v0.15.0

type ProxyLease struct {
	ProviderName string
	UserName     string
	ProxyURL     string
	Generation   uint64
}

ProxyLease identifies the provider/user/proxy tuple chosen for one request.

func (ProxyLease) Valid added in v0.15.0

func (lease ProxyLease) Valid() bool

Valid reports whether the lease has a concrete proxy URL.

type ProxyLeaseAttemptScope added in v0.15.1

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

ProxyLeaseAttemptScope tracks failed proxy leases for one scrape, request batch, or other caller-defined operation.

func NewProxyLeaseAttemptScope added in v0.15.1

func NewProxyLeaseAttemptScope() *ProxyLeaseAttemptScope

NewProxyLeaseAttemptScope constructs an operation-scoped failed-lease tracker.

func (*ProxyLeaseAttemptScope) AcquireRequired added in v0.15.1

func (scope *ProxyLeaseAttemptScope) AcquireRequired(selector *ProxyLeaseSelector) (ProxyLease, error)

AcquireRequired reserves the next lease that has not failed inside this operation scope.

func (*ProxyLeaseAttemptScope) Exhausted added in v0.15.1

func (scope *ProxyLeaseAttemptScope) Exhausted(candidateCount int) bool

Exhausted reports whether every configured candidate has failed inside this operation scope.

func (*ProxyLeaseAttemptScope) Failed added in v0.15.1

func (scope *ProxyLeaseAttemptScope) Failed(lease ProxyLease) bool

Failed reports whether the lease already failed inside this operation scope.

func (*ProxyLeaseAttemptScope) FailureDiagnostic added in v0.16.0

func (scope *ProxyLeaseAttemptScope) FailureDiagnostic(lease ProxyLease) (ProxyFailureDiagnostic, bool)

FailureDiagnostic reports the recorded failure reason for a lease.

func (*ProxyLeaseAttemptScope) ReportFailure added in v0.15.1

func (scope *ProxyLeaseAttemptScope) ReportFailure(lease ProxyLease)

ReportFailure records a lease failure inside this operation scope.

func (*ProxyLeaseAttemptScope) ReportFailureWithDiagnostic added in v0.16.0

func (scope *ProxyLeaseAttemptScope) ReportFailureWithDiagnostic(lease ProxyLease, diagnostic ProxyFailureDiagnostic)

ReportFailureWithDiagnostic records a lease failure reason inside this operation scope.

type ProxyLeaseSelector added in v0.15.0

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

ProxyLeaseSelector acquires proxy leases from ordered providers and keeps successful leases sticky until a failure advances rotation.

func NewProxyLeaseSelector added in v0.15.0

func NewProxyLeaseSelector(configs []ProxyRotationProviderConfig) (*ProxyLeaseSelector, error)

NewProxyLeaseSelector constructs a provider-aware lease selector.

func NewProxyLeaseSelectorWithOptions added in v0.15.2

func NewProxyLeaseSelectorWithOptions(configs []ProxyRotationProviderConfig, optionList ...ProxyLeaseSelectorOption) (*ProxyLeaseSelector, error)

NewProxyLeaseSelectorWithOptions constructs a provider-aware lease selector with runtime options such as cooldowns and initial provider position.

func (*ProxyLeaseSelector) Acquire added in v0.15.0

func (selector *ProxyLeaseSelector) Acquire() ProxyLease

Acquire reserves and returns the best current proxy lease.

func (*ProxyLeaseSelector) AcquireForRequest added in v0.15.0

func (selector *ProxyLeaseSelector) AcquireForRequest(request *http.Request) (ProxyLease, error)

AcquireForRequest reserves a lease and attaches it to the request context for HTTP and Colly callers.

func (*ProxyLeaseSelector) AcquireRequired added in v0.15.0

func (selector *ProxyLeaseSelector) AcquireRequired() (ProxyLease, error)

AcquireRequired reserves and returns a proxy lease or a typed unavailable error when no proxy is configured.

func (*ProxyLeaseSelector) CandidateCount added in v0.15.1

func (selector *ProxyLeaseSelector) CandidateCount() int

CandidateCount returns the number of configured proxy candidates.

func (*ProxyLeaseSelector) IsAvailable added in v0.15.2

func (selector *ProxyLeaseSelector) IsAvailable(proxyURL string) bool

IsAvailable reports whether a proxy is outside cooldown.

func (*ProxyLeaseSelector) RecordCriticalFailure added in v0.15.2

func (selector *ProxyLeaseSelector) RecordCriticalFailure(proxyURL string)

RecordCriticalFailure keeps string-only callers compatible.

func (*ProxyLeaseSelector) RecordFailure added in v0.15.0

func (selector *ProxyLeaseSelector) RecordFailure(proxyURL string)

RecordFailure keeps string-only callers compatible.

func (*ProxyLeaseSelector) RecordSuccess added in v0.15.0

func (selector *ProxyLeaseSelector) RecordSuccess(proxyURL string)

RecordSuccess keeps string-only callers compatible.

func (*ProxyLeaseSelector) Release added in v0.15.0

func (selector *ProxyLeaseSelector) Release(lease ProxyLease)

Release releases a previously acquired lease reservation without reporting success or failure.

func (*ProxyLeaseSelector) ReportCriticalFailure added in v0.15.2

func (selector *ProxyLeaseSelector) ReportCriticalFailure(lease ProxyLease)

ReportCriticalFailure releases a lease and immediately cools the proxy.

func (*ProxyLeaseSelector) ReportCriticalFailureWithDiagnostic added in v0.16.0

func (selector *ProxyLeaseSelector) ReportCriticalFailureWithDiagnostic(lease ProxyLease, diagnostic ProxyFailureDiagnostic)

ReportCriticalFailureWithDiagnostic releases a lease, immediately cools the proxy, and stores the diagnostic reason.

func (*ProxyLeaseSelector) ReportFailure added in v0.15.0

func (selector *ProxyLeaseSelector) ReportFailure(lease ProxyLease)

ReportFailure releases a lease and rotates immediately to the next provider.

func (*ProxyLeaseSelector) ReportFailureWithDiagnostic added in v0.16.0

func (selector *ProxyLeaseSelector) ReportFailureWithDiagnostic(lease ProxyLease, diagnostic ProxyFailureDiagnostic)

ReportFailureWithDiagnostic releases a lease, records a normal proxy failure, and stores the diagnostic reason.

func (*ProxyLeaseSelector) ReportProxyRetry added in v0.15.4

func (selector *ProxyLeaseSelector) ReportProxyRetry(lease ProxyLease)

ReportProxyRetry releases a lease and rotates without recording proxy health failure.

func (*ProxyLeaseSelector) ReportProxyRetryWithDiagnostic added in v0.16.0

func (selector *ProxyLeaseSelector) ReportProxyRetryWithDiagnostic(lease ProxyLease, diagnostic ProxyFailureDiagnostic)

ReportProxyRetryWithDiagnostic releases a lease, rotates without recording proxy health failure, and stores the diagnostic reason.

func (*ProxyLeaseSelector) ReportSuccess added in v0.15.0

func (selector *ProxyLeaseSelector) ReportSuccess(lease ProxyLease)

ReportSuccess releases a lease and keeps its provider/user tuple sticky.

func (*ProxyLeaseSelector) Select added in v0.15.2

func (selector *ProxyLeaseSelector) Select(request *http.Request) (*url.URL, error)

Select returns the currently active provider/user tuple as a Colly proxy function.

func (*ProxyLeaseSelector) SelectionForProxyURL added in v0.15.0

func (selector *ProxyLeaseSelector) SelectionForProxyURL(proxyURL string) (ProxySelection, bool)

SelectionForProxyURL returns the current-generation selection metadata for a known proxy URL.

type ProxyLeaseSelectorOption added in v0.15.2

type ProxyLeaseSelectorOption func(*proxyLeaseSelectorOptions)

ProxyLeaseSelectorOption configures proxy lease selector runtime behavior.

func ProxyLeaseSelectorCircuitBreaker added in v0.15.2

func ProxyLeaseSelectorCircuitBreaker(enabled bool) ProxyLeaseSelectorOption

ProxyLeaseSelectorCircuitBreaker enables or disables cooldown tracking.

func ProxyLeaseSelectorClock added in v0.15.2

func ProxyLeaseSelectorClock(now func() time.Time) ProxyLeaseSelectorOption

ProxyLeaseSelectorClock injects the selector clock for deterministic tests.

func ProxyLeaseSelectorLogger added in v0.15.2

func ProxyLeaseSelectorLogger(logger Logger) ProxyLeaseSelectorOption

ProxyLeaseSelectorLogger sets the selector logger used for cooldown notices.

func ProxyLeaseSelectorStartProvider added in v0.15.2

func ProxyLeaseSelectorStartProvider(index int) ProxyLeaseSelectorOption

ProxyLeaseSelectorStartProvider sets the initial active provider index.

type ProxyRotationProviderConfig added in v0.14.0

type ProxyRotationProviderConfig struct {
	Name  string
	Users []ProxyRotationUserConfig
}

ProxyRotationProviderConfig describes one ordered provider and its proxy users.

type ProxyRotationSelector added in v0.14.0

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

ProxyRotationSelector keeps one (provider, user) selection sticky until a proxy-related failure advances to the next provider. When the selector later returns to a failed provider, it uses that provider's next user.

func NewProxyRotationSelector added in v0.14.0

func NewProxyRotationSelector(configs []ProxyRotationProviderConfig) (*ProxyRotationSelector, error)

NewProxyRotationSelector constructs a provider-aware proxy selector.

func (*ProxyRotationSelector) RecordFailure added in v0.14.0

func (selector *ProxyRotationSelector) RecordFailure(proxyURL string)

RecordFailure keeps string-only callers compatible.

func (*ProxyRotationSelector) RecordProxyCriticalFailure added in v0.15.2

func (selector *ProxyRotationSelector) RecordProxyCriticalFailure(selection ProxySelection)

RecordProxyCriticalFailure cools the selected proxy immediately.

func (*ProxyRotationSelector) RecordProxyFailure added in v0.14.0

func (selector *ProxyRotationSelector) RecordProxyFailure(selection ProxySelection)

RecordProxyFailure rotates to the next provider and advances the failed provider's user cursor.

func (*ProxyRotationSelector) RecordProxyRetry added in v0.15.4

func (selector *ProxyRotationSelector) RecordProxyRetry(selection ProxySelection)

RecordProxyRetry rotates to the next provider without recording proxy health failure.

func (*ProxyRotationSelector) RecordProxySuccess added in v0.14.0

func (selector *ProxyRotationSelector) RecordProxySuccess(selection ProxySelection)

RecordProxySuccess makes the successful provider/user tuple sticky until the next accepted failure.

func (*ProxyRotationSelector) RecordSuccess added in v0.14.0

func (selector *ProxyRotationSelector) RecordSuccess(proxyURL string)

RecordSuccess keeps string-only callers compatible.

func (*ProxyRotationSelector) Select added in v0.14.0

func (selector *ProxyRotationSelector) Select(request *http.Request) (*url.URL, error)

Select returns the currently active provider/user tuple.

func (*ProxyRotationSelector) SelectionForProxyURL added in v0.14.0

func (selector *ProxyRotationSelector) SelectionForProxyURL(proxyURL string) (ProxySelection, bool)

SelectionForProxyURL returns the current-generation selection metadata for a known proxy URL.

type ProxyRotationUserConfig added in v0.14.0

type ProxyRotationUserConfig struct {
	Name string
	URL  string
}

ProxyRotationUserConfig describes one ordered proxy credential inside a provider.

type ProxySelection added in v0.14.0

type ProxySelection = ProxyLease

ProxySelection identifies the provider/user/proxy tuple chosen for one request.

func SelectedProxySelection added in v0.14.0

func SelectedProxySelection(request *http.Request) (ProxySelection, bool)

SelectedProxySelection reads a proxy selection previously attached to a request.

type RequestConfigurator added in v0.4.0

type RequestConfigurator interface {
	Configure(collector *colly.Collector)
}

RequestConfigurator applies cookies and headers to outgoing requests.

type RequestHeaderProvider added in v0.5.0

type RequestHeaderProvider interface {
	Apply(platformID string, request *colly.Request)
}

RequestHeaderProvider decorates outbound collector requests.

type RequestHook

type RequestHook interface {
	BeforeRequest(ctx context.Context, product Product) error
}

type ResponseHandler added in v0.4.0

type ResponseHandler interface {
	// HandleBinaryResponse processes non-HTML responses (e.g. images).
	// Return true to indicate the response was handled and stop further processing.
	HandleBinaryResponse(resp *colly.Response, productID string, fileExtension string) bool

	// BeforeEvaluation is called after HTML parsing and content validation but
	// before rule evaluation. Use for tasks like image retrieval.
	BeforeEvaluation(resp *colly.Response, document *goquery.Document)

	// AfterEvaluation is called once the processor has enough context to build
	// the final result, before that result is emitted. Use for tasks like
	// discoverability probing or file persistence.
	AfterEvaluation(resp *colly.Response, document *goquery.Document, result *Result)
}

ResponseHandler extends the crawling pipeline with domain-specific behaviour. Implementations are called at specific points during response processing.

type ResponseHandlerRuntimeBinder added in v0.5.2

type ResponseHandlerRuntimeBinder interface {
	BindRuntime(collector *colly.Collector, filePersister FilePersister, retryHandler RetryHandler)
}

ResponseHandlerRuntimeBinder fills runtime-managed dependencies on handlers after the crawler service has created them.

type ResponseProcessor added in v0.5.0

type ResponseProcessor interface {
	Setup(collector *colly.Collector)
	SendFinalResult(resp *colly.Response, success bool, errorText string)
	SetResultCallback(callback func(*colly.Response))
	SetResponseHandlers(handlers []ResponseHandler)
}

ResponseProcessor handles incoming responses and emits final results.

type Result

type Result struct {
	ProductID               string       `json:"product_id" csv:"ID"`
	OriginalProductID       string       `json:"original_product_id,omitempty" csv:"OriginalID"`
	OriginalURL             string       `json:"original_url,omitempty" csv:""`
	FinalURL                string       `json:"final_url,omitempty" csv:""`
	CanonicalURL            string       `json:"canonical_url,omitempty" csv:""`
	ProxyURL                string       `json:"proxy_url,omitempty" csv:"ProxyURL"`
	ProductURL              string       `json:"product_url" csv:"URL"`
	ProductTitle            string       `json:"product_title,omitempty" csv:"Title"`
	ProductPlatform         string       `json:"product_platform"`
	Success                 bool         `json:"success"`
	ErrorMessage            string       `json:"error_message,omitempty" csv:"ErrorMessage"`
	HTTPStatusCode          int          `json:"http_status_code,omitempty" csv:"HTTPStatusCode"`
	Progress                int          `json:"progress,omitempty"`
	RuleResults             []RuleResult `json:"results,omitempty"`
	ConfiguredVerifierCount int          `json:"-" csv:"-"`
	ScoreOverride           *int         `json:"-" csv:"-"`
}

Result represents the normalized outcome of crawling a single product page.

func (Result) CalculateScore added in v0.5.0

func (result Result) CalculateScore(configuredVerifierCount int) int

CalculateScore returns the percentage of configured verifiers that passed.

func (Result) IsNotFound added in v0.5.0

func (result Result) IsNotFound() bool

IsNotFound reports whether the HTTP status code represents a missing page.

func (Result) IsNotRetryable added in v0.5.0

func (result Result) IsNotRetryable() bool

IsNotRetryable reports whether retrying would be pointless.

type RetryDecision added in v0.4.0

type RetryDecision struct {
	ShouldRetry          bool
	Message              string
	LogMessage           string
	Policy               RetryPolicy
	ExhaustionBehavior   RetryExhaustionBehavior
	ProxyFailureSeverity RetryProxyFailureSeverity
	ProxyFailureKind     ProxyFailureKind
	ProxyFailureReason   string
}

RetryDecision captures the outcome of a platform retry check.

func (RetryDecision) ResolvedLogMessage added in v0.4.0

func (decision RetryDecision) ResolvedLogMessage() string

ResolvedLogMessage returns the log message or falls back to the general message.

type RetryExhaustionBehavior added in v0.4.0

type RetryExhaustionBehavior uint8

RetryExhaustionBehavior controls what happens when retries are exhausted.

const (
	RetryExhaustionBehaviorFail RetryExhaustionBehavior = iota
	RetryExhaustionBehaviorContinue
)

type RetryHandler added in v0.4.0

type RetryHandler interface {
	Retry(response *colly.Response, options RetryOptions) bool
}

RetryHandler encapsulates retry behaviour for failed responses.

type RetryOptions added in v0.4.0

type RetryOptions struct {
	SkipDelay    bool
	LimitRetries bool
	MaxRetries   int
}

type RetryPolicy added in v0.4.0

type RetryPolicy uint8

RetryPolicy controls how retries are performed.

const (
	RetryPolicyDefault RetryPolicy = iota
	RetryPolicyRotateProxy
)

type RetryProxyFailureSeverity added in v0.15.4

type RetryProxyFailureSeverity uint8

RetryProxyFailureSeverity controls how rotate-proxy retries affect proxy health.

const (
	// RetryProxyFailureSeverityNormal rotates away from the current proxy without
	// forcing a global cooldown. This is the default for retry decisions that
	// should avoid the current lease without proving the proxy is unhealthy.
	RetryProxyFailureSeverityNormal RetryProxyFailureSeverity = iota
	// RetryProxyFailureSeverityCritical rotates and immediately cools down the
	// proxy. Use this only when the response proves the proxy candidate itself is
	// unhealthy for future requests.
	RetryProxyFailureSeverityCritical
)

type RuleEvaluation added in v0.5.0

type RuleEvaluation struct {
	Passed             bool
	ConfiguredVerifier int
	RuleResults        []RuleResult
}

RuleEvaluation aggregates evaluation output from the injected RuleEvaluator.

type RuleEvaluator added in v0.5.0

type RuleEvaluator interface {
	Evaluate(productID string, document *goquery.Document) (RuleEvaluation, error)
	ConfiguredVerifierCount() int
}

RuleEvaluator produces a RuleEvaluation for a fetched document.

type RuleResult added in v0.5.0

type RuleResult struct {
	ID                  string               `json:"id,omitempty" csv:"-"`
	Description         string               `json:"description" csv:"Description,keyValue"`
	Passed              bool                 `json:"passed" csv:"passed"`
	ReportingOrder      int                  `json:"reporting_order" csv:"-"`
	Message             string               `json:"message" csv:"message"`
	VerificationResults []VerificationResult `json:"verification_results"`
}

RuleResult represents rule-level evaluation outcome.

type ScraperConfig added in v0.4.0

type ScraperConfig struct {
	MaxDepth                   int
	Parallelism                int
	RetryCount                 int
	HTTPTimeout                time.Duration
	InsecureSkipVerify         bool
	RateLimit                  time.Duration
	ProxyList                  []string
	ProxyLeaseSelector         *ProxyLeaseSelector
	SaveFiles                  bool
	ProxyCircuitBreakerEnabled bool
}

ScraperConfig exposes concurrency and retry knobs for the crawler.

func (ScraperConfig) ProxyCandidateCount added in v0.15.2

func (cfg ScraperConfig) ProxyCandidateCount() int

ProxyCandidateCount reports the configured proxy candidate count.

func (ScraperConfig) Validate added in v0.4.0

func (cfg ScraperConfig) Validate() error

Validate checks that essential numeric fields are positive.

type Service

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

Service orchestrates crawling of product pages and emits results.

func NewService

func NewService(cfg Config, results chan<- *Result, options ...ServiceOption) (*Service, error)

NewService constructs a crawler service configured for a platform. ServiceOption values customize the service with response handlers and lifecycle hooks.

func (*Service) Run

func (service *Service) Run(ctx context.Context, products []Product) error

Run visits each product URL once and blocks until completion or context cancellation.

type ServiceHook added in v0.5.0

type ServiceHook interface {
	// AfterInit is called after the collector, transport, and response processor
	// are fully wired. Use for binding domain-specific network configuration.
	AfterInit(collector *colly.Collector, transport http.RoundTripper)

	// BeforeRun is called before the product visit loop starts.
	BeforeRun(ctx context.Context)

	// AfterRun is called after all products have been visited and the collector
	// has finished. Use for cleanup (e.g. stopping image converter workers).
	AfterRun()
}

ServiceHook provides lifecycle callbacks for the crawler service.

type ServiceOption added in v0.5.0

type ServiceOption func(*Service)

ServiceOption configures a Service during construction.

func WithResponseHandlers added in v0.5.0

func WithResponseHandlers(handlers ...ResponseHandler) ServiceOption

WithResponseHandlers registers ResponseHandlers that extend the crawling pipeline.

func WithServiceHook added in v0.5.0

func WithServiceHook(hook ServiceHook) ServiceOption

WithServiceHook registers a lifecycle hook for the crawler service.

type VerificationResult added in v0.5.0

type VerificationResult struct {
	ID             string `json:"id,omitempty" csv:"-"`
	Description    string `json:"description" csv:"Description,keyValue"`
	Passed         bool   `json:"passed" csv:"passed"`
	Message        string `json:"message" csv:"message"`
	Value          string `json:"value" csv:"value"`
	ReportingOrder int    `json:"reporting_order"`
	IncludeValue   bool   `json:"-"`
}

VerificationResult captures the outcome of an individual verifier.

Jump to

Keyboard shortcuts

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