Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
yuanyuanma03 avatar

Wos Parse Results

  • 19 installs
  • 45 repo stars
  • Updated June 23, 2026
  • yuanyuanma03/academic-research-skills

Parse Web of Science search results from the current page or API response into structured records with citations and DOIs.

About

Extracts structured WoS records by parsing the runQuerySearch NDJSON API response, or falls back to DOM scraping. It is an internal helper used by other WoS skills.

  • Preferred NDJSON API-response parsing with DOM fallback
  • Captures citation counts, DOIs, and abstracts

Wos Parse Results by the numbers

  • 19 all-time installs (skills.sh)
  • Ranked #1,308 of 2,715 Automation & Workflows skills by installs in the Skillselion catalog
  • Data as of Aug 3, 2026 (Skillselion catalog sync)
npx skills add https://github.com/yuanyuanma03/academic-research-skills --skill wos-parse-results

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs19
repo stars45
Last updatedJune 23, 2026
Repositoryyuanyuanma03/academic-research-skills

What it does

Parse Web of Science search results from the current page or API response into structured records with citations and DOIs.

Files

SKILL.mdMarkdownGitHub ↗

WoS Parse Results

Internal skill for extracting structured data from WoS. Two modes: API response parsing (preferred) or DOM scraping (fallback).

Steps

Step 1: API Response Parsing (preferred)

When using the runQuerySearch API, the response is NDJSON. Parse records from the records payload:

// Parse NDJSON response text
const lines = text.trim().split('\n').map(l => { try { return JSON.parse(l); } catch(e) { return null; } }).filter(Boolean);
const searchInfo = lines.find(l => l.key === 'searchInfo')?.payload;
const recordsData = lines.find(l => l.key === 'records')?.payload;

const records = Object.entries(recordsData).map(([idx, rec]) => ({
  idx: parseInt(idx),
  wosId: rec.colluid,
  title: rec.titles?.item?.en?.[0]?.title || '',
  authors: rec.names?.author?.en?.filter(Boolean).map(a => a.wos_standard).join('; ') || '',
  source: rec.titles?.source?.en?.[0]?.title || '',
  year: rec.pub_info?.pubyear || '',
  vol: rec.pub_info?.vol || '',
  issue: rec.pub_info?.issue || '',
  pages: rec.pub_info?.page_no || '',
  doi: rec.doi || '',
  citations: rec.citation_related?.counts?.WOSCC || 0,
  citationsAll: rec.citation_related?.counts?.ALLDB || 0,
  refCount: rec.ref_count || 0,
  abstract: rec.abstract?.basic?.en?.abstract?.replace(/<[^>]*>/g, '') || '',
  docType: rec.doctypes?.[0] || '',
  oa: rec.oa || false
}));

Mode B: DOM Scraping (fallback)

When the browser is on a results page and API is not available:

async () => {
  for (let i = 0; i < 20; i++) {
    if (document.querySelector('app-record')) break;
    await new Promise(r => setTimeout(r, 500));
  }

  const records = [...document.querySelectorAll('app-record')].map((rec, idx) => {
    const titleEl = rec.querySelector('a[data-ta="summary-record-title-link"]');
    const title = titleEl?.textContent?.trim() || '';
    const href = titleEl?.href || '';
    const wosId = href.match(/WOS:\w+/)?.[0] || '';
    const authorEls = rec.querySelectorAll('a[data-ta*="DisplayName-author"]');
    const authors = [...authorEls].map(a => a.textContent?.trim()).join('; ');
    const sourceEl = rec.querySelector('a[data-ta="jcr-link-menu"]');
    const source = sourceEl?.textContent?.trim()?.replace('arrow_drop_down', '') || '';
    const citedEl = rec.querySelector('a[data-ta="stat-number-citation-related-count"]');
    const citations = citedEl?.textContent?.trim() || '0';
    return { idx: idx + 1, title, wosId, authors, source, citations };
  });

  return { status: 'ok', recordCount: records.length, records };
}

Notes

  • Mode A is always preferred — structured JSON, no selector fragility
  • Mode B is fallback when already on a results page without API access
  • DOM selectors may miss records due to lazy loading or dynamic rendering

Related skills

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.