Documentation
¶
Overview ¶
Package ebay is the library behind the ebay command line: an HTTP client for eBay's public web pages and autocomplete host, an optional Browse API backend, and the typed records every command emits.
eBay renders its public pages server-side with schema.org JSON-LD and HTML cards, so this client GETs pages and parses them; the autocomplete host answers plain JSON. eBay fronts its estate with Akamai Bot Manager, which walls the item page (/itm/) and keyword search (/sch/) from datacenter IPs while serving category browse (/b/), seller stores (/str/, /usr/), the deals hub (/deals), and autocomplete from anywhere. So the client is two-layered: a reliable core over the open surfaces, and a best-effort layer over the walled ones that returns ErrBlocked when the wall is up and, if the operator has set Browse API credentials, falls back to that documented backend. Each surface lives in its own file (search.go, item.go, seller.go, category.go, deals.go, suggest.go) with its parsing and record mapping; this file holds the shared web client.
Index ¶
- Constants
- Variables
- func Defaults(c *kit.Config)
- func Identity() kit.Identity
- func URLFor(kind, id string) string
- type Category
- type Client
- func (c *Client) CategoryBrowse(ctx context.Context, ref string, limit int) ([]*Listing, error)
- func (c *Client) CategoryTree(ctx context.Context, ref string, limit int) ([]*Category, error)
- func (c *Client) ClearCache() error
- func (c *Client) Deals(ctx context.Context, limit int) ([]*Deal, error)
- func (c *Client) GetCategory(ctx context.Context, ref string) (*Category, error)
- func (c *Client) GetItem(ctx context.Context, ref string) (*Item, error)
- func (c *Client) GetSeller(ctx context.Context, ref string) (*Seller, error)
- func (c *Client) Search(ctx context.Context, query string, limit int) ([]*Listing, error)
- func (c *Client) SellerListings(ctx context.Context, ref string, limit int) ([]*Listing, error)
- func (c *Client) Suggest(ctx context.Context, prefix string, limit int) ([]*Suggestion, error)
- type Config
- type Deal
- type Domain
- type Item
- type Listing
- type Ref
- type Seller
- type Suggestion
Constants ¶
const ( // DefaultDelay is the minimum gap between requests. eBay is touchier than a // plain API, so a one-second pace reads steadily without leaning on it. DefaultDelay = 1 * time.Second DefaultRetries = 3 DefaultTimeout = 30 * time.Second DefaultCacheTTL = 24 * time.Hour )
Defaults for the polite client.
const BaseURL = "https://" + Host
BaseURL is the root every item, seller, and category URL is built from.
const DefaultUserAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) " +
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"
DefaultUserAgent is sent with every page request. eBay serves its public pages to a normal browser; a browser User-Agent is what keeps a logged-out reader looking like one. Override it with --user-agent.
const Host = "www.ebay.com"
Host is the eBay hostname this client builds page URLs from and the host the URI driver in domain.go claims.
Variables ¶
var ( // ErrNotFound is a missing entity: an unknown item id, an unknown seller, or // a bad category. eBay serves these as a 404 or a not-found shell page. // Exit code 6. ErrNotFound = errors.New("not found") // ErrRateLimited is a sustained HTTP 429 after the client's own retries. // Slow down with --rate. Exit code 5. ErrRateLimited = errors.New("rate limited") // ErrBlocked is the Akamai bot wall: a 403 interstitial, a reset, or an // implausibly small body on a page that should be large. eBay walls the item // page and keyword search from datacenter IPs, so this is expected there and // the message names the two remedies (a residential IP, or Browse API // credentials). Exit code 4. ErrBlocked = errors.New("blocked by eBay's bot wall (retry from a residential network, " + "or set EBAY_CLIENT_ID and EBAY_CLIENT_SECRET to use the Browse API)") )
The library reports its outcomes as a few sentinel errors. domain.go's mapErr translates each into the kit error kind that carries the matching exit code, so the standalone binary and a host agree on what a wall, a throttle, and a miss mean.
Functions ¶
func Defaults ¶
Defaults seeds the framework baseline with ebay's own values, so an unset --rate or --timeout uses the ebay default rather than the generic kit one. It is passed to kit.New via kit.WithDefaults.
Types ¶
type Category ¶
type Category struct {
ID string `json:"id" kit:"id"` // numeric leaf category id
Name string `json:"name"`
Parent string `json:"parent,omitempty"` // parent category name (from the trail)
Trail []string `json:"trail,omitempty"` // the full ancestor path, eBay first, leaf last
Node string `json:"node,omitempty"` // bn_<digits> browse-node id when known
URL string `json:"url"`
}
Category is a category node, emitted by category show and category tree.
type Client ¶
type Client struct {
HTTP *http.Client
BaseURL string
UserAgent string
Delay time.Duration
Retries int
// SuggestURL is the autocomplete endpoint. It defaults to the public
// autosug host; tests point it at an httptest server.
SuggestURL string
// contains filtered or unexported fields
}
Client talks to eBay's public web pages. It paces requests, retries the transient failures, detects the bot wall, and caches response bodies on disk keyed by the request URL.
func ClientFromConfig ¶
ClientFromConfig maps the framework config onto an ebay.Config and returns a client. The Browse credentials are read from the environment, not flags, so they never land in shell history.
func (*Client) CategoryBrowse ¶
CategoryBrowse returns the listings in a category.
func (*Client) CategoryTree ¶
CategoryTree returns the child categories of a node, read from the left-rail category links the browse page renders.
func (*Client) ClearCache ¶
ClearCache removes the on-disk cache.
func (*Client) GetCategory ¶
GetCategory returns a category's metadata: its name and its parent, from the breadcrumb trail on the browse page.
func (*Client) SellerListings ¶
SellerListings returns a seller's active listings.
type Config ¶
type Config struct {
UserAgent string
Marketplace string
// ClientID and ClientSecret enable the Browse API fallback for the walled
// surfaces (item, search). Empty leaves the fallback off; the walled
// commands then report the bot wall rather than guessing.
ClientID string
ClientSecret string
// Delay is the minimum gap between requests. Zero means no pacing.
Delay time.Duration
Retries int
Timeout time.Duration
// BaseURL is the site root. Empty uses the public site; tests point it at an
// httptest server.
BaseURL string
// CacheDir is where responses are cached. Empty disables the cache, as does
// NoCache.
CacheDir string
CacheTTL time.Duration
NoCache bool
// Refresh fetches fresh copies and rewrites the cache, ignoring any hit.
Refresh bool
}
Config carries the knobs the client reads. It is built from the kit framework config in ClientFromConfig, so a --rate or --timeout on the command line and the same value resolved by a host both land here.
func DefaultConfig ¶
func DefaultConfig() Config
DefaultConfig returns the baseline configuration: a browser User-Agent, the EBAY_US marketplace, a one-second pace, three retries, a 30s timeout, and a one-day cache.
type Deal ¶
type Deal struct {
ID string `json:"id" kit:"id"`
Title string `json:"title,omitempty" table:",truncate"`
Price float64 `json:"price,omitempty"`
Was float64 `json:"was,omitempty"` // original price
Currency string `json:"currency,omitempty"`
Discount string `json:"discount,omitempty"` // the badge text, e.g. "20% off"
FreeShipping bool `json:"free_shipping,omitempty"`
Trending bool `json:"trending,omitempty"` // the tile carries a hotness badge
Image string `json:"image,omitempty" table:",truncate"`
URL string `json:"url"`
}
Deal is a row on the deals hub, emitted by deals.
type Domain ¶
type Domain struct{}
Domain is the ebay driver. It carries no state; the per-run client is built by the factory Register hands kit.
func (Domain) Classify ¶
Classify turns any accepted input into the canonical (type, id), so `ant resolve` and `ant url` touch no network.
func (Domain) Info ¶
func (Domain) Info() kit.DomainInfo
Info describes the scheme, the hostnames a pasted link is matched against, and the identity reused for the binary's help and version.
type Item ¶
type Item struct {
ID string `json:"id" kit:"id"`
Title string `json:"title,omitempty" table:",truncate"`
Subtitle string `json:"subtitle,omitempty" table:",truncate"`
Price float64 `json:"price,omitempty"`
Currency string `json:"currency,omitempty"`
Condition string `json:"condition,omitempty"`
Buying string `json:"buying,omitempty"` // fixed, auction
Bids int `json:"bids,omitempty"` // auctions only
EndsAt string `json:"ends_at,omitempty"`
Available int `json:"available,omitempty"`
Sold int `json:"sold,omitempty"`
Seller string `json:"seller,omitempty"`
SellerScore int `json:"seller_score,omitempty"`
SellerRating float64 `json:"seller_rating,omitempty"`
Location string `json:"location,omitempty"`
Shipping string `json:"shipping,omitempty"`
Returns string `json:"returns,omitempty"`
Category string `json:"category,omitempty"`
Image string `json:"image,omitempty" table:",truncate"`
Images []string `json:"images,omitempty"` // the photo gallery, when the page or API lists more than one
URL string `json:"url"`
}
Item is the full detail for one item, emitted by item. The fields are what the /itm page shows a logged-out visitor, the same fields the Browse API returns on the fallback path.
type Listing ¶
type Listing struct {
ID string `json:"id" kit:"id"`
Title string `json:"title,omitempty" table:",truncate"`
Price float64 `json:"price,omitempty"`
Currency string `json:"currency,omitempty"`
Condition string `json:"condition,omitempty"`
Buying string `json:"buying,omitempty"` // fixed, auction, best_offer
Bids int `json:"bids,omitempty"` // auctions only
Shipping string `json:"shipping,omitempty"`
Seller string `json:"seller,omitempty"`
Rating float64 `json:"rating,omitempty"` // aggregate rating (category JSON-LD)
Reviews int `json:"reviews,omitempty"` // review count (category JSON-LD)
Sold int `json:"sold,omitempty"` // units sold, when the card prints it
Watching int `json:"watching,omitempty"`
Thumbnail string `json:"thumbnail,omitempty" table:",truncate"`
Images []string `json:"images,omitempty"` // image gallery (category JSON-LD itemOffered)
URL string `json:"url"`
}
Listing is a summary row in a grid, emitted by search, category browse, and seller listings.
type Ref ¶
type Ref struct {
Input string `json:"input"`
Kind string `json:"kind"`
ID string `json:"id"`
URL string `json:"url"`
}
Ref is the result of `ebay ref id`: the canonical (kind, id) a reference resolves to, plus the live URL, all without touching the network.
type Seller ¶
type Seller struct {
Username string `json:"username" kit:"id"`
Store string `json:"store,omitempty"`
Score int `json:"score,omitempty"` // feedback score (count), when shown
Positive float64 `json:"positive,omitempty"` // percent positive feedback
Sold int `json:"sold,omitempty"` // lifetime items sold (storefront)
Followers int `json:"followers,omitempty"`
TopRated bool `json:"top_rated,omitempty"` // the Top Rated Seller badge
Location string `json:"location,omitempty"`
Logo string `json:"logo,omitempty" table:",truncate"` // store logo image
URL string `json:"url"`
}
Seller is a seller's public profile, emitted by seller show.
type Suggestion ¶
type Suggestion struct {
Query string `json:"query"` // the prefix that was queried
Term string `json:"term" kit:"id"` // a suggested completion
}
Suggestion is one autocomplete term, emitted by suggest.