Created
January 6, 2026 12:49
-
-
Save mekarpeles/5bd8a773e5900a55683fea7e326dd763 to your computer and use it in GitHub Desktop.
Extract openlibrary bulk search as TSV
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
| // Function to safely escape and quote a string for CSV/TSV | |
| const escapeAndQuoteTSV = str => { | |
| const value = (str?.toString() || '').trim(); | |
| const escapedValue = value.replace(/"/g, '""'); | |
| return `"${escapedValue}"`; | |
| }; | |
| // Script to extract Original Columns + All Match Details from Shadow DOM, with QUOTING | |
| const shadowRoot = document.querySelector('ol-bulk-search')?.shadowRoot; | |
| if (!shadowRoot) { | |
| console.error('ERROR: Could not find <ol-bulk-search> or its shadowRoot.'); | |
| ''; | |
| } else { | |
| // --- Data Extraction (Same as before) --- | |
| const headerRow = shadowRoot.querySelector('.tableWrapper thead tr:nth-child(2)'); | |
| if (!headerRow) { | |
| console.error('ERROR: Could not find header row.'); | |
| ''; | |
| } | |
| const headers = Array.from(headerRow.querySelectorAll('th')) | |
| .map(th => th.textContent.trim()); // Headers unquoted for object keys | |
| const outputKeys = [...headers, 'MatchTitle', 'MatchByline', 'MatchURL']; | |
| const tsvDataArray = []; // Array to hold objects for console.table() | |
| const matchRows = shadowRoot.querySelectorAll('tr.matchRow'); | |
| if (matchRows.length === 0) { | |
| console.warn('WARNING: Found 0 data rows inside the Shadow Root.'); | |
| } | |
| // --- Row Processing --- | |
| matchRows.forEach(row => { | |
| const cells = Array.from(row.querySelectorAll('td')); | |
| // Extract data for original columns (skip 1st (order#), skip last (book card)) | |
| const rowDataValues = cells.slice(1, cells.length - 1).map(td => td.textContent.trim()); | |
| // Extract match details | |
| const bookCardCell = cells[cells.length - 1]; | |
| const matchTitle = bookCardCell.querySelector('.book-card--primary .info .title')?.textContent.trim() || ''; | |
| const matchByline = bookCardCell.querySelector('.book-card--primary .info .byline')?.textContent.trim() || ''; | |
| const matchURL = bookCardCell.querySelector('.book-card--primary .info .title')?.href || ''; | |
| const finalRowValues = [...rowDataValues, matchTitle, matchByline, matchURL]; | |
| // Create an object for console.table | |
| const rowObject = {}; | |
| outputKeys.forEach((key, index) => { | |
| rowObject[key] = finalRowValues[index]; | |
| }); | |
| tsvDataArray.push(rowObject); | |
| }); | |
| // --- Output Generation (The New Part) --- | |
| console.log('--- BEAUTIFUL CONSOLE TABLE (Easier to read) ---'); | |
| console.table(tsvDataArray); // Prints a clean table in the console! | |
| // Fallback: Generate the raw TSV string (quoted) for easy copying to a spreadsheet | |
| const tsvOutput = [outputKeys.map(escapeAndQuoteTSV).join('\t')].concat( | |
| tsvDataArray.map(obj => outputKeys.map(key => escapeAndQuoteTSV(obj[key])).join('\t')) | |
| ).join('\n'); | |
| console.log('\n--- RAW QUOTED TSV STRING (Copy for Spreadsheet) ---'); | |
| console.log('NOTE: The raw string may still show \\t and \\n, but it is ready to paste.'); | |
| console.log(tsvOutput); | |
| // Return the final TSV | |
| tsvOutput; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment