Update ai suggest
This commit is contained in:
parent
64948505e7
commit
e14c504d01
|
|
@ -67,7 +67,7 @@ export default class EbayScraperService {
|
||||||
/** Đóng browser dùng chung (gọi khi command/worker tắt). */
|
/** Đóng browser dùng chung (gọi khi command/worker tắt). */
|
||||||
static async close(): Promise<void> {
|
static async close(): Promise<void> {
|
||||||
if (this._browser) {
|
if (this._browser) {
|
||||||
await this._browser.close().catch(() => {})
|
await this._browser.close().catch(() => { })
|
||||||
this._browser = null
|
this._browser = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -108,7 +108,7 @@ export default class EbayScraperService {
|
||||||
page = await browser.newPage()
|
page = await browser.newPage()
|
||||||
await page.setUserAgent(
|
await page.setUserAgent(
|
||||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ' +
|
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ' +
|
||||||
'(KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
|
'(KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
|
||||||
)
|
)
|
||||||
await page.setExtraHTTPHeaders({ 'Accept-Language': 'en-US,en;q=0.9' })
|
await page.setExtraHTTPHeaders({ 'Accept-Language': 'en-US,en;q=0.9' })
|
||||||
// Ẩn dấu hiệu automation để giảm khả năng bị eBay chặn.
|
// Ẩn dấu hiệu automation để giảm khả năng bị eBay chặn.
|
||||||
|
|
@ -127,7 +127,7 @@ export default class EbayScraperService {
|
||||||
// QUAN TRỌNG: eBay chặn truy cập trực tiếp vào /sch/i.html (trả Error Page).
|
// QUAN TRỌNG: eBay chặn truy cập trực tiếp vào /sch/i.html (trả Error Page).
|
||||||
// Phải vào homepage trước để lấy cookie/session, rồi mới điều hướng tới search.
|
// Phải vào homepage trước để lấy cookie/session, rồi mới điều hướng tới search.
|
||||||
const origin = new URL(url).origin
|
const origin = new URL(url).origin
|
||||||
await page.goto(origin + '/', { waitUntil: 'domcontentloaded', timeout }).catch(() => {})
|
await page.goto(origin + '/', { waitUntil: 'domcontentloaded', timeout }).catch(() => { })
|
||||||
await wait(1500)
|
await wait(1500)
|
||||||
|
|
||||||
await page.goto(url, { waitUntil: 'networkidle2', timeout })
|
await page.goto(url, { waitUntil: 'networkidle2', timeout })
|
||||||
|
|
@ -142,9 +142,9 @@ export default class EbayScraperService {
|
||||||
html.includes('Something went wrong on our end')
|
html.includes('Something went wrong on our end')
|
||||||
if (blocked) {
|
if (blocked) {
|
||||||
// Bị chặn -> quay lại homepage rồi vào lại search.
|
// Bị chặn -> quay lại homepage rồi vào lại search.
|
||||||
await page.goto(new URL(url).origin + '/', { waitUntil: 'domcontentloaded', timeout }).catch(() => {})
|
await page.goto(new URL(url).origin + '/', { waitUntil: 'domcontentloaded', timeout }).catch(() => { })
|
||||||
await wait(1500)
|
await wait(1500)
|
||||||
await page.goto(url, { waitUntil: 'networkidle2', timeout }).catch(() => {})
|
await page.goto(url, { waitUntil: 'networkidle2', timeout }).catch(() => { })
|
||||||
retries++
|
retries++
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
@ -190,6 +190,7 @@ export default class EbayScraperService {
|
||||||
const idMatch = it.link_detail.match(/\/itm\/(\d+)/)
|
const idMatch = it.link_detail.match(/\/itm\/(\d+)/)
|
||||||
const id = idMatch ? idMatch[1] : it.listingId
|
const id = idMatch ? idMatch[1] : it.listingId
|
||||||
if (!id) return null
|
if (!id) return null
|
||||||
|
if (!it.title?.includes(sku)) return null
|
||||||
|
|
||||||
const { amount, currency } = this.parsePrice(it.priceText)
|
const { amount, currency } = this.parsePrice(it.priceText)
|
||||||
if (!Number.isFinite(amount) || amount <= 0) return null
|
if (!Number.isFinite(amount) || amount <= 0) return null
|
||||||
|
|
@ -226,7 +227,7 @@ export default class EbayScraperService {
|
||||||
logger.error({ err, url }, `eBay scrape lỗi cho SKU ${sku}`)
|
logger.error({ err, url }, `eBay scrape lỗi cho SKU ${sku}`)
|
||||||
return []
|
return []
|
||||||
} finally {
|
} finally {
|
||||||
if (page) await page.close().catch(() => {})
|
if (page) await page.close().catch(() => { })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,10 +46,10 @@ export default class EbayService {
|
||||||
const [sale, sold] = await Promise.all([
|
const [sale, sold] = await Promise.all([
|
||||||
hasApiCreds
|
hasApiCreds
|
||||||
? this.tryFetch('sale', () =>
|
? this.tryFetch('sale', () =>
|
||||||
this.getAccessToken(clientId!, clientSecret!, baseUrl, SCOPE_BASE).then((token) =>
|
this.getAccessToken(clientId!, clientSecret!, baseUrl, SCOPE_BASE).then((token) =>
|
||||||
this.searchActiveListings(token, baseUrl, sku, conditionId, marketplace)
|
this.searchActiveListings(token, baseUrl, sku, conditionId, marketplace)
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
)
|
||||||
: Promise.resolve([] as Array<Record<string, any>>),
|
: Promise.resolve([] as Array<Record<string, any>>),
|
||||||
this.tryFetch('sold', () =>
|
this.tryFetch('sold', () =>
|
||||||
this.getSoldListings(clientId, clientSecret, baseUrl, sku, conditionId, marketplace)
|
this.getSoldListings(clientId, clientSecret, baseUrl, sku, conditionId, marketplace)
|
||||||
|
|
@ -144,7 +144,7 @@ export default class EbayService {
|
||||||
marketplace: string
|
marketplace: string
|
||||||
) {
|
) {
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
`${baseUrl.replace(/\/$/, '')}/buy/browse/v1/item_summary/search?q=${encodeURIComponent(sku)}&filter=conditionIds:{${conditionId}}&limit=100`,
|
`${baseUrl.replace(/\/$/, '')}/buy/browse/v1/item_summary/search?q=${encodeURIComponent(sku)}&filter=conditionIds:{${conditionId}}&limit=50`,
|
||||||
{
|
{
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ const Product = (await import('#models/product')).default
|
||||||
const EbayService = (await import('#services/ebay_service')).default
|
const EbayService = (await import('#services/ebay_service')).default
|
||||||
|
|
||||||
async function runSyncServiceTest() {
|
async function runSyncServiceTest() {
|
||||||
const product = await Product.query().first()
|
const product = await Product.query().where('id', 182).first()
|
||||||
if (!product) {
|
if (!product) {
|
||||||
throw new Error('Không có sản phẩm nào trong database để test AI suggest')
|
throw new Error('Không có sản phẩm nào trong database để test AI suggest')
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue