book

package
v0.3.2 Latest Latest
Warning

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

Go to latest
Published: Jul 9, 2022 License: MIT Imports: 17 Imported by: 0

Documentation

Index

Constants

View Source
const (
	C全部      Category    = "-1"
	C奇幻      Category    = "1"
	C悬疑      Category    = "10"
	C轻小说     Category    = "12"
	C现实      Category    = "15"
	C武侠      Category    = "2"
	C短篇      Category    = "20076"
	C诸天无限    Category    = "20109"
	C玄幻      Category    = "21"
	C仙侠      Category    = "22"
	C短篇mm    Category    = "30083"
	C现实生活mm  Category    = "30120"
	C都市      Category    = "4"
	C历史      Category    = "5"
	C军事      Category    = "6"
	C游戏      Category    = "7"
	C体育      Category    = "8"
	C古代言情mm  Category    = "80"
	C仙侠奇缘mm  Category    = "81"
	C现代言情mm  Category    = "82"
	C浪漫青春mm  Category    = "83"
	C玄幻言情mm  Category    = "84"
	C悬疑推理mm  Category    = "85"
	C科幻空间mm  Category    = "86"
	C轻小说mm   Category    = "87"
	C游戏竞技mm  Category    = "88"
	C科幻      Category    = "9"
	SC都市生活   SubCategory = "12"
	SC青春校园   SubCategory = "130"
	SC娱乐明星   SubCategory = "151"
	SC商战职场   SubCategory = "153"
	SC都市异能   SubCategory = "16"
	SC修真文明   SubCategory = "18"
	SC影视剧本   SubCategory = "20075"
	SC评论文集   SubCategory = "20077"
	SC生活随笔   SubCategory = "20078"
	SC美文游记   SubCategory = "20079"
	SC历史神话   SubCategory = "20092"
	SC另类幻想   SubCategory = "20093"
	SC民间传说   SubCategory = "20094"
	SC古今传奇   SubCategory = "20095"
	SC短篇小说   SubCategory = "20096"
	SC诗歌散文   SubCategory = "20097"
	SC人物传记   SubCategory = "20098"
	SC古武未来   SubCategory = "20099"
	SC史诗奇幻   SubCategory = "201"
	SC武侠同人   SubCategory = "20100"
	SC古典仙侠   SubCategory = "20101"
	SC游戏系统   SubCategory = "20102"
	SC游戏主播   SubCategory = "20103"
	SC社会乡土   SubCategory = "20104"
	SC生活时尚   SubCategory = "20105"
	SC文学艺术   SubCategory = "20106"
	SC成功励志   SubCategory = "20107"
	SC青春文学   SubCategory = "20108"
	SC无限     SubCategory = "20110"
	SC诸天     SubCategory = "20111"
	SC综漫     SubCategory = "20112"
	SC神秘幻想   SubCategory = "202"
	SC国术无双   SubCategory = "206"
	SC神话修真   SubCategory = "207"
	SC现实百态   SubCategory = "209"
	SC古武机甲   SubCategory = "21"
	SC架空历史   SubCategory = "22"
	SC上古先秦   SubCategory = "220"
	SC两晋隋唐   SubCategory = "222"
	SC五代十国   SubCategory = "223"
	SC两宋元明   SubCategory = "224"
	SC清史民国   SubCategory = "225"
	SC外国历史   SubCategory = "226"
	SC抗战烽火   SubCategory = "230"
	SC谍战特工   SubCategory = "231"
	SC游戏异界   SubCategory = "240"
	SC未来世界   SubCategory = "25"
	SC超级科技   SubCategory = "250"
	SC时空穿梭   SubCategory = "251"
	SC进化变异   SubCategory = "252"
	SC末世危机   SubCategory = "253"
	SC诡秘悬疑   SubCategory = "26"
	SC探险生存   SubCategory = "260"
	SC篮球运动   SubCategory = "28"
	SC衍生同人   SubCategory = "281"
	SC搞笑吐槽   SubCategory = "282"
	SC武侠幻想   SubCategory = "30"
	SC短篇小说mm SubCategory = "30089"
	SC异能超术mm SubCategory = "30092"
	SC仙侣奇缘mm SubCategory = "30093"
	SC西方时空mm SubCategory = "30094"
	SC清穿民国mm SubCategory = "30095"
	SC上古蛮荒mm SubCategory = "30096"
	SC热血江湖mm SubCategory = "30097"
	SC异国情缘mm SubCategory = "30098"
	SC幽情奇缘mm SubCategory = "30099"
	SC同人衍生mm SubCategory = "30100"
	SC唯美幻想mm SubCategory = "30101"
	SC萌系变身mm SubCategory = "30102"
	SC恋爱日常mm SubCategory = "30103"
	SC搞笑吐槽mm SubCategory = "30104"
	SC古典衍生mm SubCategory = "30105"
	SC影视衍生mm SubCategory = "30106"
	SC动漫衍生mm SubCategory = "30107"
	SC其他衍生mm SubCategory = "30108"
	SC家与情感mm SubCategory = "30121"
	SC行业人生mm SubCategory = "30122"
	SC探索科幻mm SubCategory = "30123"
	SC人文博览mm SubCategory = "30124"
	SC历史传记   SubCategory = "32"
	SC奇妙世界   SubCategory = "35"
	SC现代魔法   SubCategory = "38"
	SC幻想修仙   SubCategory = "44"
	SC秦汉三国   SubCategory = "48"
	SC传统武侠   SubCategory = "5"
	SC军旅生涯   SubCategory = "54"
	SC体育赛事   SubCategory = "55"
	SC侦探推理   SubCategory = "57"
	SC王朝争霸   SubCategory = "58"
	SC爱情婚姻   SubCategory = "6"
	SC原生幻想   SubCategory = "60"
	SC剑与魔法   SubCategory = "62"
	SC现代修真   SubCategory = "64"
	SC军事战争   SubCategory = "65"
	SC恋爱日常   SubCategory = "66"
	SC星际文明   SubCategory = "68"
	SC电子竞技   SubCategory = "7"
	SC虚拟网游   SubCategory = "70"
	SC异世大陆   SubCategory = "73"
	SC异术超能   SubCategory = "74"
	SC高武世界   SubCategory = "78"
	SC东方玄幻   SubCategory = "8"
	SC战争幻想   SubCategory = "80"
	SC古代情缘mm SubCategory = "801"
	SC宫闱宅斗mm SubCategory = "802"
	SC经商种田mm SubCategory = "803"
	SC古典架空mm SubCategory = "804"
	SC女尊王朝mm SubCategory = "805"
	SC穿越奇情mm SubCategory = "806"
	SC武侠情缘mm SubCategory = "810"
	SC古典仙侠mm SubCategory = "811"
	SC现代修真mm SubCategory = "812"
	SC远古洪荒mm SubCategory = "813"
	SC足球运动   SubCategory = "82"
	SC商战职场mm SubCategory = "821"
	SC豪门世家mm SubCategory = "822"
	SC都市生活mm SubCategory = "823"
	SC婚恋情缘mm SubCategory = "824"
	SC娱乐明星mm SubCategory = "825"
	SC都市异能mm SubCategory = "827"
	SC极道江湖mm SubCategory = "828"
	SC民国情缘mm SubCategory = "829"
	SC青春校园mm SubCategory = "831"
	SC青春疼痛mm SubCategory = "832"
	SC叛逆成长mm SubCategory = "833"
	SC青春纯爱mm SubCategory = "834"
	SC东方玄幻mm SubCategory = "841"
	SC异世大陆mm SubCategory = "844"
	SC西方奇幻mm SubCategory = "846"
	SC远古神话mm SubCategory = "847"
	SC异族恋情mm SubCategory = "848"
	SC魔法幻情mm SubCategory = "849"
	SC推理侦探mm SubCategory = "850"
	SC诡秘惊险mm SubCategory = "851"
	SC悬疑探险mm SubCategory = "852"
	SC奇妙世界mm SubCategory = "853"
	SC神秘文化mm SubCategory = "854"
	SC未来世界mm SubCategory = "862"
	SC进化变异mm SubCategory = "863"
	SC星际恋歌mm SubCategory = "864"
	SC时空穿梭mm SubCategory = "866"
	SC古武机甲mm SubCategory = "867"
	SC超级科技mm SubCategory = "868"
	SC末世危机mm SubCategory = "869"
	SC电子竞技mm SubCategory = "880"
	SC网游情缘mm SubCategory = "881"
	SC游戏异界mm SubCategory = "882"
	SC体育竞技mm SubCategory = "883"
)

Variables

View Source
var (
	SC青春日常   = SC恋爱日常
	SC青春日常mm = SC恋爱日常mm
	SC黑暗幻想   = SC神秘幻想
)

Deprecated: these categories has been renamed

View Source
var (
	// support query by year and month after 2020-01.
	RTMonthlyTicket = RankType{
		URL: httpsURL("/rank/yuepiao/"),
		ColumnParser: ColumnParserFunc(func(book *Book, i int, th, td *goquery.Selection) (err error) {
			switch strings.TrimSpace(th.Text()) {
			case "":
				book.MonthTicketCount, err = ParseSelectionCount(td)
			default:
				err = DefaultColumnParser.ParseColumn(book, i, th, td)
			}
			return
		}),
	}
	// support query by year and month after 2020-01.
	RTMonthlyTicketVIP = RankType{
		URL: httpsURL("/rank/fengyun/"),
		ColumnParser: ColumnParserFunc(func(book *Book, i int, th, td *goquery.Selection) (err error) {
			switch strings.TrimSpace(th.Text()) {
			case "月票榜", "起点月票榜":
				book.MonthTicketCount, err = ParseSelectionCount(td)
			default:
				err = DefaultColumnParser.ParseColumn(book, i, th, td)
			}
			return
		}),
	}
	// support query by year and month after 2020-01.
	RTMonthlyTicketMM = RankType{
		URL:          httpsURL("/rank/mm/yuepiao/"),
		ColumnParser: RTMonthlyTicketVIP.ColumnParser,
		Site:         "mm",
	}
	RTNewBookSalesMM = RankType{
		URL:  httpsURL("/rank/mm/newsales/"),
		Site: "mm",
	}
	RTDailySales = RankType{
		URL: httpsURL("/rank/hotsales/"),
	}
	RTDailySalesMM = RankType{
		URL:  httpsURL("/rank/mm/hotsales/"),
		Site: "mm",
	}
	RTWeeklyRead = RankType{
		URL: httpsURL("/rank/readindex/"),
	}
	RTWeeklyReadMM = RankType{
		URL:  httpsURL("/rank/mm/readindex/"),
		Site: "mm",
	}
	RTWeeklyRecommendation = RankType{
		URL: httpsURL("/rank/recom/"),
		ColumnParser: ColumnParserFunc(func(book *Book, i int, th, td *goquery.Selection) (err error) {
			switch column := strings.TrimSpace(th.Text()); column {
			case "推荐":
				book.WeekRecommendCount, err = ParseSelectionCount(td)
			default:
				err = DefaultColumnParser.ParseColumn(book, i, th, td)
			}
			return
		}),
	}
	RTWeeklyRecommendationMM = RankType{
		URL:          httpsURL("/rank/mm/recom/"),
		ColumnParser: RTWeeklyRecommendation.ColumnParser,
		Site:         "mm",
	}
	RTMonthlyRecommendation = RankType{
		URL: httpsURL("/rank/recom/datatype2/"),
		ColumnParser: ColumnParserFunc(func(book *Book, i int, th, td *goquery.Selection) (err error) {
			switch strings.TrimSpace(th.Text()) {
			case "推荐":
				book.MonthRecommendCount, err = ParseSelectionCount(td)
			default:
				err = DefaultColumnParser.ParseColumn(book, i, th, td)
			}
			return
		}),
	}
	RTMonthlyRecommendationMM = RankType{
		URL:          httpsURL("/rank/mm/recom/datatype2/"),
		ColumnParser: RTMonthlyRecommendation.ColumnParser,
		Site:         "mm",
	}
	RTTotalRecommendation = RankType{
		URL: httpsURL("/rank/recom/datatype3/"),
		ColumnParser: ColumnParserFunc(func(book *Book, i int, th, td *goquery.Selection) (err error) {
			switch strings.TrimSpace(th.Text()) {
			case "推荐":
				book.TotalRecommendCount, err = ParseSelectionCount(td)
			default:
				err = DefaultColumnParser.ParseColumn(book, i, th, td)
			}
			return
		}),
	}
	RTTotalRecommendationMM = RankType{
		URL:          httpsURL("/rank/mm/recom/datatype3/"),
		ColumnParser: RTTotalRecommendation.ColumnParser,
		Site:         "mm",
	}
	RTTotalBookmark = RankType{
		URL: httpsURL("/rank/collect/"),
	}
	RTTotalBookmarkMM = RankType{
		URL:  httpsURL("/rank/mm/collect/"),
		Site: "mm",
	}
	RTSignedAuthorNewBook = RankType{
		URL: httpsURL("/rank/signnewbook/"),
	}
	RTSignedAuthorNewBookMM = RankType{
		URL:  httpsURL("/rank/mm/signnewbook/"),
		Site: "mm",
	}
	RTPublicAuthorNewBook = RankType{
		URL: httpsURL("/rank/pubnewbook/"),
	}
	RTPublicAuthorNewBookMM = RankType{
		URL:  httpsURL("/rank/mm/pubnewbook/"),
		Site: "mm",
	}
	RTNewSignedAuthorNewBook = RankType{
		URL: httpsURL("/rank/newsign/"),
	}
	RTNewSignedAuthorNewBookMM = RankType{
		URL:  httpsURL("/rank/mm/newsign/"),
		Site: "mm",
	}
	RTNewAuthorNewBook = RankType{
		URL: httpsURL("/rank/newauthor/"),
	}
	RTNewAuthorNewBookMM = RankType{
		URL:  httpsURL("/rank/mm/newauthor/"),
		Site: "mm",
	}
	RTWeeklyFans = RankType{
		URL: httpsURL("/rank/newfans/"),
	}
	RTWeeklyFansMM = RankType{
		URL:  httpsURL("/rank/mm/newfans/"),
		Site: "mm",
	}
	RTLastUpdatedVIP = RankType{
		URL: httpsURL("/rank/vipup/"),
	}
	RTDailyMostUpdateVIPMM = RankType{
		URL:  httpsURL("/rank/mm/vipup/"),
		Site: "mm",
	}
	RTWeeklyMostUpdateVIPMM = RankType{
		URL:  httpsURL("/rank/mm/vipup/datatype2/"),
		Site: "mm",
	}
	RTMonthlyMostUpdateVIPMM = RankType{
		URL:  httpsURL("/rank/mm/vipup/datatype3/"),
		Site: "mm",
	}
	RTTotalWordCountMM = RankType{
		URL:  httpsURL("/rank/mm/wordcount/"),
		Site: "mm",
	}
	RTTotalBookmarkVIP = RankType{
		URL: httpsURL("/rank/vipcollect/"),
	}
	RTWeeklyRewardVIP = RankType{
		URL: httpsURL("/rank/vipreward/"),
	}
	RTWeeklySingleChapterSalesMM = RankType{
		URL:  httpsURL("/rank/mm/subscr/"),
		Site: "mm",
	}
	RTTotalSingleChapterSalesVIPMM = RankType{
		URL:  httpsURL("/rank/mm/vipsub/"),
		Site: "mm",
	}
)

Rank types

View Source
var DefaultColumnParser = ColumnParserFunc(defaultColumnParser)

DefaultColumnParser handler common column

View Source
var TZ = time.FixedZone("CST", 8*60*60)

TZ is timezone used to parse timezone, defaults to china standard time.

Functions

func CategorySearchURL added in v0.2.0

func CategorySearchURL(opts ...CategorySearchOption) (ret url.URL)

func ParseCount

func ParseCount(v string) (uint64, error)

ParseCount that may contains "万" or thousand period.

func ParseSelectionCount

func ParseSelectionCount(doc *goquery.Selection) (ret uint64, err error)

ParseSelectionCount that may obfuscated by font.

func ParseTime

func ParseTime(s string) (time.Time, error)

ParseTime for any format that qidian used on their web page.

func RankURL added in v0.2.0

func RankURL(rt RankType, opts ...RankOption) (ret url.URL)

Types

type Book

type Book struct {
	ID string
	// "" for main site,  "mm" for female site
	Site     string
	Title    string
	Author   author.Author
	CoverURL string
	// short description
	Summary string
	// long description
	Introduction string
	Category     Category
	SubCategory  SubCategory
	Tags         []string
	LastUpdated  time.Time
	Finished     time.Time
	WordCount    uint64
	// only available when search by bookmark
	BookmarkCount       uint64
	MonthTicketCount    uint64
	WeekRecommendCount  uint64
	MonthRecommendCount uint64
	TotalRecommendCount uint64
}

Book model

func (*Book) Fetch

func (b *Book) Fetch(ctx context.Context) (err error)

Fetch book from info page.

func (Book) URL

func (b Book) URL() string

URL of book info page on website.

type Category

type Category string

func CategoryByName

func CategoryByName(name, site string) Category

func (Category) Site

func (c Category) Site() string

Site for this category, "" for main site, "mm" for female site.

func (Category) String

func (c Category) String() string

type CategorySearchOption added in v0.2.0

type CategorySearchOption = func(o *CategorySearchOptions)

func CategorySearchOptionCategory added in v0.2.0

func CategorySearchOptionCategory(v Category) CategorySearchOption

func CategorySearchOptionPage added in v0.2.0

func CategorySearchOptionPage(v int) CategorySearchOption

func CategorySearchOptionSign added in v0.2.0

func CategorySearchOptionSign(v Sign) CategorySearchOption

func CategorySearchOptionSize added in v0.2.0

func CategorySearchOptionSize(v Size) CategorySearchOption

func CategorySearchOptionSort added in v0.2.0

func CategorySearchOptionSort(v Sort) CategorySearchOption

func CategorySearchOptionState added in v0.2.0

func CategorySearchOptionState(v State) CategorySearchOption

func CategorySearchOptionSubCategory added in v0.2.0

func CategorySearchOptionSubCategory(v SubCategory) CategorySearchOption

func CategorySearchOptionTag added in v0.2.0

func CategorySearchOptionTag(v string) CategorySearchOption

func CategorySearchOptionUpdate added in v0.2.0

func CategorySearchOptionUpdate(v Update) CategorySearchOption

func CategorySearchOptionVIP added in v0.2.0

func CategorySearchOptionVIP(v VIP) CategorySearchOption

type CategorySearchOptions added in v0.2.0

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

type CategorySearchResult added in v0.2.0

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

func CategorySearch

func CategorySearch(ctx context.Context, opts ...CategorySearchOption) (ret CategorySearchResult, err error)

CategorySearch use https://www.qidian.com/all page

func (CategorySearchResult) Books added in v0.2.0

func (r CategorySearchResult) Books() (ret []Book, err error)

func (CategorySearchResult) Site added in v0.2.0

func (obj CategorySearchResult) Site() string

type ColumnParser

type ColumnParser interface {
	// Parse title to a column data type
	ParseColumn(book *Book, index int, th *goquery.Selection, td *goquery.Selection) error
}

ColumnParser parse data type from column title.

type ColumnParserFunc

type ColumnParserFunc func(book *Book, index int, th *goquery.Selection, td *goquery.Selection) error

ColumnParserFunc implements ColumnParser from a function.

func (ColumnParserFunc) ParseColumn

func (f ColumnParserFunc) ParseColumn(book *Book, index int, th *goquery.Selection, td *goquery.Selection) error

ParseColumn implements ColumnParser

type RankOption added in v0.2.0

type RankOption = func(o *RankOptions)

func RankOptionCategory added in v0.2.0

func RankOptionCategory(v Category) RankOption

func RankOptionMonth added in v0.2.0

func RankOptionMonth(month time.Month) RankOption

RankOptionMonth set rank period, not all rank support this.

func RankOptionPage added in v0.2.0

func RankOptionPage(page int) RankOption

RankOptionPage set wanted page, start from 1.

func RankOptionYearMonth added in v0.2.0

func RankOptionYearMonth(year int, month time.Month) RankOption

RankOptionYearMonth set rank period, not all rank support this.

type RankOptions added in v0.2.0

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

type RankResult added in v0.2.0

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

func Rank

func Rank(ctx context.Context, rt RankType, opts ...RankOption) (ret RankResult, err error)

func (RankResult) Books added in v0.2.0

func (r RankResult) Books() ([]Book, error)

func (RankResult) RankType added in v0.2.0

func (obj RankResult) RankType() RankType

type RankType

type RankType struct {
	// URL for rank page.
	URL url.URL
	// ColumnParser for result table. Defaults to DefaultColumnParser.
	ColumnParser ColumnParser
	Site         string
}

RankType that corresponding a rank page.

type Sign

type Sign string

Sign for book

const (
	// 全部作品
	SignAll Sign = ""
	// 签约作品
	SignSigned Sign = "1"
	// 精品小说
	SignChoicest Sign = "2"
)

Sign for book

type Size

type Size string

Size for book

const (
	SizeAll          Size = ""
	SizeLt300k       Size = "1"
	SizeGt300kLt500k Size = "2"
	SizeGt500kLt1m   Size = "3"
	SizeGt1mLt2m     Size = "4"
	SizeGt2m         Size = "5"
)

Size for book

type Sort

type Sort string

Sort for search

const (
	SortTotalRecommend Sort = "2"
	SortCharCount      Sort = "3"
	SortLastUpdated    Sort = "5"
	SortRecentFinished Sort = "6"
	SortWeekRecommend  Sort = "9"
	SortMonthRecommend Sort = "10"
	SortTotalBookmark  Sort = "11"
)

Sort for search

type State

type State string

State for book

const (
	StateAll      State = ""
	StateOnGoing  State = "1"
	StateFinished State = "2"
)

State for book

type SubCategory

type SubCategory string

func SubCategoryByName

func SubCategoryByName(name, site string) SubCategory

func (SubCategory) Parent

func (sc SubCategory) Parent() Category

func (SubCategory) Site

func (c SubCategory) Site() string

Site for this sub-category, "" for main site, "mm" for female site.

func (SubCategory) String

func (sc SubCategory) String() string

type Update

type Update string

Update for book

const (
	UpdateAll         Update = ""
	UpdateIn3Day      Update = "1"
	UpdateIn7Day      Update = "2"
	UpdateInHalfMonth Update = "3"
	UpdateInMonth     Update = "4"
)

Update for book

type VIP

type VIP string

VIP state for book

const (
	VIPAll   VIP = ""
	VIPFalse VIP = "1"
	VIPTrue  VIP = "2"
)

VIP state for book

Jump to

Keyboard shortcuts

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