fix search error

This commit is contained in:
HughWan 2023-12-21 13:27:16 +08:00
parent 1b5b9bb0b3
commit f0c1421f5d
11 changed files with 129 additions and 104 deletions

@ -76,38 +76,38 @@
## 支持的字段
(若有缺少想导入的字段, 欢迎提issues反馈)
| 字段 | 电影 | 电视剧 | 书籍 | 音乐 | 日记 | 游戏 | 广播 |
|------------------|-------------------|------------------|-------------------|----------------|----------------|---------------| ---- |
| id | 豆瓣ID | 豆瓣ID | 豆瓣ID | 豆瓣ID | 豆瓣ID | 豆瓣ID | - |
| title | 电影名称 | 电视剧名称 | 书名 | 音乐名 | 日记标题 | 游戏名称 | - |
| type | 类型 | 类型 | 类型 | 类型 | 类型 | 类型 | - |
| score | 评分 | 评分 | 评分 | 评分 | 评分 | 评分 | - |
| image | 封面 | 封面 | 封面 | 封面 | 图片 | 封面 | - |
| imageData.url | 封面url | 封面url | 封面url | 封面url | 封面url | 封面url | - |
| url | 豆瓣网址 | 豆瓣网址 | 豆瓣网址 | 豆瓣网址 | 豆瓣网址 | 豆瓣网址 | - |
| desc | 简介 | 简介 | 内容简介 | 简介 | 简介 | 简介 | - |
| publisher | - | - | 出版社 | 出版者 | 发布者 | 发行商 | - |
| datePublished | 上映日期 | 上映日期 | 出版年 | 发行时间 | 发布时间 | 发行日期 | - |
| yearPublished | 上映年份 | 上映年份 | 出版年份 | 发行年份 | 发布年份 | 发行年份 | - |
| genre | 类型 | 类型 | - | 流派 | - | 类型 | - |
| currentDate | 今日日期 | 今日日期 | 今日日期 | 今日日期 | 今日日期 | 今日日期 | |
| currentTime | 当前时间 | 当前时间 | 当前时间 | 当前时间 | 当前时间 | 当前时间 | |
| myTags | 我标记的标签 | 我标记的标签 | 我标记的标签 | 我标记的标签 | - | 我标记的标签 | |
| 字段 | 电影 | 电视剧 | 书籍 | 音乐 | 日记 | 游戏 | * |
|------------------|-------------------|------------------|-------------------|----------------|----------------|---------------|-------|
| id | 豆瓣ID | 豆瓣ID | 豆瓣ID | 豆瓣ID | 豆瓣ID | 豆瓣ID | id |
| title | 电影名称 | 电视剧名称 | 书名 | 音乐名 | 日记标题 | 游戏名称 | 剧名 |
| type | 类型 | 类型 | 类型 | 类型 | 类型 | 类型 | 类型 |
| score | 评分 | 评分 | 评分 | 评分 | 评分 | 评分 | 评分 |
| image | 封面 | 封面 | 封面 | 封面 | 图片 | 封面 | 封面 |
| imageData.url | 封面url | 封面url | 封面url | 封面url | 封面url | 封面url | 封面url |
| url | 豆瓣网址 | 豆瓣网址 | 豆瓣网址 | 豆瓣网址 | 豆瓣网址 | 豆瓣网址 | - |
| desc | 简介 | 简介 | 内容简介 | 简介 | 简介 | 简介 | - |
| publisher | - | - | 出版社 | 出版者 | 发布者 | 发行商 | - |
| datePublished | 上映日期 | 上映日期 | 出版年 | 发行时间 | 发布时间 | 发行日期 | - |
| yearPublished | 上映年份 | 上映年份 | 出版年份 | 发行年份 | 发布年份 | 发行年份 | - |
| genre | 类型 | 类型 | - | 流派 | - | 类型 | - |
| currentDate | 今日日期 | 今日日期 | 今日日期 | 今日日期 | 今日日期 | 今日日期 | |
| currentTime | 当前时间 | 当前时间 | 当前时间 | 当前时间 | 当前时间 | 当前时间 | |
| myTags | 我标记的标签 | 我标记的标签 | 我标记的标签 | 我标记的标签 | - | 我标记的标签 | |
| myRating | 我的评分 | 我的评分 | 我的评分 | 我的评分 | - | 我的评分 |
| myState | 状态:想看/在看/看过 | 状态:想看/在看/看过 | 状态:想看/在看/看过 | 状态:想听/在听/听过 | - | 状态:想玩/在玩/玩过 | |
| myComment | 我的评语 | 我的评语 | 我的评语 | 我的评语 | - | 我的评语 | |
| myCollectionDate | 我标记的时间 | 我标记的时间 | 我标记的时间 | 我标记的时间 | - | 我标记的时间 | |
| 扩展1 | director:导演 | director:导演 | author:原作者 | actor: 表演者 | author:作者 | aliases:别名 | |
| 扩展2 | author:编剧 | author:编剧 | translator:译者 | albumType:专辑类型 | authorUrl:作者网址 | developer:开发商 | |
| 扩展3 | actor:主演 | actor:主演 | isbn:isbn | medium:介质 | content:日记内容 | platform:平台 | |
| 扩展4 | originalTitle:原作名 | originalTitle:原作名 | originalTitle:原作名 | records:唱片数 | | | |
| 扩展5 | country:国家 | country:国家 | subTitle:副标题 | barcode:条形码 | | | |
| 扩展6 | language:语言 | language:语言 | totalPage:页数 | | | | |
| 扩展7 | time:片长 | time:片长 | series:丛书 | | | | |
| 扩展8 | aliases:又名 | aliases:又名 | menu:目录 | | | | |
| 扩展9 | IMDb | IMDb | price:定价 | | | | |
| 扩展7 | | episode:集数 | binding:装帧 | | | | |
| 扩展8 | | | producer: 出品方 | | | | |
| myState | 状态:想看/在看/看过 | 状态:想看/在看/看过 | 状态:想看/在看/看过 | 状态:想听/在听/听过 | - | 状态:想玩/在玩/玩过 | |
| myComment | 我的评语 | 我的评语 | 我的评语 | 我的评语 | - | 我的评语 | |
| myCollectionDate | 我标记的时间 | 我标记的时间 | 我标记的时间 | 我标记的时间 | - | 我标记的时间 | |
| 扩展1 | director:导演 | director:导演 | author:原作者 | actor: 表演者 | author:作者 | aliases:别名 | |
| 扩展2 | author:编剧 | author:编剧 | translator:译者 | albumType:专辑类型 | authorUrl:作者网址 | developer:开发商 | |
| 扩展3 | actor:主演 | actor:主演 | isbn:isbn | medium:介质 | content:日记内容 | platform:平台 | |
| 扩展4 | originalTitle:原作名 | originalTitle:原作名 | originalTitle:原作名 | records:唱片数 | | | |
| 扩展5 | country:国家 | country:国家 | subTitle:副标题 | barcode:条形码 | | | |
| 扩展6 | language:语言 | language:语言 | totalPage:页数 | | | | |
| 扩展7 | time:片长 | time:片长 | series:丛书 | | | | |
| 扩展8 | aliases:又名 | aliases:又名 | menu:目录 | | | | |
| 扩展9 | IMDb | IMDb | price:定价 | | | | |
| 扩展7 | | episode:集数 | binding:装帧 | | | | |
| 扩展8 | | | producer: 出品方 | | | | |
- 注: myTags, myRating, myState, myComment, myCollectionDate 参数均为在插件中登录后可用

@ -42,10 +42,10 @@ export default abstract class DoubanAbstractLoadHandler<T extends DoubanSubject>
}
async parse(extract: T, context: HandleContext): Promise<HandleResult> {
let template: string = await this.getTemplate(extract, context);
const template: string = await this.getTemplate(extract, context);
await this.saveImage(extract, context);
let frontMatterStart: number = template.indexOf(BasicConst.YAML_FRONT_MATTER_SYMBOL, 0);
let frontMatterEnd: number = template.indexOf(BasicConst.YAML_FRONT_MATTER_SYMBOL, frontMatterStart + 1);
const frontMatterStart: number = template.indexOf(BasicConst.YAML_FRONT_MATTER_SYMBOL, 0);
const frontMatterEnd: number = template.indexOf(BasicConst.YAML_FRONT_MATTER_SYMBOL, frontMatterStart + 1);
let frontMatter: string = '';
let frontMatterBefore: string = '';
let frontMatterAfter: string = '';
@ -156,7 +156,7 @@ export default abstract class DoubanAbstractLoadHandler<T extends DoubanSubject>
if (context.syncActive) {
guessType = this.getGuessType(data);
}
let sub = this.parseSubjectFromHtml(data, context);
const sub = this.parseSubjectFromHtml(data, context);
sub.userState = userState;
sub.guessType = guessType;
return sub;
@ -166,14 +166,14 @@ export default abstract class DoubanAbstractLoadHandler<T extends DoubanSubject>
.catch(e => {
log.error(i18nHelper.getMessage('130101', e.toString()), e);
if (url) {
let id = StringUtil.analyzeIdByUrl(url);
const id = StringUtil.analyzeIdByUrl(url);
context.syncStatusHolder?context.syncStatusHolder.syncStatus.fail(id, ''):null;
}else {
context.syncStatusHolder?context.syncStatusHolder.syncStatus.handled(1):null;
}
return e;
});
;
}
@ -223,7 +223,7 @@ export default abstract class DoubanAbstractLoadHandler<T extends DoubanSubject>
resultName = chineseName;
break;
case PersonNameMode.EN_NAME:
resultName = originalName.trim().replaceAll(chineseName, '').trim();
resultName = originalName.trim().replace(chineseName, '').trim();
if (!resultName) {
resultName = originalName;
}
@ -539,6 +539,7 @@ export default abstract class DoubanAbstractLoadHandler<T extends DoubanSubject>
})
}
protected getPropertyValue(html: CheerioAPI, name: PropertyName): string {
return HtmlUtil.getHtmlText(html, this.doubanPlugin.settingsManager.getSelector(this.getSupportType(), name));
}

@ -55,13 +55,13 @@ export default class DoubanBookLoadHandler extends DoubanAbstractLoadHandler<Dou
}
analysisUser(html: CheerioAPI, context: HandleContext): {data:CheerioAPI , userState: UserStateSubject} {
let rate = html('input#n_rating').val();
let tagsStr = html('span#rating').next().text().trim();
let tags = tagsStr ? tagsStr.replace('标签:', '').trim().split(' ') : null;
let stateWord = html('div#interest_sect_level > div.a_stars > span.mr10').text().trim();
let collectionDateStr = html('div#interest_sect_level > div.a_stars > span.mr10').next().text().trim();
let userState1 = DoubanAbstractLoadHandler.getUserState(stateWord);
let comment = this.getComment(html);
const rate = html('input#n_rating').val();
const tagsStr = html('span#rating').next().text().trim();
const tags = tagsStr ? tagsStr.replace('标签:', '').trim().split(' ') : null;
const stateWord = html('div#interest_sect_level > div.a_stars > span.mr10').text().trim();
const collectionDateStr = html('div#interest_sect_level > div.a_stars > span.mr10').next().text().trim();
const userState1 = DoubanAbstractLoadHandler.getUserState(stateWord);
const comment = this.getComment(html);
const userState: UserStateSubject = {
@ -76,28 +76,25 @@ export default class DoubanBookLoadHandler extends DoubanAbstractLoadHandler<Dou
parseSubjectFromHtml(html: CheerioAPI, context: HandleContext): DoubanBookSubject {
let desc = html('#link-report > span.all.hidden > div > div[class= "intro"]').html();
if (desc) {
//替换p标签 为换行符
desc = desc.replace(/<p>/g, '').replace(/<\/p>/g, '\n');
//去掉开头的换行符
desc = desc.replace(/^\n/, '');
let desc = html(".intro p").text();
if (!desc) {
desc = html(html("head > meta[property= 'og:description']").get(0)).attr("content");
}
let image = html(html("head > meta[property= 'og:image']").get(0)).attr("content");
const image = html(html("head > meta[property= 'og:image']").get(0)).attr("content");
let item = html(html("head > script[type='application/ld+json']").get(0)).text();
item = super.html_decode(item);
let obj = JSON.parse(item.replace(/[\r\n\s+]/g, ''));
let title = obj.name;
let url = obj.url;
let author = obj.author.map((a: any) => a.name);
let isbn = obj.isbn;
const obj = JSON.parse(item.replace(/[\r\n\s+]/g, ''));
const title = obj.name;
const url = obj.url;
const author = obj.author.map((a: any) => a.name);
const isbn = obj.isbn;
let score = html(html("#interest_sectl > div > div.rating_self.clearfix > strong[property= 'v:average']").get(0)).text();
let detailDom = html(html("#info").get(0));
let publish = detailDom.find("span.pl");
const score = html(html("#interest_sectl > div > div.rating_self.clearfix > strong[property= 'v:average']").get(0)).text();
const detailDom = html(html("#info").get(0));
const publish = detailDom.find("span.pl");
let valueMap = new Map<string, any>();
const valueMap = new Map<string, any>();
publish.map((index, info) => {
let key = html(info).text().trim();

@ -70,7 +70,7 @@ export default class DoubanMovieLoadHandler extends DoubanAbstractLoadHandler<Do
private getComment(html: CheerioAPI, context: HandleContext) {
let component = html('div#interest_sect_level > div.a_stars > span.color_gray').next().next().text().trim();
const component = html('div#interest_sect_level > div.a_stars > span.color_gray').next().next().text().trim();
if (component) {
return component;
}
@ -84,12 +84,12 @@ export default class DoubanMovieLoadHandler extends DoubanAbstractLoadHandler<Do
.map(i => {
let item = html(i).text();
item = super.html_decode(item);
let obj = JSON.parse(item.replace(/[\r\n\s+]/g, ''));
let idPattern = /(\d){5,10}/g;
let id = idPattern.exec(obj.url);
let name = obj.name;
let title = super.getTitleNameByMode(name, PersonNameMode.CH_NAME, context)??name;
let originalTitle = super.getTitleNameByMode(name, PersonNameMode.EN_NAME, context) ?? name;
const obj = JSON.parse(item.replace(/[\r\n+]/g, ''));
const idPattern = /(\d){5,10}/g;
const id = idPattern.exec(obj.url);
const name = obj.name;
const title = super.getTitleNameByMode(name, PersonNameMode.CH_NAME, context)??name;
const originalTitle = super.getTitleNameByMode(name, PersonNameMode.EN_NAME, context) ?? name;
const result: DoubanMovieSubject = {
id: id ? id[0] : '',
@ -119,17 +119,22 @@ export default class DoubanMovieLoadHandler extends DoubanAbstractLoadHandler<Do
this.handlePersonNameByMeta(html, movie, context, 'video:actor', 'actor');
this.handlePersonNameByMeta(html, movie, context, 'video:director', 'director');
let detailDom = html(html("#info").get(0));
let publish = detailDom.find("span.pl");
const desc:string = html("span[property='v:summary']").text();
if (desc) {
movie.desc = desc;
}
let valueMap = new Map<string, any>();
const detailDom = html(html("#info").get(0));
const publish = detailDom.find("span.pl");
const valueMap = new Map<string, any>();
publish.map((index, info) => {
let key = html(info).text().trim();
const key = html(info).text().trim();
let value;
if (key.indexOf('又名') >= 0 || key.indexOf('语言') >= 0 || key.indexOf('制片国家') >= 0) {
// value = html(info.next.next).text().trim();
let vas = html(info.next).text().trim();
const vas = html(info.next).text().trim();
value = vas.split("/").map((v) => v.trim());
} else if(key.indexOf('片长') >= 0) {
value = html(info.next.next).text().trim()

@ -42,13 +42,13 @@ export default class DoubanMusicLoadHandler extends DoubanAbstractLoadHandler<Do
}
analysisUser(html: CheerioAPI, context: HandleContext): {data:CheerioAPI , userState: UserStateSubject} {
let rate = html('input#n_rating').val();
let tagsStr = html('span#rating').next().next().text().trim();
let tags = tagsStr ? tagsStr.replace('标签:', '').trim().split(' ') : null;
let stateWord = html('div#interest_sect_level > div.a_stars > span.mr10').text().trim();
let collectionDateStr = html('div#interest_sect_level > div.a_stars > span.mr10').next().text().trim();
let userState1 = DoubanAbstractLoadHandler.getUserState(stateWord);
let component = html('span#rating').next().next().next().next().text().trim();
const rate = html('input#n_rating').val();
const tagsStr = html('span#rating').next().next().text().trim();
const tags = tagsStr ? tagsStr.replace('标签:', '').trim().split(' ') : null;
const stateWord = html('div#interest_sect_level > div.a_stars > span.mr10').text().trim();
const collectionDateStr = html('div#interest_sect_level > div.a_stars > span.mr10').next().text().trim();
const userState1 = DoubanAbstractLoadHandler.getUserState(stateWord);
const component = html('span#rating').next().next().next().next().text().trim();
const userState: UserStateSubject = {
tags: tags,
@ -61,15 +61,22 @@ export default class DoubanMusicLoadHandler extends DoubanAbstractLoadHandler<Do
}
parseSubjectFromHtml(html: CheerioAPI, context: HandleContext): DoubanMusicSubject {
let title = html(html("head > meta[property= 'og:title']").get(0)).attr("content");
let desc = html(html("head > meta[property= 'og:description']").get(0)).attr("content");
let url = html(html("head > meta[property= 'og:url']").get(0)).attr("content");
let image = html(html("head > meta[property= 'og:image']").get(0)).attr("content");
let score = html(html("#interest_sectl > div > div.rating_self.clearfix > strong[property= 'v:average']").get(0)).text();
let detailDom = html(html("#info").get(0));
let publish = detailDom.find("span.pl");
const title = html(html("head > meta[property= 'og:title']").get(0)).attr("content");
let desc:string = html("span.all.hidden").text();
if (!desc) {
desc = html("span[property='v:summary']").text();
}
if (!desc) {
desc = html(html("head > meta[property= 'og:description']").get(0)).attr("content");
}
let valueMap = new Map<string, string>();
const url = html(html("head > meta[property= 'og:url']").get(0)).attr("content");
const image = html(html("head > meta[property= 'og:image']").get(0)).attr("content");
const score = html(html("#interest_sectl > div > div.rating_self.clearfix > strong[property= 'v:average']").get(0)).text();
const detailDom = html(html("#info").get(0));
const publish = detailDom.find("span.pl");
const valueMap = new Map<string, string>();
publish.map((index, info) => {
let key = html(info).text().trim();
@ -106,6 +113,9 @@ export default class DoubanMusicLoadHandler extends DoubanAbstractLoadHandler<Do
medium: valueMap.has('medium') ? valueMap.get('medium') : "",
barcode: valueMap.has('barcode') ? valueMap.get('barcode') : ""
};
return result;
}

@ -49,11 +49,10 @@ export class DoubanSearchChooseItemHandler {
}
public async parseText(extract: DoubanSubject, context: HandleContext): Promise<HandleResult> {
let doubanSubjectHandlers: DoubanSubjectLoadHandler<DoubanSubject>[] = this._doubanSubjectHandlers
const doubanSubjectHandlers: DoubanSubjectLoadHandler<DoubanSubject>[] = this._doubanSubjectHandlers
.filter(h => h.support(extract));
let result:string='';
if (doubanSubjectHandlers && doubanSubjectHandlers.length > 0) {
let result = await doubanSubjectHandlers.map(h => h.parse(extract, context));
const result = await doubanSubjectHandlers.map(h => h.parse(extract, context));
if (result && result.length > 0) {
return result[0];
} else {

@ -78,12 +78,12 @@ export class DoubanTeleplayLoadHandler extends DoubanAbstractLoadHandler<DoubanT
.map(i => {
let item = html(i).text();
item = super.html_decode(item);
let obj = JSON.parse(item.replace(/[\r\n\s+]/g, ''));
let idPattern = /(\d){5,10}/g;
let id = idPattern.exec(obj.url);
let name = obj.name;
let title = super.getTitleNameByMode(name, PersonNameMode.CH_NAME, context)??name;
let originalTitle = super.getTitleNameByMode(name, PersonNameMode.EN_NAME, context) ?? name;
const obj = JSON.parse(item.replace(/[\r\n\s+]/g, ''));
const idPattern = /(\d){5,10}/g;
const id = idPattern.exec(obj.url);
const name = obj.name;
const title = super.getTitleNameByMode(name, PersonNameMode.CH_NAME, context)??name;
const originalTitle = super.getTitleNameByMode(name, PersonNameMode.EN_NAME, context) ?? name;
const result: DoubanTeleplaySubject = {
id: id ? id[0] : '',
@ -114,19 +114,22 @@ export class DoubanTeleplayLoadHandler extends DoubanAbstractLoadHandler<DoubanT
this.handlePersonNameByMeta(html, teleplay, context, 'video:actor', 'actor');
this.handlePersonNameByMeta(html, teleplay, context, 'video:director', 'director');
const desc:string = html("span[property='v:summary']").text();
if (desc) {
teleplay.desc = desc;
}
const detailDom = html(html("#info").get(0));
const publish = detailDom.find("span.pl");
let detailDom = html(html("#info").get(0));
let publish = detailDom.find("span.pl");
let valueMap = new Map<string, any>();
const valueMap = new Map<string, any>();
publish.map((index, info) => {
let key = html(info).text().trim();
const key = html(info).text().trim();
let value;
if (key.indexOf('又名') >= 0 || key.indexOf('语言') >= 0 || key.indexOf('制片国家') >= 0) {
// value = html(info.next.next).text().trim();
let vas = html(info.next).text().trim();
const vas = html(info.next).text().trim();
value = vas.split("/").map((v) => v.trim());
}else {
value = html(info.next).text().trim();

@ -90,7 +90,11 @@ export default class SettingsManager {
return doubanPluginSubjectProperty.selectors;
}
}
return ONLINE_SETTING_DEFAULT.properties.find(subjectProperty => subjectProperty.type === itemType && subjectProperty.name === propertyName).selectors;
const doubanPluginSubjectProperty = ONLINE_SETTING_DEFAULT.properties.find(subjectProperty => subjectProperty.type === itemType && subjectProperty.name === propertyName);
if(doubanPluginSubjectProperty) {
return doubanPluginSubjectProperty.selectors;
}
return [];
}
handleArray(arr: string[]): string {

@ -8,6 +8,9 @@ export default class HtmlUtil {
* @param selector
*/
public static getHtmlText(html: CheerioAPI, selector: string | string[]): string {
if (!selector) {
return null;
}
if (typeof selector == 'string') {
return html(selector).text().trim();
}else {

@ -25,6 +25,8 @@ export default class StringUtil {
return id;
}
/**
* request headers json
* @param text

@ -16,6 +16,7 @@ export default class YamlUtil {
public static handleText(text: string) {
return YamlUtil.hasSpecialChar(text) ? YamlUtil.handleSpecialChar(text.replaceAll('"', '\\"'))
.replaceAll(/\s+/g,' ')
.replaceAll('\n', '。')
.replaceAll('。。', '。') : text;
}