import {
|
IPage,
|
ISearchItem,
|
ISearchParams,
|
ISearchProvider,
|
IYahooFleamarketProductItem,
|
Order,
|
Sort,
|
StationId
|
} from "../type";
|
import {beginToPage, queryNextData, wrappedFetch} from "../lib";
|
|
export class Provider10YahooFleamarket implements ISearchProvider {
|
readonly stationId = StationId.YahooFleamarket;
|
|
async search(params: ISearchParams): Promise<IPage> {
|
const {keyword, begin = 1, maxNum = 50, category, minPrice, maxPrice, shipping, sort, order} = params;
|
const pageNum = beginToPage(begin, maxNum);
|
const warn: string[] = [];
|
const url = new URL(`https://paypayfleamarket.yahoo.co.jp/search/${keyword}`);
|
url.searchParams.set("page", String(pageNum));
|
url.searchParams.set("n", String(maxNum));
|
if (category) {
|
url.searchParams.set("categoryIds", category);
|
}
|
if (minPrice) {
|
url.searchParams.set("minPrice", String(minPrice));
|
}
|
if (maxPrice) {
|
url.searchParams.set("maxPrice", String(maxPrice));
|
}
|
if (shipping === 'free') {
|
warn.push('unsupported free shipping');
|
}
|
if (sort) {
|
if (sort === Sort.Latest) {
|
url.searchParams.set("sort", 'openTime');
|
if (order === Order.Asc) {
|
url.searchParams.set("order", 'asc');
|
} else {
|
url.searchParams.set("order", 'desc');
|
}
|
} else if (sort ===Sort.Price) {
|
url.searchParams.set("sort", 'price');
|
if (order === Order.Desc) {
|
url.searchParams.set("order", 'desc');
|
} else {
|
url.searchParams.set("order", 'asc');
|
}
|
} else if(sort!==Sort.Default) {
|
warn.push(`unsupported sort: ${sort}`);
|
}
|
}
|
|
const resp = await wrappedFetch(url);
|
|
if (!resp.ok) {
|
if (resp.status === 404) {
|
return {...params, dataList: [], error: '404 Not Found'};
|
}
|
return {...params, dataList: [], error: `HTTP error! status: ${resp.status}`};
|
}
|
|
// noinspection TypeScriptUnresolvedReference
|
const html = await resp.text();
|
const result = parseProducts(html);
|
|
return {
|
srcUrl: url.toString(),
|
warning: warn.join(', '),
|
begin,
|
maxNum,
|
pageNum,
|
...params,
|
...result,
|
};
|
}
|
}
|
|
function parseProducts(docHtml: string): Omit<IPage, keyof ISearchParams> {
|
const nextProps = queryNextData(docHtml);
|
const result = nextProps?.initialState?.searchState?.search?.result;
|
const dataList = result?.items.map(parseItem) || [];
|
|
return {
|
total: Math.max(result?.totalResultsAvailable || 0, dataList.length),
|
dataList
|
};
|
}
|
|
|
function parseItem(item: IYahooFleamarketProductItem): ISearchItem {
|
return {
|
itemId: item.id,
|
url: `https://paypayfleamarket.yahoo.co.jp/item/${item.id}`,
|
image: {
|
imageUrl: item.thumbnailImageUrl,
|
},
|
name: item.title,
|
time: item.endTime,
|
price: item.price,
|
};
|
}
|