import { fromByteArray as base64Encode } from 'base64-js' import Token from './token' import config from '../config' import { request_get, request_post } from '../request' const { taobao_api_key, taobao_host, taobao_jsv, taobao_upload_api, taobao_upload_app_key, taobao_upload_app_name, taobao_v, } = config export class TaobaoCrawler extends Token { imageId: string constructor(options?) { super(options) } get t() { return Math.floor(Date.now() / 1000) } get upload_url() { return `https://${taobao_host}/h5/${taobao_upload_api.toLowerCase()}/${taobao_v}` } get goods_search_url() { return 'https://h5api.m.taobao.com/h5/mtop.relationrecommend.wirelessrecommend.recommend/2.0/'; } get upload_headers() { const headers: any = { 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', } headers.referer = 'https://s.taobao.com/' headers['Content-Type'] = 'application/x-www-form-urlencoded' return headers } get search_headers() { const headers: any = { 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', } headers.referer = 'https://s.taobao.com/' headers['Content-Type'] = 'application/x-www-form-urlencoded' return headers } get_params(data, t, jsv = taobao_jsv) { const sign_str = this.get_sign(data, t, this.token) return { jsv, appKey: taobao_api_key, t, api: taobao_upload_api, ecode: '0', v: taobao_v, type: 'originaljson', dataType: 'jsonp', sign: sign_str, data } } get_search_data(q: string) { return JSON.stringify({ "appId": "34385", "params": { "device": "HMA-AL00", "isBeta": "false", "grayHair": "false", "from": "nt_history", "brand": "HUAWEI", "info": "wifi", "index": "4", "rainbow": "", "schemaType": "auction", "elderHome": "false", "isEnterSrpSearch": "true", "newSearch": "false", "network": "wifi", "subtype": "", "hasPreposeFilter": "false", "prepositionVersion": "v2", "client_os": "Android", "gpsEnabled": "false", "searchDoorFrom": "srp", "debug_rerankNewOpenCard": "false", "homePageVersion": "v7", "searchElderHomeOpen": "false", "search_action": "initiative", "sugg": "_4_1", "sversion": "13.6", "style": "list", "ttid": "600000@taobao_pc_10.7.0", "needTabs": "true", "areaCode": "CN", "vm": "nw", "countryNum": "156", "m": "pc", "page": "1", "n": 48, q, "qSource": "url", "pageSource": "", "tab": "mall", "pageSize": 48, "totalPage": 100, "totalResults": 4800, "sourceS": "0", "sort": "_coefp", "bcoffset": "", "ntoffset": "", "filterTag": "", "service": "", "prop": "", "loc": "", "start_price": null, "end_price": null, "startPrice": null, "endPrice": null, "itemIds": null, "p4pIds": null, "categoryp": "" } } ) } getSearchParams({imageId,requestId,sessionId,sortField,sortType,beginPage,pageSize}) { return { tab: 'imageSearch', imageId, imageIdList: imageId, sortField: sortField || 'normal', sortType: sortType || 'desc', spm: '', imageAddress: '', beginPage: beginPage || 1, pageSize: pageSize || 40, pageName: 'image', '_bx-v': '1.1.20', requestId, sessionId }; } binaryio_to_base64(binaryData) { const base64String = base64Encode(new Uint8Array(binaryData)) return base64String } get_data(fileBuffer) { const b64_str = this.binaryio_to_base64(fileBuffer) const data = JSON.stringify({ imageBase64: b64_str, appName: taobao_upload_app_name, appKey: taobao_upload_app_key, }) return { data } } async upload(fileBuffer) { await this.token_request() // Upload image const data = this.get_data(fileBuffer) const params = this.get_params(data.data, this.t) const headers = this.upload_headers try { const response = await request_post({ url: this.upload_url, params, headers, data, }) return response.data } catch (error) { console.error('Upload failed:', error) return null } } async imageSearchResult({requestId,sessionId,sortField,sortType,beginPage,pageSize}: {requestId?:string,sessionId?:string, sortField?: string, sortType?:string,beginPage?: number, pageSize?:number}) { await this.token_request() const params = this.getSearchParams({imageId: this.imageId,requestId,sessionId,sortField,sortType,beginPage,pageSize}); const headers = this.search_headers; const response = await request_get(this.goods_search_url, params,headers); return response.data; } async searchResult({q}) { await this.token_request() const data = this.get_search_data(q) const params = this.get_params(data,this.t); const headers = this.search_headers; const response = await request_get(this.goods_search_url, params,headers); return response.data; } async uploadAndSearch(fileBuffer) { const res = await this.upload(fileBuffer) this.imageId = res.data.imageId return await this.imageSearchResult(res.data) } image_search_url(image_id) { const url = 'https://s.taobao.com/youyuan/index.htm' const params = new URLSearchParams({ tab: 'imageSearch', imageId: image_id, imageIdList: image_id, }) return `${url}?${params.toString()}` } } export * from './good_list' export * from './sku_list'