mirror of
https://github.com/opelly27/streetmerchant.git
synced 2026-05-20 01:47:39 +00:00
feat(store): specify links to navigate to between product searches (#1542)
Fixes #1504 When querying a store, if `deterrentLinks` has been defined, pick one at random and navigate there then wait 3 seconds. This should help reduce the likelihood of being sent to a captcha on subsequent page loads from the same store.
This commit is contained in:
@@ -197,6 +197,7 @@ const notifications = {
|
||||
3070: envOrArray(process.env.DISCORD_NOTIFY_GROUP_3070),
|
||||
3080: envOrArray(process.env.DISCORD_NOTIFY_GROUP_3080),
|
||||
3090: envOrArray(process.env.DISCORD_NOTIFY_GROUP_3090),
|
||||
'captcha-deterrent': [],
|
||||
darkhero: envOrArray(process.env.DISCORD_NOTIFY_GROUP_DARKHERO),
|
||||
rx6800: envOrArray(process.env.DISCORD_NOTIFY_GROUP_RX6800),
|
||||
rx6800xt: envOrArray(process.env.DISCORD_NOTIFY_GROUP_RX6800XT),
|
||||
@@ -348,6 +349,7 @@ const store = {
|
||||
3070: envOrNumber(process.env.MAX_PRICE_SERIES_3070),
|
||||
3080: envOrNumber(process.env.MAX_PRICE_SERIES_3080),
|
||||
3090: envOrNumber(process.env.MAX_PRICE_SERIES_3090),
|
||||
'captcha-deterrent': 0,
|
||||
darkhero: envOrNumber(process.env.MAX_PRICE_SERIES_DARKHERO),
|
||||
rx6800: envOrNumber(process.env.MAX_PRICE_SERIES_RX6800),
|
||||
rx6800xt: envOrNumber(process.env.MAX_PRICE_SERIES_RX6800XT),
|
||||
|
||||
@@ -234,6 +234,10 @@ async function lookup(browser: Browser, store: Store) {
|
||||
} catch {}
|
||||
});
|
||||
|
||||
if (store.captchaDeterrent) {
|
||||
await runCaptchaDeterrent(browser, store, page);
|
||||
}
|
||||
|
||||
let statusCode = 0;
|
||||
|
||||
try {
|
||||
@@ -477,6 +481,75 @@ async function lookupCardInStock(store: Store, page: Page, link: Link) {
|
||||
return true;
|
||||
}
|
||||
|
||||
async function runCaptchaDeterrent(browser: Browser, store: Store, page: Page) {
|
||||
const successStatusCodes = store.successStatusCodes ?? [[0, 399]];
|
||||
let statusCode = 0;
|
||||
let deterrentLinks: string[] = [];
|
||||
|
||||
logger.debug(`[${store.name}] Navigating to random anti-captcha page...`);
|
||||
|
||||
if (store.captchaDeterrent?.hardLinks?.length) {
|
||||
deterrentLinks = deterrentLinks.concat(
|
||||
store.captchaDeterrent.hardLinks
|
||||
);
|
||||
}
|
||||
|
||||
if (store.captchaDeterrent?.searchUrl) {
|
||||
if (store.captchaDeterrent.searchTerms) {
|
||||
store.captchaDeterrent.searchTerms.forEach((element) =>
|
||||
deterrentLinks.push(
|
||||
store.captchaDeterrent?.searchUrl
|
||||
? store.captchaDeterrent.searchUrl.replace(
|
||||
'%%s',
|
||||
element
|
||||
)
|
||||
: ''
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (deterrentLinks.length > 0) {
|
||||
const link: Link = {
|
||||
brand: 'captcha-deterrent',
|
||||
model: 'captcha-deterrent',
|
||||
series: 'captcha-deterrent',
|
||||
url:
|
||||
deterrentLinks[
|
||||
Math.floor(Math.random() * deterrentLinks.length)
|
||||
]
|
||||
};
|
||||
logger.debug(`Selected captcha-deterrent link: ${link.url}`);
|
||||
|
||||
try {
|
||||
const givenWaitFor = store.waitUntil
|
||||
? store.waitUntil
|
||||
: 'networkidle0';
|
||||
const response: Response | null = await page.goto(link.url, {
|
||||
waitUntil: givenWaitFor
|
||||
});
|
||||
statusCode = await handleResponse(
|
||||
browser,
|
||||
store,
|
||||
page,
|
||||
link,
|
||||
response
|
||||
);
|
||||
setTimeout(() => {
|
||||
// Do nothing
|
||||
}, 3000);
|
||||
} catch (error: unknown) {
|
||||
logger.error(error);
|
||||
}
|
||||
|
||||
if (!isStatusCodeInRange(statusCode, successStatusCodes)) {
|
||||
logger.warn(
|
||||
`✖ [${store.name}] - Failed to navigate to anti-captcha target: ${link.url}`
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function tryLookupAndLoop(browser: Browser, store: Store) {
|
||||
if (!browser.isConnected()) {
|
||||
logger.debug(
|
||||
|
||||
@@ -2,6 +2,16 @@ import {Store} from './store';
|
||||
|
||||
export const Amazon: Store = {
|
||||
backoffStatusCodes: [403, 429, 503],
|
||||
captchaDeterrent: {
|
||||
hardLinks: [
|
||||
'https://www.amazon.com/Amazon-Video/b/?ie=UTF8&node=2858778011&ref_=nav_cs_prime_video',
|
||||
'https://www.amazon.com/alm/storefront?almBrandId=VUZHIFdob2xlIEZvb2Rz&ref_=nav_cs_whole_foods_in_region',
|
||||
'https://www.amazon.com/gp/goldbox?ref_=nav_cs_gb'
|
||||
],
|
||||
searchTerms: ['goober', 'dungeons+and+dragons'],
|
||||
searchUrl:
|
||||
'https://www.amazon.com/s?k=%%s&i=todays-deals&ref=nb_sb_noss_2'
|
||||
},
|
||||
currency: '$',
|
||||
labels: {
|
||||
captcha: {
|
||||
|
||||
@@ -12,6 +12,7 @@ export type Pricing = {
|
||||
|
||||
export type Brand =
|
||||
| 'test:brand'
|
||||
| 'captcha-deterrent'
|
||||
| 'amd'
|
||||
| 'asrock'
|
||||
| 'asus'
|
||||
@@ -37,6 +38,7 @@ export type Brand =
|
||||
|
||||
export type Series =
|
||||
| 'test:series'
|
||||
| 'captcha-deterrent'
|
||||
| '3060ti'
|
||||
| '3070'
|
||||
| '3080'
|
||||
@@ -57,6 +59,7 @@ export type Series =
|
||||
|
||||
export type Model =
|
||||
| 'test:model'
|
||||
| 'captcha-deterrent'
|
||||
| '5600x'
|
||||
| '5800x'
|
||||
| '5900x'
|
||||
@@ -181,6 +184,12 @@ export type Labels = {
|
||||
maxPrice?: Pricing;
|
||||
};
|
||||
|
||||
export type CaptchaDeterrent = {
|
||||
hardLinks?: string[];
|
||||
searchUrl?: string;
|
||||
searchTerms?: string[];
|
||||
};
|
||||
|
||||
export type StatusCodeRangeArray = Array<number | [number, number]>;
|
||||
|
||||
export type Store = {
|
||||
@@ -215,4 +224,6 @@ export type Store = {
|
||||
|
||||
proxyList?: string[];
|
||||
currentProxyIndex?: number;
|
||||
|
||||
captchaDeterrent?: CaptchaDeterrent;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user