feat: read outlier score and subscribers from VidIQ blocks
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
edb450d4e6
commit
d88c06d086
+26
-7
@@ -1,14 +1,33 @@
|
||||
// CSS selector of VidIQ's outlier badge on a video card. It stays null until the real
|
||||
// markup is captured (Task 15); until then readVidiqScore returns null for every card.
|
||||
export const VIDIQ_BADGE_SELECTOR = null;
|
||||
import { parseCount } from './numbers.js';
|
||||
|
||||
// VidIQ's own class names are generated (vidiq-c-xxxx) and change between builds; these hooks are
|
||||
// data attributes it sets deliberately.
|
||||
export const OUTLIER_SELECTOR = '[data-hover-popover="OutlierPopover"]';
|
||||
export const SUBSCRIBERS_SELECTOR = '[data-vidiq-subscriber-count]';
|
||||
|
||||
export function parseVidiqScore(text) {
|
||||
const match = /(\d+(?:[.,]\d+)?)/.exec(text ?? '');
|
||||
return match ? Number(match[1].replace(',', '.')) : null;
|
||||
}
|
||||
|
||||
export function readVidiqScore(card, selector = VIDIQ_BADGE_SELECTOR) {
|
||||
if (!selector || !card) return null;
|
||||
const badge = card.querySelector(selector);
|
||||
return badge ? parseVidiqScore(badge.textContent) : null;
|
||||
// The badge link carries the exact value (e.g. 146.19) while the badge text is capped (">100x").
|
||||
export function outlierScoreFromHref(href) {
|
||||
if (!href) return null;
|
||||
let raw;
|
||||
try {
|
||||
raw = new URL(href, 'https://app.vidiq.com').searchParams.get('outlier_score');
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
if (raw === null || raw === '') return null;
|
||||
const value = Number(raw);
|
||||
return Number.isFinite(value) ? Math.round(value * 100) / 100 : null;
|
||||
}
|
||||
|
||||
export function readVidiqData(card) {
|
||||
const outlier = card.querySelector(OUTLIER_SELECTOR);
|
||||
const href = outlier?.querySelector('a')?.getAttribute('href');
|
||||
const outlierScore = outlier ? (outlierScoreFromHref(href) ?? parseVidiqScore(outlier.textContent)) : null;
|
||||
const subscribersNode = card.querySelector(SUBSCRIBERS_SELECTOR);
|
||||
return { outlierScore, subscribers: subscribersNode ? parseCount(subscribersNode.textContent) : null };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user