* fix(route/fanbox): refactor to use playwright to load posts
* fix(route/fanbox) added missing await
* fix(route/fanbox) closing context after page close
* fix(route/fanbox) Update model to conform to new API response
---------
Co-authored-by: Sryvkver <git@sryvkver.com>
* fix(route): harden njxzc, gxmzu and jou routes
- parse all observed date formats (ISO, slash, Chinese with optional
time) instead of a fixed YYYY-MM-DD pattern
- fall back to list data when an article page fails or lacks content,
instead of crashing the whole feed on cheerio load(null)
- skip content fetching for off-site links (e.g. WeChat posts)
- only override title/pubDate when found on the detail page
- resolve relative links and images against the article URL
- deduplicate the list/detail scaffold into per-namespace utils
- remove dead response.status checks, unused ctx params and noise
comments; fix namespace URLs and antiCrawler flags
* refactor(route): address review feedback for gxmzu, jou and njxzc
- translate code comments to English (AGENTS.md rule 53)
- select the date cell via $(selector, context) instead of .find(selector)
to avoid unicorn/no-array-callback-reference false positives
* refactor(route): simplify gxmzu, jou and njxzc per review
- drop the unused type exports, unnecessary .first() calls and the
unreachable no-content early returns
- restore the original selector object order in gxmzu/jou call sites
- gxmzu/jou: drop try-catch in resolveArticles (no failing article
observed); keep the same-host guard for off-site list entries
- njxzc: drop the same-host guard (list links are same-host /_redirect
URLs); keep try-catch for redirects to intranet-only subdomains
- gxmzu/lib: read the link text directly (library rows have no title
attribute)
* refactor(route): drop jou host guard and njxzc intranet handling
- jou: remove the same-host guard — no off-site rows on the current
first pages, which are all the route reads
- njxzc: remove the intranet-notice branch and the try-catch — every
article on the current first pages loads fine from off-campus; drop
the now-stale route descriptions as well
---------
Co-authored-by: real-jiakai <real.jiakai@gmail.com>
* fix(route/zhihu): obtain __zse_ck from a browser session
`__zse_ck` is computed at runtime by Zhihu's JS from the device fingerprint
and `d_c0`, rotates every few days, and is cross-checked against `d_c0` by
the backend, so it has to come from a real browser session. Drive a browser
seeded with the configured cookies (including the `z_c0` login cookie that
most endpoints now require) to compute a fresh, consistent `__zse_ck`,
harvest the cookie jar, and cache it for 30 minutes so it is refreshed
automatically.
Recommended ZHIHU_COOKIES: "d_c0=...; z_c0=..." (omit `__zse_ck`).
* fix(route/zhihu): fetch posts profile via API instead of HTML
The user's HTML homepage (www.zhihu.com/people/:id) is now rate-limited
(403) more aggressively than the API, which broke /zhihu/posts on the
profile fetch even though the article-list API works. Read the profile
(name, headline, avatar) from /api/v4/members/:id instead.
* fix(route/zhihu): generate __zse_ck with JSDOM
* fix(route/zhihu): use members API for org posts
---------
Co-authored-by: DzmingLi <news@dzming.li>
The /xueqiu/today route requested statuses/hot/listV2.json on xueqiu.com,
which the Alibaba Cloud WAF blocks (returns a challenge page instead of
JSON), so response.data.items was undefined and the route threw 503.
Switch the endpoint to api.xueqiu.com, which serves the same JSON without
the WAF challenge. Also mark antiCrawler: true.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The /xueqiu/user route drove a headless browser (Patchright) to load the
profile page and navigate to each status for full text. The user timeline
is public, so the data can be fetched directly from api.xueqiu.com once the
WAF challenge cookie is obtained.
- replace the browser navigation with direct ofetch calls to
api.xueqiu.com/v4/statuses/user_timeline.json and statuses/show.json
- requirePuppeteer: false (no longer drives a browser); antiCrawler: true
- pass source=买卖 for the 交易 (type 11) tab so it filters correctly
- skip the show.json detail request when legal_user_visible is true
- inline images and the retweeted status into the description
- derive screen_name and the avatar image from the timeline response
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(route): refactor to adapt to new web design
* fix:reduce complexity
* fix: update CSS selector for xingnew and xwzt
* fix: update selectors
* fix:update hideBoxes
* fix: replace for with find
- Update route name from 'User' to 'Stories'
- Rename parameter 'user' to 'value' for clarity
- Document all available sections (index, newest, ask, show, jobs, over, threads, submitted)
- Document type parameter options (sources, comments, comments_list)
- Clarify 'over' section uses points threshold instead of user ID
- Document value's general ?id=<value> behavior for other sections
- Add usage examples (HN100, user submitted, threads, comments_list)
comicat.org now fronts every page with a fake JS "captcha" (/public/html/start/)
that redirects back only after setting a `visitor_test=human` cookie. A bare request
302s to that page, so #listTable and the detail selectors match nothing (empty feed).
Send the cookie directly on both the search listing and the per-item detail fetches.
* fix(route/makerworld): bypass Cloudflare challenge and adapt to new API shape
makerworld.com now sits behind a Cloudflare bot-management challenge that
fingerprints the TLS/HTTP client rather than just headers, so plain fetch
requests get a 403 even with a browser-like User-Agent. Fall back to a
stealth Playwright page load when that happens.
The trending page's data shape also changed: designs moved from
`pageProps.popularDesignsData` to `pageProps.v2Props.foryouData.hits[].design`,
mixed in with non-design promo/community entries, and `tags`/`startTime` were
replaced by `createTime` (no tags exposed on this endpoint anymore).
* fix(route/makerworld): always fetch via browser instead of trying ofetch first
Cloudflare's challenge fingerprints the client itself, so the plain fetch
attempt was guaranteed to always fail with a 403 first. Go straight to the
Playwright fallback instead of paying for a request known to fail.
* route: add 中国地质大学(北京)
Co-Authored-By: Claude <noreply@anthropic.com>
* feat(route): add channel icon for 中国地质大学(北京)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(route): use official crest favicon as 中国地质大学(北京)feed icon
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(route): use official high-res crest for 中国地质大学(北京)feed icon
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
* perf: use only one WASM alloc for xxhash
* perf(deps): lazy load mercury-parser and use googleapis/youtube instead of heavy googleapis
* perf(dx): lazy load dev registry
speed up npm dev script
* perf: close playwright browser on destroy
* fix: show exception msg in prod
* revert: "perf: use only one WASM alloc for xxhash"
This reverts commit 01ecdd48d09a046dce05f440814dcbec0323a7de.
* perf: use only one WASM alloc for xxhash
* test: add claim for worker
* fix: missing piece from 8dd9c9a
* feat: add namespace to the chunkfilename
* fix: keep var naming
* fix: remove the src attribute of atom:content
The src attribute is to replace the inner content, not to mark its source.
RFC4287:
> 4.1.3.2. The "src" Attribute
>
> atom:content MAY have a "src" attribute, whose value MUST be an IRI
> reference [RFC3987]. If the "src" attribute is present, atom:content
> MUST be empty. Atom Processors MAY use the IRI to retrieve the
> content and MAY choose to ignore remote content or to present it in a
> different manner than local content.
>
> If the "src" attribute is present, the "type" attribute SHOULD be
> provided and MUST be a MIME media type [MIMEREG], rather than "text",
> "html", or "xhtml". The value is advisory; that is to say, when the
> corresponding URI (mapped from an IRI, if necessary) is dereferenced,
> if the server providing that content also provides a media type, the
> server-provided media type is authoritative.
* fix: move <language> to xml:lang
* fix: remove <webMaster> in atom
* fix: use ISO format to display date in atom & always have <updated>
* fix: use ISO date for feed <updated> in atom
* fix: add <link rel=self> for atom
* feat(route): add Zhejiang Museum temporary exhibition route
* fix: fix the radar source and target
* fix:fix location with null
* fix: only remove the faulty x448