Skip to content

Commit cfc0cab

Browse files
committed
add ebay user/search routes
1 parent c205eeb commit cfc0cab

3 files changed

Lines changed: 134 additions & 0 deletions

File tree

lib/routes/ebay/namespace.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import type { Namespace } from '@/types';
2+
3+
export const namespace: Namespace = {
4+
name: 'eBay',
5+
url: 'ebay.com',
6+
categories: ['shopping'],
7+
description: 'eBay search results and user listings.',
8+
};

lib/routes/ebay/search.ts

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { Route } from '@/types';
2+
import { load } from 'cheerio';
3+
import ofetch from '@/utils/ofetch';
4+
import { parseDate } from '@/utils/parse-date';
5+
import logger from '@/utils/logger';
6+
7+
export const route: Route = {
8+
path: '/search/:keywords',
9+
categories: ['shopping'],
10+
example: '/ebay/search/sodimm+ddr4+16gb',
11+
parameters: { keywords: 'Keywords for search' },
12+
features: {
13+
requireConfig: false,
14+
requirePuppeteer: false,
15+
antiCrawler: false,
16+
supportBT: false,
17+
supportPodcast: false,
18+
supportScihub: false,
19+
},
20+
name: 'Search Results',
21+
maintainers: ['phoeagon'],
22+
handler,
23+
};
24+
25+
async function handler(ctx) {
26+
const { keywords } = ctx.req.param();
27+
const url = `https://www.ebay.com/sch/i.html?_nkw=${encodeURIComponent(keywords)}&_sop=10&_ipg=240`;
28+
29+
logger.info(`Fetching eBay search results: ${url}`);
30+
const response = await ofetch(url);
31+
logger.info(`eBay response status: ${response instanceof Response ? response.status : 'unknown'}`);
32+
const $ = load(response);
33+
34+
const items = $('.s-item, .s-card, .s-item__wrapper.clearfix')
35+
.toArray()
36+
.map((item) => {
37+
const $item = $(item);
38+
const titleElement = $item.find('.s-item__title, .s-card__title, .s-item__title--has-tags');
39+
const title = titleElement.text().replace(/^New Listing/i, '').trim();
40+
const link = $item.find('.s-item__link, .s-card__link').attr('href');
41+
const price = $item.find('.s-item__price, .s-card__price').text().trim();
42+
const image =
43+
$item.find('.s-item__image-img img, img.s-item__image-img').attr('src') ||
44+
$item.find('.s-item__image-wrapper img').attr('src') ||
45+
$item.find('.s-card__image-img img').attr('src') ||
46+
$item.find('.s-item__image img').attr('src');
47+
48+
if (!title || !link || title.toLowerCase().includes('shop on ebay') || price === '') {
49+
return null;
50+
}
51+
52+
return {
53+
title: `${title} - ${price}`,
54+
link,
55+
description: `<img src="${image}"><br>Price: ${price}`,
56+
category: 'eBay Search',
57+
};
58+
})
59+
.filter(Boolean);
60+
61+
logger.info(`Found ${items.length} items on eBay`);
62+
63+
return {
64+
title: `eBay Search: ${keywords}`,
65+
link: url,
66+
item: items,
67+
};
68+
}

lib/routes/ebay/user.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import { Route } from '@/types';
2+
import { load } from 'cheerio';
3+
import ofetch from '@/utils/ofetch';
4+
5+
export const route: Route = {
6+
path: ['/usr/:username', '/user/:username'],
7+
categories: ['shopping'],
8+
example: '/ebay/usr/m.trotters',
9+
parameters: { username: 'Username of the seller' },
10+
features: {
11+
requireConfig: false,
12+
requirePuppeteer: false,
13+
antiCrawler: false,
14+
supportBT: false,
15+
supportPodcast: false,
16+
supportScihub: false,
17+
},
18+
name: 'User Listings',
19+
maintainers: ['phoeagon'],
20+
handler,
21+
};
22+
23+
async function handler(ctx) {
24+
const { username } = ctx.req.param();
25+
const url = `https://www.ebay.com/usr/${username}`;
26+
27+
const response = await ofetch(url);
28+
const $ = load(response);
29+
console.log(response);
30+
31+
const items = $('article.str-item-card.StoreFrontItemCard')
32+
.toArray()
33+
.map((item) => {
34+
const $item = $(item);
35+
const title = $item.find('.str-card-title .str-text-span').first().text().trim();
36+
const link = $item.find('.str-item-card__link').attr('href');
37+
const price = $item.find('.str-item-card__property-displayPrice').text().trim();
38+
const image = $item.find('.str-image img').attr('src');
39+
40+
if (!title || !link) {
41+
return null;
42+
}
43+
44+
return {
45+
title: `${title} - ${price}`,
46+
link,
47+
description: `<img src="${image}"><br>Price: ${price}`,
48+
author: username,
49+
};
50+
})
51+
.filter(Boolean);
52+
53+
return {
54+
title: `eBay User: ${username}`,
55+
link: url,
56+
item: items,
57+
};
58+
}

0 commit comments

Comments
 (0)