Documentation ¶
Index ¶
- Constants
- Variables
- func CategorySearchURL(opts ...CategorySearchOption) (ret url.URL)
- func ParseCount(v string) (uint64, error)
- func ParseSelectionCount(doc *goquery.Selection) (ret uint64, err error)
- func ParseTime(s string) (time.Time, error)
- func RankURL(rt RankType, opts ...RankOption) (ret url.URL)
- type Book
- type Category
- type CategorySearchOption
- func CategorySearchOptionCategory(v Category) CategorySearchOption
- func CategorySearchOptionPage(v int) CategorySearchOption
- func CategorySearchOptionSign(v Sign) CategorySearchOption
- func CategorySearchOptionSize(v Size) CategorySearchOption
- func CategorySearchOptionSort(v Sort) CategorySearchOption
- func CategorySearchOptionState(v State) CategorySearchOption
- func CategorySearchOptionSubCategory(v SubCategory) CategorySearchOption
- func CategorySearchOptionTag(v string) CategorySearchOption
- func CategorySearchOptionUpdate(v Update) CategorySearchOption
- func CategorySearchOptionVIP(v VIP) CategorySearchOption
- type CategorySearchOptions
- type CategorySearchResult
- type ColumnParser
- type ColumnParserFunc
- type RankOption
- type RankOptions
- type RankResult
- type RankType
- type Sign
- type Size
- type Sort
- type State
- type SubCategory
- type Update
- type VIP
Constants ¶
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 ¶
var ( SC青春日常 = SC恋爱日常 SC青春日常mm = SC恋爱日常mm SC黑暗幻想 = SC神秘幻想 )
Deprecated: these categories has been renamed
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
var DefaultColumnParser = ColumnParserFunc(defaultColumnParser)
DefaultColumnParser handler common column
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 ¶
ParseCount that may contains "万" or thousand period.
func ParseSelectionCount ¶
ParseSelectionCount that may obfuscated by font.
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
type Category ¶
type Category string
func CategoryByName ¶
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 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