Repository navigation
feat: linkedin-session adapter (LinkedIn perf-data) - #51
Merged
Jooonnn merged 1 commit intoJun 18, 2026
Merged
Conversation
New linkedin-session adapter for /cheat-retro, mirroring the douyin-session architecture (Playwright persistent login + read rendered DOM, no signature reversing, no public API). LinkedIn's single-post analytics page (/analytics/post-summary/) is author-only and SSR/inline — no public API and no stable voyager XHR to intercept, so pure HTTP can't reach it. This adapter logs in once (li_at cookie persisted to .auth-linkedin/), navigates to the post-summary page, and parses the rendered DOM text by known label anchors. - Follows perf-data contract: bash run.sh <activity_id_or_url> <video_folder> [script] → writes <video_folder>/report.md; exit codes 0/1/2/3 match douyin-session - paths.py honors CHEAT_PROJECT_ROOT / CHEAT_VIDEOS_DIR per the douyin-session / xhs-explore / bilibili-stat convention - report.md format matches existing adapters: meta + data snapshot (10 metrics: impressions / reach / reactions / comments / reposts / saves / sends / social engagements / profile-views-from-post / followers-from-post + derived ratios) + post body + comments note - Bilingual JP/EN DOM parser: LinkedIn randomly flips the UI language between Japanese and English within a session, so extract.py's POST_METRICS stores both label sets per metric. Unit-tested both ways (test_extract.py, synthetic fixtures — no real metrics committed) - accepts a full post URL (…/feed/update/urn:li:activity:<id>/) or a bare activity_id; auto-extracts the id - .gitattributes (*.sh / *.py eol=lf) — prevents Windows-CRLF from breaking the scripts (matches bilibili-stat) - cheat-retro adapter table + 特殊处理 block, cheat-init Q2.1 menu, and .gitignore / gitignore.template (.auth-linkedin/) all synced Tested end-to-end on a real post (run.sh contract + report.md output). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Contributor
|
感谢这个 PR,整体质量很高 —— 架构忠实复刻了 一个建议后续优化(非阻塞):
|
h3qing
added a commit
to h3qing/cheat-on-content
that referenced
this pull request
Jun 19, 2026
Sync upstream cheat-on-content (XBuilderLAB#48 XBuilderLAB#49 XBuilderLAB#51); keep local linkedin-session adapter
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
New
linkedin-sessionperf-data adapter for/cheat-retro, mirroring thedouyin-sessionarchitecture (Playwright persistent login + read rendered DOM — no signature reversing, no public API).What it scrapes
LinkedIn's single-post analytics page (
/analytics/post-summary/urn:li:activity:<id>/) is author-only and SSR/inline — there's no public API and no stable voyager XHR to intercept, so pure HTTP /requests(and WebFetch) can't reach it. The adapter logs in once (li_atcookie persisted to.auth-linkedin/), navigates to the post-summary page, and parses the rendered DOM text by known label anchors.Captures 10 metrics for one post: impressions, members reached, reactions, comments, reposts, saves, sends, social engagements, profile-views-from-post, followers-from-post, plus the post body.
Matches the perf-data convention
bash run.sh <activity_id_or_url> <video_folder> [<script_path>]→ writes<video_folder>/report.md, with the same exit codes asdouyin-session(0success ·1login required ·2missing playwright ·3other) so/cheat-retrodegrades gracefully to manual on any failure.paths.pyhonorsCHEAT_PROJECT_ROOT/CHEAT_VIDEOS_DIRlike the other adapters; auth lives in its own.auth-linkedin/to avoid cookie cross-talk.report.mdmatches the existing adapters' shape: meta (author / age / link) → data snapshot (the 10 metrics + derived ratios: 反应率 / 评论率 / 转发率 / 社交互动率) → post body → original script → comments note.review.pyCLI matches thelogin/video <id> [script]contract.…/feed/update/urn:li:activity:<id>/) or a bareactivity_idand auto-extracts the id..gitattributes(*.sh/*.pyeol=lf) likebilibili-stat, to keep Windows-CRLF from breaking the scripts.Bilingual JP/EN parser (honest maintenance note)
LinkedIn randomly flips the UI language between Japanese and English within a single session (a label shows up as
Impressionsone load andインプレッション数the next). Soextract.py'sPOST_METRICSstores both label aliases per metric and tries both. If you hit a third language, add the label toPOST_METRICS— the aliases are a list.test_extract.pyexercises both JP and EN with synthetic fixtures (no real metrics committed). The parser is DOM-text + language dependent, so it's marked stability ★★ and needs occasional upkeep; the debug dump (.cheat-cache/linkedin-session-debug/post_<id>.txt) is the first place to look when a field comes backNone.Install / usage
How to get the
activity_id: it's the number in a post URLhttps://www.linkedin.com/feed/update/urn:li:activity:<id>/.Wiring
skills/cheat-retro/SKILL.md: adds thelinkedinrow to the adapter routing table + alinkedin-session 的特殊处理block (same pattern as the douyin / xhs / bilibili PRs).skills/cheat-init/SKILL.md: adds LinkedIn to the Q2.1 platform menu + theenabled_perf_adaptersmapping..gitignore+templates/gitignore.template: add.auth-linkedin/so the login cookie is never committed.Tested
End-to-end on a real post (the example
activity_idabove):run.shproduces a sanereport.mdin the requested folder (auto-named-folder move works), and the unit tests pass for both JP and EN label sets. No auth, debug output, or__pycache__is committed.🤖 Generated with Claude Code