douban

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Jun 14, 2026 License: Apache-2.0 Imports: 16 Imported by: 0

Documentation

Overview

Package douban is the library behind the douban command: the HTTP client, request shaping, and typed data models for Douban (豆瓣).

The client reads Douban through the public web surfaces that serve without a login: subject search, the j/subject_suggest JSON endpoints, book subject pages, the Top 250 / chart / now-playing film lists, and curated doulists. No API key or authentication is required. It sets a real User-Agent, paces requests, and retries transient 429/5xx errors with exponential backoff.

Douban's subdomains differ in anti-bot posture: book subject pages serve fully, but movie subject and celebrity pages redirect to a sec.douban.com challenge. Film data is therefore reached through suggest and the list pages rather than per-film detail pages.

Index

Constants

View Source
const (
	// DefaultFrodoBase is the Frodo API origin.
	DefaultFrodoBase = "https://frodo.douban.com"
	// DefaultFrodoKey and DefaultFrodoSecret are a recognized Frodo app key pair.
	// They can be overridden via FrodoConfig (or CLI flags) if Douban rotates them.
	DefaultFrodoKey    = "0dad551ec0f84ed02907ff5c42e8ec70"
	DefaultFrodoSecret = "bf7dddc7c9cfe6f7"
	// DefaultFrodoUA is the Frodo Android client User-Agent. The host rejects
	// any request whose UA does not identify the app (it answers
	// invalid_apikey, code 1062), so this string is not cosmetic. The
	// "api-client/1 " prefix matches the form the live app sends.
	DefaultFrodoUA = "" /* 144-byte string literal not displayed */
)
View Source
const DefaultUserAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"

DefaultUserAgent is the browser-like User-Agent sent with every request.

Variables

View Source
var ErrForbidden = errors.New("douban: forbidden")

ErrForbidden is returned for a 403, which on Douban means a wall (login-gated or anti-bot) rather than a transient error. Callers record it as blocked so it is not retried like a recoverable failure.

View Source
var ErrNotFound = errors.New("douban: not found")

ErrNotFound is returned when Douban has no subject, list, or page for an id.

Functions

This section is empty.

Types

type Book added in v0.2.0

type Book struct {
	ID            string `json:"id"`
	Title         string `json:"title"`
	OriginalTitle string `json:"original_title,omitempty"`
	Author        string `json:"author,omitempty"`
	Translator    string `json:"translator,omitempty"`
	Publisher     string `json:"publisher,omitempty"`
	Producer      string `json:"producer,omitempty"`
	PubDate       string `json:"pubdate,omitempty"`
	Pages         string `json:"pages,omitempty"`
	Price         string `json:"price,omitempty"`
	Binding       string `json:"binding,omitempty"`
	Series        string `json:"series,omitempty"`
	ISBN          string `json:"isbn,omitempty"`
	Rating        string `json:"rating"`
	Summary       string `json:"summary,omitempty"`
	URL           string `json:"url"`
	Cover         string `json:"cover,omitempty"`
}

Book is the full record for one book subject.

type Client

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

Client talks to Douban's public web surfaces.

func NewClient

func NewClient(cfg Config) *Client

NewClient returns a Client configured with cfg.

func (*Client) Book added in v0.2.0

func (c *Client) Book(ctx context.Context, idOrURL string) (*Book, error)

Book fetches the full record for one book subject. The argument may be a bare id or a pasted book.douban.com URL.

func (*Client) Chart added in v0.2.0

func (c *Client) Chart(ctx context.Context) ([]Movie, error)

Chart returns the current Douban film ranking board (/chart).

func (*Client) Doulist added in v0.2.0

func (c *Client) Doulist(ctx context.Context, idOrURL string, limit int) ([]DoulistItem, error)

Doulist returns the subjects in a curated list (豆列) in list order. The argument may be a bare id or a pasted www.douban.com/doulist URL. It walks the paged ?start= listing until limit items are collected (default 100).

func (*Client) Get added in v0.2.0

func (c *Client) Get(ctx context.Context, rawURL string) ([]byte, error)

Get fetches a URL and returns the body, pacing and retrying as configured. It is the exported entry point used by the mirror crawler to fetch arbitrary Douban URLs (sitemaps, subject pages); the lookup commands use the typed helpers built on the same internal get.

func (*Client) NowPlaying added in v0.2.0

func (c *Client) NowPlaying(ctx context.Context, city string, coming bool, limit int) ([]Movie, error)

NowPlaying returns the films in cinemas now for a city (default beijing). When coming is true it returns the upcoming list from the same page instead.

func (*Client) Search

func (c *Client) Search(ctx context.Context, query, searchType string, limit int) ([]Result, error)

Search fetches Douban subject-search results for query and searchType. searchType must be one of "book", "movie", or "music". Up to limit results are returned; pass 0 to use a reasonable default (15).

func (*Client) Suggest added in v0.2.0

func (c *Client) Suggest(ctx context.Context, query, suggestType string, limit int) ([]Suggestion, error)

Suggest queries Douban's j/subject_suggest typeahead. suggestType selects the catalog ("movie" or "book"); movie is the reliable way to resolve a film id, since movie subject pages are sealed. Up to limit results are returned.

func (*Client) Top250 added in v0.2.0

func (c *Client) Top250(ctx context.Context, limit int) ([]Movie, error)

Top250 returns the Douban Top 250 films in rank order. It walks the paged ?start= listing until limit rows are collected (default and maximum 250).

type Config

type Config struct {
	// BaseURL overrides the host for tests. When empty the client talks to the
	// real https://<sub>.douban.com subdomains; when set, every host resolves to
	// this single base and is dispatched by path.
	BaseURL   string
	UserAgent string
	Rate      time.Duration
	Timeout   time.Duration
	Retries   int
}

Config holds constructor parameters.

func DefaultConfig

func DefaultConfig() Config

DefaultConfig returns sensible defaults.

type DoulistItem added in v0.2.0

type DoulistItem struct {
	Rank     int    `json:"rank"`
	ID       string `json:"id"`
	Title    string `json:"title"`
	Rating   string `json:"rating"`
	Abstract string `json:"abstract,omitempty"`
	URL      string `json:"url"`
	Cover    string `json:"cover,omitempty"`
}

DoulistItem is one subject in a curated list.

type FrodoClient added in v0.2.0

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

FrodoClient calls the signed Frodo API.

func NewFrodoClient added in v0.2.0

func NewFrodoClient(cfg FrodoConfig) *FrodoClient

NewFrodoClient returns a FrodoClient. Empty config fields fall back to the DefaultFrodoConfig values.

func (*FrodoClient) Book added in v0.2.0

func (f *FrodoClient) Book(ctx context.Context, id string) ([]byte, error)

func (*FrodoClient) Celebrities added in v0.2.0

func (f *FrodoClient) Celebrities(ctx context.Context, id string) ([]byte, error)

Celebrities returns the directors/actors credit list for a movie.

func (*FrodoClient) Game added in v0.2.0

func (f *FrodoClient) Game(ctx context.Context, id string) ([]byte, error)

func (*FrodoClient) Get added in v0.2.0

func (f *FrodoClient) Get(ctx context.Context, path string, params url.Values) ([]byte, error)

Get fetches a signed API path and returns the raw JSON body. It paces and retries transient failures; a 404 maps to ErrNotFound and an API error envelope to *FrodoError.

func (*FrodoClient) Interests added in v0.2.0

func (f *FrodoClient) Interests(ctx context.Context, typ, id string, start, count int) ([]byte, error)

Interests returns the public per-user ratings and short comments for a subject.

func (*FrodoClient) Movie added in v0.2.0

func (f *FrodoClient) Movie(ctx context.Context, id string) ([]byte, error)

Movie, Book, Music, Game fetch a subject detail of that type.

func (*FrodoClient) Music added in v0.2.0

func (f *FrodoClient) Music(ctx context.Context, id string) ([]byte, error)

func (*FrodoClient) Personage added in v0.2.0

func (f *FrodoClient) Personage(ctx context.Context, id string) ([]byte, error)

Personage fetches the rich celebrity/personage profile (elessar subject).

func (*FrodoClient) Photos added in v0.2.0

func (f *FrodoClient) Photos(ctx context.Context, typ, id string, start, count int) ([]byte, error)

Photos returns the photo gallery for a subject.

func (*FrodoClient) Rating added in v0.2.0

func (f *FrodoClient) Rating(ctx context.Context, typ, id string) ([]byte, error)

Rating returns the rating breakdown (star distribution, wish/doing/done) for a subject.

func (*FrodoClient) Reviews added in v0.2.0

func (f *FrodoClient) Reviews(ctx context.Context, typ, id string, start, count int) ([]byte, error)

Reviews returns the long reviews for a subject.

func (*FrodoClient) SearchSubjects added in v0.2.0

func (f *FrodoClient) SearchSubjects(ctx context.Context, q string, start, count int) ([]byte, error)

SearchSubjects searches across subjects; filter results by item.target_type.

func (*FrodoClient) Subject added in v0.2.0

func (f *FrodoClient) Subject(ctx context.Context, typ, id string) ([]byte, error)

Subject fetches a subject of the given Frodo type ("movie", "book", "music", "game"). Movie covers TV as well.

func (*FrodoClient) UserAgent added in v0.2.0

func (f *FrodoClient) UserAgent() string

UserAgent returns the User-Agent the client sends. Frodo rejects requests that do not identify the app, so this must remain an app UA.

type FrodoConfig added in v0.2.0

type FrodoConfig struct {
	// BaseURL overrides the API origin for tests. Empty means DefaultFrodoBase.
	BaseURL   string
	APIKey    string
	Secret    string
	UserAgent string
	Rate      time.Duration
	Timeout   time.Duration
	Retries   int
}

FrodoConfig configures a FrodoClient.

func DefaultFrodoConfig added in v0.2.0

func DefaultFrodoConfig() FrodoConfig

DefaultFrodoConfig returns a working configuration. The Frodo host tolerates a faster pace than the web hosts, so Rate defaults below the web Crawl-delay.

type FrodoError added in v0.2.0

type FrodoError struct {
	Status    int    `json:"-"`
	Code      int    `json:"code"`
	Request   string `json:"request"`
	Msg       string `json:"msg"`
	Localized string `json:"localized_message"`
}

FrodoError is the API's error envelope: a JSON body carrying a numeric code, e.g. 996 (signature error), 997 (unknown apikey), 1062 (rate limited).

func (*FrodoError) Error added in v0.2.0

func (e *FrodoError) Error() string

type Movie added in v0.2.0

type Movie struct {
	Rank      int    `json:"rank,omitempty"`
	ID        string `json:"id"`
	Title     string `json:"title"`
	AKA       string `json:"aka,omitempty"`
	Year      string `json:"year,omitempty"`
	Region    string `json:"region,omitempty"`
	Genres    string `json:"genres,omitempty"`
	Directors string `json:"directors,omitempty"`
	Cast      string `json:"cast,omitempty"`
	Duration  string `json:"duration,omitempty"`
	Rating    string `json:"rating"`
	URL       string `json:"url"`
	Cover     string `json:"cover,omitempty"`
	Quote     string `json:"quote,omitempty"`
}

Movie is a unified film record; fields a given surface does not carry are omitted from output.

type Result

type Result struct {
	Rank     int    `json:"rank"`
	ID       string `json:"id"`
	Type     string `json:"type"`
	Title    string `json:"title"`
	Rating   string `json:"rating"`
	Abstract string `json:"abstract"`
	URL      string `json:"url"`
	Cover    string `json:"cover,omitempty"`
}

Result is the record emitted for every search hit.

type Suggestion added in v0.2.0

type Suggestion struct {
	ID       string `json:"id"`
	Type     string `json:"type"`
	Title    string `json:"title"`
	SubTitle string `json:"sub_title,omitempty"`
	Year     string `json:"year,omitempty"`
	URL      string `json:"url"`
	Img      string `json:"img,omitempty"`
}

Suggestion is the record emitted for every suggest hit.

Jump to

Keyboard shortcuts

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