Skip to content

feat(xiaohongshu): add search filter panel options (--sort/--note-type/--publish-time/--scope/--location) - #2276

Open
xemaya wants to merge 1 commit into
jackwener:mainfrom
xemaya:feat/xiaohongshu-search-filters
Open

feat(xiaohongshu): add search filter panel options (--sort/--note-type/--publish-time/--scope/--location)#2276
xemaya wants to merge 1 commit into
jackwener:mainfrom
xemaya:feat/xiaohongshu-search-filters

Conversation

@xemaya

@xemaya xemaya commented Aug 12, 2026

Copy link
Copy Markdown

What

Adds five filter options to opencli xiaohongshu search, mirroring the web search filter panel (筛选):

Option Choices Panel group
--sort comprehensive (default) / latest / most-liked / most-commented / most-collected 排序依据
--note-type all (default) / video / image 笔记类型
--publish-time anytime (default) / day / week / half-year 发布时间
--scope all (default) / seen / unseen / following 搜索范围
--location all (default) / same-city / nearby 位置距离

Example: opencli xiaohongshu search 美食 --limit 10 --sort latest --publish-time day

Why

The command previously exposed no way to filter or sort results; users had to post-filter published_at client-side, which wastes results budget (--limit max 100) and cannot express sort order at all.

How

Xiaohongshu's web search does not encode filters in the URL — selecting a chip fires a signed /api/sns/web/v1/search/notes XHR with a filters array, e.g. {"tags":["time_descending"],"type":"sort_type"}. Since this adapter is DOM-based (the header comment documents why the XHR approach broke), the implementation reproduces the user's own clicks:

  1. After navigation + content wait, buildApplyFiltersJs() opens the 筛选 panel (toggle reads 筛选 when idle, 已筛选 when filters are active — both matched).
  2. Clicks each requested chip by group label + option text.
  3. Waits (bounded) for the result list to re-render after each click before extraction proceeds.

Chip display texts for all five groups were verified against live XHR request bodies. Filters left at their default value are skipped entirely, so existing behavior is unchanged when no new flag is passed. Failures (panel or chip not found, e.g. a XHS layout change) raise a typed CommandExecutionError instead of silently returning unfiltered results.

Testing

  • 8 new unit tests in clis/xiaohongshu/search.test.js (mapping, IIFE generation, panel driving order, typed failure, no-panel-when-default).
  • npx tsc --noEmit clean; full suite: 590 files / 6741 tests passed.
  • Verified live against xiaohongshu.com with a logged-in session: --publish-time day returned only notes from the last 24h, --sort most-liked returned descending like counts, --location same-city returned local-city results.

Xiaohongshu's web search filter panel (排序依据/笔记类型/发布时间/搜索范围/位置距离)
is not URL-addressable: selecting a chip fires a signed
/api/sns/web/v1/search/notes XHR with a filters array. This adds five
options to xiaohongshu search that drive the panel chips after navigation
and wait for each re-render before extraction:

  --sort          comprehensive|latest|most-liked|most-commented|most-collected
  --note-type     all|video|image
  --publish-time  anytime|day|week|half-year
  --scope         all|seen|unseen|following
  --location      all|same-city|nearby

Chip texts and behavior were verified against live XHR request bodies.
Filters left at their default are skipped, preserving prior behavior.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant