{"record":{"id":"dd0c09b8fb7748d9","repo":"jackwener/OpenCLI","slug":"taobao-my-itaobao-rendered-but-no-user-id-extracta","errorCode":null,"errorMessage":"Taobao my_itaobao rendered but no user_id extractable — stale cookie2 or layout drift","messagePattern":"Taobao my_itaobao rendered but no user_id extractable — stale cookie2 or layout drift","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/taobao/auth.js","lineNumber":40,"sourceCode":"    throw new AuthRequiredError('taobao.com', 'Taobao tracknick cookie absent after navigation');\n  }\n  const domInfo = await page.evaluate(`\n    (() => {\n      const nick = (document.querySelector('.user-nick, .site-nav-user, .user-name')?.innerText || '').trim();\n      const html = document.body?.innerHTML || '';\n      const userIdMatch = html.match(/userId[\\\"'\\\\s:=]+(\\\\d+)/i);\n      return { nickname: nick, user_id: userIdMatch?.[1] || '' };\n    })()\n  `);\n  let decodedTracknick = '';\n  try {\n    decodedTracknick = JSON.parse('\"' + tracknick.replace(/\\\\/g, '\\\\\\\\') + '\"');\n  } catch {\n    decodedTracknick = tracknick;\n  }\n  const nickname = domInfo.nickname || decodedTracknick;\n  if (!domInfo.user_id) {\n    throw new CommandExecutionError('Taobao my_itaobao rendered but no user_id extractable — stale cookie2 or layout drift');\n  }\n  return { user_id: String(domInfo.user_id), nickname: String(nickname) };\n}\n\nregisterSiteAuthCommands({\n  site: 'taobao',\n  domain: 'taobao.com',\n  loginUrl: 'https://login.taobao.com/member/login.jhtml',\n  columns: ['user_id', 'nickname'],\n  quickCheck: hasTaobaoSessionCookie,\n  verify: verifyTaobaoIdentity,\n  poll: async (page) => {\n    if (!await hasTaobaoSessionCookie(page)) {\n      throw new AuthRequiredError('taobao.com', 'Waiting for Taobao tracknick cookie');\n    }\n    return verifyTaobaoIdentity(page);\n  },\n});","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/taobao/auth.js#L22-L58","documentation":"After tracknick confirms a session, verifyTaobaoIdentity scrapes user_id from the rendered my_itaobao page DOM. If the page rendered but no user_id could be extracted, the library throws CommandExecutionError, indicating the stored auth cookie (cookie2) is stale or the page layout changed so the userId regex no longer matches.","triggerScenarios":"domInfo.user_id is falsy after page.evaluate on the my_itaobao page: the userId regex /userId[\"'\\s:=]+(\\d+)/i finds no match in body HTML and no .user-nick/.site-nav-user/.user-name selector yields an id. Happens with a half-valid session (cookie2 stale) or Taobao markup changes.","commonSituations":"Taobao front-end redeploy changed element classes; session valid enough to render page but server treats it as degraded; A/B-tested layout variants; region-specific pages rendering a different template.","solutions":["Re-login to refresh cookie2 and other session cookies, then verify again","Inspect the rendered my_itaobao HTML and update the userId extraction regex/selectors in clis/taobao/auth.js to match current markup","Dump page.content() on failure to diagnose whether the page is a captcha/interstitial rather than the real profile page","Pin/retry against the m. or alternate Taobao profile URL if the desktop template drifted"],"exampleFix":"// before\nconst userIdMatch = html.match(/userId[\"'\\s:=]+(\\d+)/i);\n// after (broaden extraction)\nconst userIdMatch = html.match(/userId[\"'\\s:=]+(\\d+)/i)\n  || html.match(/\"userId\":\"?(\\d+)/i)\n  || (await page.evaluate(() => document.querySelector('[data-userid]')?.dataset.userid));","handlingStrategy":"try-catch","validationCode":"const html = await page.evaluate(() => document.body?.innerHTML || '');\nif (!/userId[\"'\\s:=]+(\\d+)/i.test(html)) console.warn('userId marker missing — layout may have drifted');","typeGuard":"function hasExtractableUserId(domInfo) {\n  return domInfo != null && Boolean(domInfo.user_id) && /^\\d+$/.test(String(domInfo.user_id));\n}","tryCatchPattern":"try {\n  const identity = await verifyTaobaoIdentity(page);\n} catch (e) {\n  if (/no user_id extractable/.test(e.message)) {\n    await page.reload({ waitUntil: 'networkidle' }); // or re-login to refresh cookie2\n    return verifyTaobaoIdentity(page);\n  }\n  throw e;\n}","preventionTips":["Re-login periodically; stale cookie2 causes half-authenticated pages","Snapshot page.content() on extraction failure for debugging layout drift","Keep extraction selectors/regexes in one place and update on Taobao redesigns","Wait for the profile section to render (networkidle/specific selector) before evaluate"],"tags":["scraping","dom-parse","taobao","stale-session"],"backgroundTag":"dom-scrape-extraction-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}