1688-cli 0.1.38 → 0.1.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +64 -0
- package/README.md +1 -1
- package/dist/cli.js +12 -1
- package/dist/cli.js.map +1 -1
- package/dist/commands/cart-add.js +40 -55
- package/dist/commands/cart-add.js.map +1 -1
- package/dist/commands/cart-list.js +32 -39
- package/dist/commands/cart-list.js.map +1 -1
- package/dist/commands/image-search.js +17 -48
- package/dist/commands/image-search.js.map +1 -1
- package/dist/commands/inbox.js +305 -0
- package/dist/commands/inbox.js.map +1 -0
- package/dist/commands/offer.js +38 -45
- package/dist/commands/offer.js.map +1 -1
- package/dist/commands/order-list.js +44 -46
- package/dist/commands/order-list.js.map +1 -1
- package/dist/commands/order-logistics.js +1 -5
- package/dist/commands/order-logistics.js.map +1 -1
- package/dist/commands/search.js +123 -208
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/similar.js +23 -47
- package/dist/commands/similar.js.map +1 -1
- package/dist/session/artifacts.js +5 -1
- package/dist/session/artifacts.js.map +1 -1
- package/dist/session/dispatch.js +1 -0
- package/dist/session/dispatch.js.map +1 -1
- package/dist/session/im-ws.js +97 -0
- package/dist/session/im-ws.js.map +1 -0
- package/dist/session/mtop.js +7 -0
- package/dist/session/mtop.js.map +1 -0
- package/dist/session/response-capture.js +145 -0
- package/dist/session/response-capture.js.map +1 -0
- package/dist/session/search-capture.js +115 -0
- package/dist/session/search-capture.js.map +1 -0
- package/dist/session/search-mtop.js +67 -0
- package/dist/session/search-mtop.js.map +1 -0
- package/dist/session/wait.js +24 -14
- package/dist/session/wait.js.map +1 -1
- package/package.json +1 -1
|
@@ -2,7 +2,7 @@ import { dispatch } from '../session/dispatch.js';
|
|
|
2
2
|
import { emit, info } from '../io/output.js';
|
|
3
3
|
import { CliError } from '../io/errors.js';
|
|
4
4
|
import { withRecovery } from '../session/recovery.js';
|
|
5
|
-
import {
|
|
5
|
+
import { startResponseCapture } from '../session/response-capture.js';
|
|
6
6
|
const STATUS_LABELS = {
|
|
7
7
|
all: '全部',
|
|
8
8
|
waitbuyerpay: '待付款',
|
|
@@ -18,65 +18,63 @@ export async function execute(ctx, args) {
|
|
|
18
18
|
}
|
|
19
19
|
export async function executeRaw(ctx, args) {
|
|
20
20
|
const page = await ctx.newPage();
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
if (!MTOP_API_RE.test(resp.url()))
|
|
27
|
-
return;
|
|
28
|
-
try {
|
|
21
|
+
const capture = startResponseCapture({
|
|
22
|
+
page,
|
|
23
|
+
timeoutMs: 25000,
|
|
24
|
+
matcher: MTOP_API_RE,
|
|
25
|
+
parse: async (resp) => {
|
|
29
26
|
const text = await resp.text();
|
|
30
27
|
const outer = JSON.parse(text);
|
|
31
28
|
const resultStr = outer?.data?.data?.result;
|
|
32
29
|
if (typeof resultStr !== 'string')
|
|
33
|
-
return;
|
|
30
|
+
return null;
|
|
34
31
|
const inner = JSON.parse(resultStr);
|
|
35
32
|
const list = inner?.data?.data;
|
|
36
33
|
if (!Array.isArray(list))
|
|
37
|
-
return;
|
|
34
|
+
return null;
|
|
38
35
|
const first = list[0];
|
|
39
|
-
if (list.length
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
36
|
+
if (list.length > 0 && (first?.id ?? null) === null)
|
|
37
|
+
return null;
|
|
38
|
+
if (process.env.BB1688_PROBE === '1') {
|
|
39
|
+
try {
|
|
40
|
+
const fs = await import('node:fs/promises');
|
|
41
|
+
await fs.writeFile('/tmp/1688-order-list-raw.json', text);
|
|
42
|
+
process.stderr.write(`[probe] saved raw order-list response → /tmp/1688-order-list-raw.json (${text.length} bytes)\n`);
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
/* ignore */
|
|
49
46
|
}
|
|
50
|
-
resolveCapture(inner);
|
|
51
47
|
}
|
|
48
|
+
return inner;
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
try {
|
|
52
|
+
const url = `${ORDER_LIST_URL}?tradeStatus=${encodeURIComponent(args.status)}&page=${args.page}&pageSize=${args.pageSize}`;
|
|
53
|
+
info(`Fetching orders (${args.status}, page ${args.page})...`);
|
|
54
|
+
try {
|
|
55
|
+
await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 30000 });
|
|
52
56
|
}
|
|
53
|
-
catch {
|
|
54
|
-
|
|
57
|
+
catch (e) {
|
|
58
|
+
throw new CliError(9, 'NETWORK_ERROR', `Failed to load order page: ${e.message}`);
|
|
55
59
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
60
|
+
if (/login\.1688\.com|login\.taobao\.com/.test(page.url())) {
|
|
61
|
+
throw new CliError(3, 'NOT_LOGGED_IN', 'Session expired. Run `1688 login`.');
|
|
62
|
+
}
|
|
63
|
+
// Wait up to 25s for the mtop response carrying the order array.
|
|
64
|
+
const inner = await capture.wait();
|
|
65
|
+
if (!inner) {
|
|
66
|
+
throw new CliError(11, 'NO_ORDER_DATA', 'Order list response was not captured (page may have changed or risk-controlled).', {
|
|
67
|
+
category: 'response_capture',
|
|
68
|
+
retryable: true,
|
|
69
|
+
responseCapture: capture.diagnostics(),
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
return parseOrderList(inner, args);
|
|
68
73
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
fallback: null,
|
|
73
|
-
});
|
|
74
|
-
page.off('response', onResp);
|
|
75
|
-
await page.close().catch(() => { });
|
|
76
|
-
if (!inner) {
|
|
77
|
-
throw new CliError(11, 'NO_ORDER_DATA', 'Order list response was not captured (page may have changed or risk-controlled).');
|
|
74
|
+
finally {
|
|
75
|
+
capture.dispose();
|
|
76
|
+
await page.close().catch(() => { });
|
|
78
77
|
}
|
|
79
|
-
return parseOrderList(inner, args);
|
|
80
78
|
}
|
|
81
79
|
function parseOrderList(inner, args) {
|
|
82
80
|
const list = inner.data?.data ?? [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"order-list.js","sourceRoot":"","sources":["../../src/commands/order-list.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"order-list.js","sourceRoot":"","sources":["../../src/commands/order-list.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,6 +2,7 @@ import { dispatch } from '../session/dispatch.js';
|
|
|
2
2
|
import { emit, info } from '../io/output.js';
|
|
3
3
|
import { CliError } from '../io/errors.js';
|
|
4
4
|
import { withRecovery } from '../session/recovery.js';
|
|
5
|
+
import { parseMtop } from '../session/mtop.js';
|
|
5
6
|
import { sleep } from '../session/wait.js';
|
|
6
7
|
const ORDER_LIST_URL = 'https://air.1688.com/app/ctf-page/trade-order-list/buyer-order-list.html';
|
|
7
8
|
const TRACE_API_RE = /mtoplgttraceservice\.querytrace/i;
|
|
@@ -122,11 +123,6 @@ async function fetchPageLogistics(ctx, page, pageSize, status) {
|
|
|
122
123
|
}
|
|
123
124
|
return { traceList, totalPages, orderIdsOnPage };
|
|
124
125
|
}
|
|
125
|
-
function parseMtop(text) {
|
|
126
|
-
const t = text.trim();
|
|
127
|
-
const m = t.match(/^\s*mtopjsonp\d+\(([\s\S]*)\)\s*$/);
|
|
128
|
-
return JSON.parse(m ? m[1] : t);
|
|
129
|
-
}
|
|
130
126
|
function parseTrace(t) {
|
|
131
127
|
const remark = t.remark ?? '';
|
|
132
128
|
// Carrier is usually in "remark" after a "|" separator: "... | 中通快递(ZTO)承运"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"order-logistics.js","sourceRoot":"","sources":["../../src/commands/order-logistics.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"order-logistics.js","sourceRoot":"","sources":["../../src/commands/order-logistics.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/search.js
CHANGED
|
@@ -4,7 +4,10 @@ import { emit, info } from '../io/output.js';
|
|
|
4
4
|
import { CliError } from '../io/errors.js';
|
|
5
5
|
import { withRecovery } from '../session/recovery.js';
|
|
6
6
|
import { clickSearchNextPage } from '../session/search-locators.js';
|
|
7
|
-
import {
|
|
7
|
+
import { startSearchOfferCapture } from '../session/search-capture.js';
|
|
8
|
+
import { SEARCH_APP_ID, SEARCH_MTOP_API, mapOffer, } from '../session/search-mtop.js';
|
|
9
|
+
import { parseMtopJsonp } from '../session/mtop.js';
|
|
10
|
+
import { sleep, waitWithDeadline } from '../session/wait.js';
|
|
8
11
|
export async function execute(ctx, args) {
|
|
9
12
|
return withRecovery(ctx, { cmd: 'search', args }, async () => {
|
|
10
13
|
const offers = await fetchSearch(ctx, args.keyword, args.headed === true, args.max);
|
|
@@ -26,11 +29,7 @@ export async function run(keyword, opts) {
|
|
|
26
29
|
}
|
|
27
30
|
let HTML_SEQ = 0;
|
|
28
31
|
let MTOP_SEQ = 0;
|
|
29
|
-
|
|
30
|
-
// appId=32517. Same endpoint serves keyword search, image search, and
|
|
31
|
-
// related-product recommendations — appId is the discriminator.
|
|
32
|
-
export const SEARCH_MTOP_API = 'mtop.relationrecommend.wirelessrecommend.recommend';
|
|
33
|
-
export const SEARCH_APP_ID = '32517';
|
|
32
|
+
export { SEARCH_APP_ID, SEARCH_MTOP_API, mapOffer };
|
|
34
33
|
// 1688 search returns 60 offers per page. `--max` auto-paginates by
|
|
35
34
|
// clicking the in-page "next" arrow (which keeps the search-context
|
|
36
35
|
// `pageId` stable — see fetchSearch for why that matters). MAX_PAGES caps
|
|
@@ -39,56 +38,7 @@ export const SEARCH_APP_ID = '32517';
|
|
|
39
38
|
// asks for more.
|
|
40
39
|
const PAGE_SIZE = 60;
|
|
41
40
|
const MAX_PAGES = 10;
|
|
42
|
-
export
|
|
43
|
-
const t = raw.trim();
|
|
44
|
-
const m = t.match(/^\s*mtopjsonp\w+\(([\s\S]*)\)\s*$/);
|
|
45
|
-
return JSON.parse(m ? m[1] : t);
|
|
46
|
-
}
|
|
47
|
-
function bool(s) {
|
|
48
|
-
return s === 'true';
|
|
49
|
-
}
|
|
50
|
-
export function mapOffer(item) {
|
|
51
|
-
const d = item.data;
|
|
52
|
-
if (!d?.offerId)
|
|
53
|
-
return null;
|
|
54
|
-
const title = (d.title ?? '').replace(/<\/?font[^>]*>/g, '').trim();
|
|
55
|
-
const priceRaw = d.priceInfo?.price;
|
|
56
|
-
const price = priceRaw ? parseFloat(priceRaw) : null;
|
|
57
|
-
const yearsRaw = d.shop?.tpYear;
|
|
58
|
-
const years = yearsRaw ? parseInt(yearsRaw, 10) : null;
|
|
59
|
-
const tags = (d.tags ?? [])
|
|
60
|
-
.map((t) => t?.text?.trim() ?? '')
|
|
61
|
-
.filter((s) => !!s);
|
|
62
|
-
return {
|
|
63
|
-
offerId: d.offerId,
|
|
64
|
-
title,
|
|
65
|
-
price: {
|
|
66
|
-
text: priceRaw ? `¥${priceRaw}` : '',
|
|
67
|
-
min: price,
|
|
68
|
-
max: price,
|
|
69
|
-
},
|
|
70
|
-
supplier: {
|
|
71
|
-
name: d.shop?.text ?? null,
|
|
72
|
-
shopUrl: d.shopAddition?.shopLinkUrl ?? d.winPortUrl ?? null,
|
|
73
|
-
years,
|
|
74
|
-
},
|
|
75
|
-
location: {
|
|
76
|
-
province: d.province ?? null,
|
|
77
|
-
city: d.city ?? null,
|
|
78
|
-
},
|
|
79
|
-
bizType: d.bizType ?? null,
|
|
80
|
-
verified: {
|
|
81
|
-
factory: bool(d.factoryInspection),
|
|
82
|
-
business: bool(d.businessInspection),
|
|
83
|
-
superFactory: bool(d.superFactory),
|
|
84
|
-
},
|
|
85
|
-
tags,
|
|
86
|
-
isP4P: bool(d.isP4P),
|
|
87
|
-
turnover: d.bookedCount ?? null,
|
|
88
|
-
url: `https://detail.1688.com/offer/${d.offerId}.html`,
|
|
89
|
-
image: d.offerPicUrl ?? null,
|
|
90
|
-
};
|
|
91
|
-
}
|
|
41
|
+
export { parseMtopJsonp };
|
|
92
42
|
async function fetchSearch(ctx, keyword, headed, maxResults) {
|
|
93
43
|
const page = await ctx.newPage();
|
|
94
44
|
// s.1688.com is GBK-encoded — UTF-8 percent-encoding makes the server
|
|
@@ -99,57 +49,10 @@ async function fetchSearch(ctx, keyword, headed, maxResults) {
|
|
|
99
49
|
.join('');
|
|
100
50
|
const baseUrl = `https://s.1688.com/selloffer/offer_search.htm?keywords=${gbkQs}`;
|
|
101
51
|
const pagesWanted = Math.min(Math.max(1, Math.ceil(maxResults / PAGE_SIZE)), MAX_PAGES);
|
|
102
|
-
//
|
|
103
|
-
//
|
|
104
|
-
//
|
|
105
|
-
// The search page fires several appId=32517 calls: a navigation/config
|
|
106
|
-
// call (`batchGetNavigationAndConfigData`) and the result list
|
|
107
|
-
// (`getOfferList`). Only the latter carries offers. Crucially, we also
|
|
108
|
-
// match the request's `beginPage` against the page we're currently on —
|
|
109
|
-
// a stale page-1 response can still be in flight when we've already
|
|
110
|
-
// navigated to page 2, and capturing it would silently mix pages or stall
|
|
111
|
-
// pagination.
|
|
112
|
-
let capturedOffers = [];
|
|
52
|
+
// The search capture must only attach AFTER warmup: the warmup homepage fires
|
|
53
|
+
// the same WirelessRecommend endpoint/appId for recommendations. The capture
|
|
54
|
+
// also checks beginPage so stale page-1 responses cannot poison later pages.
|
|
113
55
|
let currentTargetPage = 1;
|
|
114
|
-
const onResp = async (resp) => {
|
|
115
|
-
const respUrl = resp.url();
|
|
116
|
-
if (!respUrl.includes(SEARCH_MTOP_API))
|
|
117
|
-
return;
|
|
118
|
-
try {
|
|
119
|
-
const dataParam = new URLSearchParams(new URL(respUrl).search).get('data') ?? '';
|
|
120
|
-
const dataObj = JSON.parse(dataParam);
|
|
121
|
-
if (String(dataObj.appId) !== SEARCH_APP_ID)
|
|
122
|
-
return;
|
|
123
|
-
const params = JSON.parse(dataObj.params ?? '{}');
|
|
124
|
-
if (params.method !== 'getOfferList')
|
|
125
|
-
return;
|
|
126
|
-
// `beginPage` is a number on page 1 (the page's default) but a string
|
|
127
|
-
// on pages 2+ (it flows through the click handler) — coerce to compare.
|
|
128
|
-
if (Number(params.beginPage ?? 1) !== currentTargetPage)
|
|
129
|
-
return;
|
|
130
|
-
}
|
|
131
|
-
catch {
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
try {
|
|
135
|
-
const body = await resp.text();
|
|
136
|
-
const json = parseMtopJsonp(body);
|
|
137
|
-
const items = json?.data?.data?.OFFER?.items ?? [];
|
|
138
|
-
const offers = items
|
|
139
|
-
.map(mapOffer)
|
|
140
|
-
.filter((o) => o !== null);
|
|
141
|
-
if (offers.length > 0)
|
|
142
|
-
capturedOffers = offers;
|
|
143
|
-
}
|
|
144
|
-
catch {
|
|
145
|
-
/* malformed response — skip */
|
|
146
|
-
}
|
|
147
|
-
};
|
|
148
|
-
// NOTE: `onResp` is intentionally NOT attached here. It must only listen
|
|
149
|
-
// AFTER the warmup navigation — `https://s.1688.com/` (the warmup target)
|
|
150
|
-
// fires its own WirelessRecommend.recommend with appId=32517 for the
|
|
151
|
-
// homepage recommendation feed. Attaching early captures that feed instead
|
|
152
|
-
// of the actual keyword-search results.
|
|
153
56
|
async function warmup(delayMs) {
|
|
154
57
|
try {
|
|
155
58
|
await page.goto('https://s.1688.com/', {
|
|
@@ -296,109 +199,119 @@ async function fetchSearch(ctx, keyword, headed, maxResults) {
|
|
|
296
199
|
}
|
|
297
200
|
});
|
|
298
201
|
}
|
|
299
|
-
|
|
300
|
-
// timeout; headed: long enough for user to solve any slider.
|
|
301
|
-
async function waitForOffers(timeoutMs) {
|
|
302
|
-
const deadline = Date.now() + timeoutMs;
|
|
303
|
-
while (Date.now() < deadline) {
|
|
304
|
-
if (page.isClosed()) {
|
|
305
|
-
throw new CliError(130, 'CANCELED', 'Browser closed.');
|
|
306
|
-
}
|
|
307
|
-
if (capturedOffers.length > 0)
|
|
308
|
-
return true;
|
|
309
|
-
// Cheap WAF check: if we're stuck on the punish URL, fail fast headless.
|
|
310
|
-
if (!headed && /\/punish|x5secdata=/.test(page.url()))
|
|
311
|
-
return false;
|
|
312
|
-
await sleep(300);
|
|
313
|
-
}
|
|
314
|
-
return false;
|
|
315
|
-
}
|
|
202
|
+
const isSearchBlocked = () => !headed && /\/punish|x5secdata=/.test(page.url());
|
|
316
203
|
// Stable strategy: always warm up before search. Cookie-presence checks
|
|
317
204
|
// can't tell whether the WAF has invalidated the session, so we pay a
|
|
318
205
|
// small constant overhead instead of betting on stale cookies.
|
|
319
206
|
info('Warming up s.1688.com...');
|
|
320
207
|
await warmup(1500);
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
208
|
+
let capture = startSearchOfferCapture({
|
|
209
|
+
page,
|
|
210
|
+
requireMethod: 'getOfferList',
|
|
211
|
+
targetPage: () => currentTargetPage,
|
|
212
|
+
});
|
|
213
|
+
try {
|
|
214
|
+
const allOffers = [];
|
|
215
|
+
const seenIds = new Set();
|
|
216
|
+
for (let pageNum = 1; pageNum <= pagesWanted; pageNum++) {
|
|
217
|
+
capture.reset();
|
|
218
|
+
currentTargetPage = pageNum;
|
|
219
|
+
if (pageNum === 1) {
|
|
220
|
+
info(`Searching 1688 for "${keyword}"...`);
|
|
221
|
+
if (headed) {
|
|
222
|
+
info('A Chrome window has opened — switch focus to it now.');
|
|
223
|
+
}
|
|
224
|
+
await navigateTo(baseUrl);
|
|
333
225
|
}
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
226
|
+
else {
|
|
227
|
+
// Pages 2+ MUST stay in the same page session. Every fresh navigation
|
|
228
|
+
// mints a new search-context `pageId`, and `beginPage=N` against a
|
|
229
|
+
// fresh pageId returns near-duplicate top results (~75% overlap).
|
|
230
|
+
// Clicking the in-page "next" arrow advances `beginPage` within the
|
|
231
|
+
// SAME pageId, which is the only way to get a clean next 60.
|
|
232
|
+
info(`Fetching page ${pageNum}/${pagesWanted}...`);
|
|
233
|
+
const advanced = await clickSearchNextPage(page).catch(() => false);
|
|
234
|
+
if (!advanced) {
|
|
235
|
+
info(`Could not advance to page ${pageNum} — stopping at ${allOffers.length} results.`);
|
|
236
|
+
break;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
let captureResult = await capture.wait({
|
|
240
|
+
timeoutMs: headed ? 180000 : 12000,
|
|
241
|
+
isClosed: () => page.isClosed(),
|
|
242
|
+
isBlocked: isSearchBlocked,
|
|
243
|
+
});
|
|
244
|
+
let capturedOffers = captureResult.offers;
|
|
245
|
+
let got = captureResult.status === 'captured';
|
|
246
|
+
if (captureResult.status === 'browser_closed') {
|
|
247
|
+
throw new CliError(130, 'CANCELED', 'Browser closed.');
|
|
248
|
+
}
|
|
249
|
+
// Retry only on page 1 — first-contact WAF warmup. A page-2+ failure
|
|
250
|
+
// just stops the loop with whatever has been collected so far.
|
|
251
|
+
if (!got && !headed && pageNum === 1) {
|
|
252
|
+
info('First attempt blocked or empty. Re-warming and retrying...');
|
|
253
|
+
// Dispose + recreate around the re-warmup: the re-warmup hits the
|
|
254
|
+
// homepage again, which would otherwise re-poison capturedOffers.
|
|
255
|
+
capture.dispose();
|
|
256
|
+
await warmup(3500);
|
|
257
|
+
capture = startSearchOfferCapture({
|
|
258
|
+
page,
|
|
259
|
+
requireMethod: 'getOfferList',
|
|
260
|
+
targetPage: () => currentTargetPage,
|
|
261
|
+
});
|
|
262
|
+
await navigateTo(baseUrl);
|
|
263
|
+
captureResult = await capture.wait({
|
|
264
|
+
timeoutMs: 15000,
|
|
265
|
+
isClosed: () => page.isClosed(),
|
|
266
|
+
isBlocked: isSearchBlocked,
|
|
267
|
+
});
|
|
268
|
+
capturedOffers = captureResult.offers;
|
|
269
|
+
got = captureResult.status === 'captured';
|
|
270
|
+
if (captureResult.status === 'browser_closed') {
|
|
271
|
+
throw new CliError(130, 'CANCELED', 'Browser closed.');
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
if (!got) {
|
|
275
|
+
if (pageNum === 1) {
|
|
276
|
+
throw riskControlError(headed);
|
|
277
|
+
}
|
|
278
|
+
info(`Page ${pageNum} blocked or empty — returning ${allOffers.length} ` +
|
|
279
|
+
`results from ${pageNum - 1} page(s).`);
|
|
346
280
|
break;
|
|
347
281
|
}
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
282
|
+
if (pageNum === 1)
|
|
283
|
+
await detectLoginRedirect(page);
|
|
284
|
+
// Accumulate with cross-page dedup. 1688 occasionally repeats P4P ad
|
|
285
|
+
// slots across pages; dedup keeps the result set clean.
|
|
286
|
+
let added = 0;
|
|
287
|
+
for (const o of capturedOffers) {
|
|
288
|
+
if (seenIds.has(o.offerId))
|
|
289
|
+
continue;
|
|
290
|
+
seenIds.add(o.offerId);
|
|
291
|
+
allOffers.push(o);
|
|
292
|
+
added++;
|
|
293
|
+
}
|
|
294
|
+
// Stop conditions:
|
|
295
|
+
// - collected enough for the caller's --max
|
|
296
|
+
// - short page (< 60) means we hit the last page of results
|
|
297
|
+
// - zero new items means pagination isn't advancing (bail rather than
|
|
298
|
+
// spin through identical pages)
|
|
299
|
+
if (allOffers.length >= maxResults)
|
|
300
|
+
break;
|
|
301
|
+
if (capturedOffers.length < PAGE_SIZE)
|
|
302
|
+
break;
|
|
303
|
+
if (added === 0)
|
|
304
|
+
break;
|
|
305
|
+
// Human-like jitter between page clicks to keep the WAF score low.
|
|
306
|
+
if (pageNum < pagesWanted) {
|
|
307
|
+
await sleep(1500 + Math.random() * 2000);
|
|
367
308
|
}
|
|
368
|
-
info(`Page ${pageNum} blocked or empty — returning ${allOffers.length} ` +
|
|
369
|
-
`results from ${pageNum - 1} page(s).`);
|
|
370
|
-
break;
|
|
371
|
-
}
|
|
372
|
-
if (pageNum === 1)
|
|
373
|
-
await detectLoginRedirect(page);
|
|
374
|
-
// Accumulate with cross-page dedup. 1688 occasionally repeats P4P ad
|
|
375
|
-
// slots across pages; dedup keeps the result set clean.
|
|
376
|
-
let added = 0;
|
|
377
|
-
for (const o of capturedOffers) {
|
|
378
|
-
if (seenIds.has(o.offerId))
|
|
379
|
-
continue;
|
|
380
|
-
seenIds.add(o.offerId);
|
|
381
|
-
allOffers.push(o);
|
|
382
|
-
added++;
|
|
383
|
-
}
|
|
384
|
-
// Stop conditions:
|
|
385
|
-
// - collected enough for the caller's --max
|
|
386
|
-
// - short page (< 60) means we hit the last page of results
|
|
387
|
-
// - zero new items means pagination isn't advancing (bail rather than
|
|
388
|
-
// spin through identical pages)
|
|
389
|
-
if (allOffers.length >= maxResults)
|
|
390
|
-
break;
|
|
391
|
-
if (capturedOffers.length < PAGE_SIZE)
|
|
392
|
-
break;
|
|
393
|
-
if (added === 0)
|
|
394
|
-
break;
|
|
395
|
-
// Human-like jitter between page clicks to keep the WAF score low.
|
|
396
|
-
if (pageNum < pagesWanted) {
|
|
397
|
-
await sleep(1500 + Math.random() * 2000);
|
|
398
309
|
}
|
|
310
|
+
return allOffers;
|
|
311
|
+
}
|
|
312
|
+
finally {
|
|
313
|
+
capture.dispose();
|
|
399
314
|
}
|
|
400
|
-
page.off('response', onResp);
|
|
401
|
-
return allOffers;
|
|
402
315
|
}
|
|
403
316
|
async function isBlocked(page, retries = 3) {
|
|
404
317
|
for (let i = 0; i < retries; i++) {
|
|
@@ -441,11 +354,10 @@ async function waitPastBlocking(page, headed) {
|
|
|
441
354
|
return false;
|
|
442
355
|
info('Verification page detected — drag the slider in the window.');
|
|
443
356
|
}
|
|
444
|
-
const deadline = Date.now() + (headed ? 180000 : 8000);
|
|
445
357
|
let lastProgressAt = Date.now();
|
|
446
358
|
let lastDebugAt = 0;
|
|
447
359
|
const debug = process.env.BB1688_DEBUG === '1';
|
|
448
|
-
|
|
360
|
+
return waitWithDeadline(async ({ now, remainingMs }) => {
|
|
449
361
|
if (page.isClosed()) {
|
|
450
362
|
throw new CliError(130, 'CANCELED', 'Browser closed.');
|
|
451
363
|
}
|
|
@@ -457,9 +369,9 @@ async function waitPastBlocking(page, headed) {
|
|
|
457
369
|
bodyLen: (document.body?.innerText ?? '').length,
|
|
458
370
|
}))
|
|
459
371
|
.catch(() => null);
|
|
460
|
-
if (debug && state &&
|
|
372
|
+
if (debug && state && now - lastDebugAt > 1000) {
|
|
461
373
|
info(`[poll] url=${state.url.slice(0, 80)} title="${state.title.slice(0, 40)}" anchors=${state.anchorCount} bodyLen=${state.bodyLen}`);
|
|
462
|
-
lastDebugAt =
|
|
374
|
+
lastDebugAt = now;
|
|
463
375
|
}
|
|
464
376
|
if (state) {
|
|
465
377
|
const onPunish = /\/punish|x5secdata=|punish\.1688\.com/.test(state.url);
|
|
@@ -472,13 +384,16 @@ async function waitPastBlocking(page, headed) {
|
|
|
472
384
|
return true;
|
|
473
385
|
}
|
|
474
386
|
}
|
|
475
|
-
if (headed &&
|
|
476
|
-
info(`Still waiting for results page (${Math.round(
|
|
477
|
-
lastProgressAt =
|
|
387
|
+
if (headed && now - lastProgressAt > 10000) {
|
|
388
|
+
info(`Still waiting for results page (${Math.round(remainingMs / 1000)}s left)...`);
|
|
389
|
+
lastProgressAt = now;
|
|
478
390
|
}
|
|
479
|
-
|
|
480
|
-
}
|
|
481
|
-
|
|
391
|
+
return null;
|
|
392
|
+
}, {
|
|
393
|
+
timeoutMs: headed ? 180000 : 8000,
|
|
394
|
+
intervalMs: 500,
|
|
395
|
+
onTimeout: () => false,
|
|
396
|
+
});
|
|
482
397
|
}
|
|
483
398
|
function riskControlError(triedHeaded) {
|
|
484
399
|
const msg = triedHeaded
|