Sped things up a bit.
This commit is contained in:
parent
ff580ec5d5
commit
10277adbd8
|
|
@ -80,8 +80,9 @@
|
|||
let lastRowCount = 0;
|
||||
let currentRowCount = getRowCount();
|
||||
let attempts = 0;
|
||||
let maxAttempts = 3;
|
||||
|
||||
while (lastRowCount !== currentRowCount && attempts < 5) {
|
||||
while (lastRowCount !== currentRowCount && attempts < maxAttempts) {
|
||||
lastRowCount = currentRowCount;
|
||||
container.scrollTop = container.scrollHeight;
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
|
|
@ -90,7 +91,8 @@
|
|||
console.log(`Row loading attempt ${attempts}: ${currentRowCount} rows`);
|
||||
}
|
||||
|
||||
return true;
|
||||
// If we have rows and they're stable (not changing), consider it successful
|
||||
return currentRowCount > 0;
|
||||
}
|
||||
|
||||
// Helper function to wait for content to load after navigation
|
||||
|
|
@ -358,7 +360,15 @@
|
|||
// Helper function to extract current page
|
||||
async function extractCurrentPage() {
|
||||
// Wait for rows to be loaded
|
||||
await waitForRowsToLoad();
|
||||
if (!await waitForRowsToLoad()) {
|
||||
console.log('Failed to load rows, but checking if we have any content');
|
||||
// Even if waitForRowsToLoad fails, check if we have any rows
|
||||
const rows = document.querySelectorAll('.particle-table-row');
|
||||
if (rows.length === 0) {
|
||||
createNotification('No keywords found on this page', 3000, true);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Find all keyword sections
|
||||
const rows = document.querySelectorAll('.particle-table-row');
|
||||
|
|
@ -410,8 +420,28 @@
|
|||
}
|
||||
|
||||
// Helper function to create notifications
|
||||
function createNotification(message, duration = 3000, isError = false) {
|
||||
function createNotification(message, duration = 3000, isError = false, id = null, remove = false) {
|
||||
if (remove && id) {
|
||||
const existingNotification = document.getElementById(id);
|
||||
if (existingNotification) {
|
||||
existingNotification.remove();
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
// If updating existing notification
|
||||
if (id) {
|
||||
const existingNotification = document.getElementById(id);
|
||||
if (existingNotification) {
|
||||
existingNotification.textContent = message;
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
// Create new notification
|
||||
const notification = document.createElement('div');
|
||||
const notificationId = id || 'notification-' + Date.now();
|
||||
notification.id = notificationId;
|
||||
notification.style.cssText = `
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
|
|
@ -421,7 +451,6 @@
|
|||
color: white;
|
||||
border-radius: 4px;
|
||||
z-index: 10000;
|
||||
font-family: Arial, sans-serif;
|
||||
box-shadow: 0 2px 5px rgba(0,0,0,0.2);
|
||||
max-width: 300px;
|
||||
word-wrap: break-word;
|
||||
|
|
@ -430,10 +459,15 @@
|
|||
document.body.appendChild(notification);
|
||||
|
||||
if (duration > 0) {
|
||||
setTimeout(() => notification.remove(), duration);
|
||||
setTimeout(() => {
|
||||
const notificationToRemove = document.getElementById(notificationId);
|
||||
if (notificationToRemove) {
|
||||
notificationToRemove.remove();
|
||||
}
|
||||
}, duration);
|
||||
}
|
||||
|
||||
return notification;
|
||||
return notificationId;
|
||||
}
|
||||
|
||||
// Helper function to set show rows to 500
|
||||
|
|
@ -595,7 +629,7 @@
|
|||
|
||||
let lastRowCount = 0;
|
||||
let sameCountIterations = 0;
|
||||
let maxAttempts = 10;
|
||||
let maxAttempts = 5;
|
||||
let attempts = 0;
|
||||
|
||||
while (attempts < maxAttempts) {
|
||||
|
|
@ -604,7 +638,7 @@
|
|||
|
||||
if (currentRowCount === lastRowCount) {
|
||||
sameCountIterations++;
|
||||
if (sameCountIterations >= 2) {
|
||||
if (sameCountIterations >= 2 && currentRowCount > 0) {
|
||||
console.log('Row loading complete. Total rows:', currentRowCount);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -623,7 +657,14 @@
|
|||
attempts++;
|
||||
}
|
||||
|
||||
console.log('Could not load all rows after maximum attempts');
|
||||
// If we have rows but didn't meet the stability criteria, still consider it a success
|
||||
const finalRowCount = getRowCount();
|
||||
if (finalRowCount > 0) {
|
||||
console.log('Row loading completed with', finalRowCount, 'rows');
|
||||
return true;
|
||||
}
|
||||
|
||||
console.log('Could not load any rows after maximum attempts');
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -649,133 +690,120 @@
|
|||
return paginationText;
|
||||
}
|
||||
|
||||
// Helper function to format keywords into CSV format
|
||||
function formatKeywords(keywords, includeHeaders) {
|
||||
let csvContent = '';
|
||||
if (includeHeaders) {
|
||||
csvContent = 'Keyword,Search Volume,Source\n';
|
||||
}
|
||||
csvContent += keywords.map(k => `${k.keyword},${k.volume},${k.source}`).join('\n');
|
||||
return csvContent;
|
||||
}
|
||||
|
||||
// Main function to extract keywords
|
||||
async function extractKeywords() {
|
||||
if (isExtracting) {
|
||||
console.log('Extraction already in progress, skipping...');
|
||||
return;
|
||||
}
|
||||
|
||||
isExtracting = true;
|
||||
const progressDialog = new KeywordGrabberUI.ProgressDialog().create();
|
||||
|
||||
try {
|
||||
progressDialog.updateProgress('Starting extraction...');
|
||||
const processedKeywords = new Map();
|
||||
|
||||
// Initial setup
|
||||
await waitForContent();
|
||||
|
||||
// Set rows to 500
|
||||
progressDialog.updateProgress('Setting rows to 500...');
|
||||
await setShowRows500();
|
||||
await waitForContentLoad();
|
||||
|
||||
// Get total pages
|
||||
const initialPageInfo = getCurrentPageInfo();
|
||||
const totalPages = initialPageInfo && initialPageInfo.total ?
|
||||
Math.ceil(initialPageInfo.total / initialPageInfo.perPage) : 0;
|
||||
|
||||
let pageCount = 1;
|
||||
|
||||
do {
|
||||
progressDialog.updateProgress(`Processing page ${pageCount}${totalPages ? ` of ${totalPages}` : ''}...`);
|
||||
|
||||
// Load rows for current page
|
||||
await loadAllRows();
|
||||
|
||||
// Extract keywords from current page
|
||||
const currentPageKeywords = await extractCurrentPage();
|
||||
if (!currentPageKeywords || currentPageKeywords.length === 0) {
|
||||
console.log('No keywords found on current page');
|
||||
break;
|
||||
}
|
||||
|
||||
console.log(`Found ${currentPageKeywords.length} keywords on page ${pageCount}`);
|
||||
|
||||
// Add to processed set
|
||||
currentPageKeywords.forEach(({ keyword, volume, source }) => {
|
||||
if (!processedKeywords.has(keyword)) {
|
||||
processedKeywords.set(keyword, { volume, source });
|
||||
}
|
||||
});
|
||||
|
||||
progressDialog.updateProgress(`Found ${processedKeywords.size} keywords...`);
|
||||
|
||||
// Check if we're on the last page
|
||||
if (isLastPage()) {
|
||||
console.log('On last page, finished pagination');
|
||||
break;
|
||||
}
|
||||
|
||||
// Get current page info before moving
|
||||
const currentStart = getCurrentPageInfo()?.start;
|
||||
if (!currentStart) {
|
||||
console.log('Could not get current page info');
|
||||
break;
|
||||
}
|
||||
|
||||
// Move to next page
|
||||
progressDialog.updateProgress('Moving to next page...');
|
||||
const nextButton = findNextButton();
|
||||
if (!nextButton) {
|
||||
console.log('Could not find next button');
|
||||
break;
|
||||
}
|
||||
|
||||
nextButton.click();
|
||||
|
||||
// Wait for page update
|
||||
const updated = await waitForPageUpdate(currentStart);
|
||||
if (!updated) {
|
||||
console.log('Page did not update after clicking next');
|
||||
break;
|
||||
}
|
||||
|
||||
// Wait for content to load on new page
|
||||
await waitForContentLoad();
|
||||
pageCount++;
|
||||
|
||||
} while (pageCount <= totalPages || totalPages === 0);
|
||||
|
||||
// Convert keywords to array and sort by volume
|
||||
const keywordArray = Array.from(processedKeywords.entries()).map(([keyword, { volume, source }]) => ({
|
||||
keyword,
|
||||
volume,
|
||||
source
|
||||
}));
|
||||
|
||||
// Sort by volume (highest to lowest)
|
||||
keywordArray.sort((a, b) => {
|
||||
const volA = parseInt(a.volume.replace(/,/g, '')) || 0;
|
||||
const volB = parseInt(b.volume.replace(/,/g, '')) || 0;
|
||||
return volB - volA;
|
||||
});
|
||||
|
||||
// Create CSV content
|
||||
let csvContent = '';
|
||||
if (window.keywordGrabberOptions.includeHeaders) {
|
||||
csvContent = 'Keyword,Search Volume,Source\n';
|
||||
if (isExtracting) {
|
||||
console.log('Already extracting keywords');
|
||||
return;
|
||||
}
|
||||
csvContent += keywordArray.map(k => `${k.keyword},${k.volume},${k.source}`).join('\n');
|
||||
|
||||
// Copy to clipboard
|
||||
await navigator.clipboard.writeText(csvContent);
|
||||
|
||||
console.log(`Total keywords processed: ${processedKeywords.size}`);
|
||||
progressDialog.updateProgress(`Successfully copied ${processedKeywords.size} keywords!`);
|
||||
await new Promise(resolve => setTimeout(resolve, 2000));
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error:', error);
|
||||
progressDialog.updateProgress(`Error: ${error.message}`);
|
||||
await new Promise(resolve => setTimeout(resolve, 3000));
|
||||
throw error;
|
||||
} finally {
|
||||
progressDialog.remove();
|
||||
isExtracting = false;
|
||||
hasStarted = false;
|
||||
}
|
||||
isExtracting = true;
|
||||
let progressNotificationId = null;
|
||||
try {
|
||||
// Initial setup
|
||||
await waitForContent();
|
||||
|
||||
// Get initial page info to check total keywords
|
||||
const initialPageInfo = getCurrentPageInfo();
|
||||
if (!initialPageInfo) {
|
||||
throw new Error('Could not get page information');
|
||||
}
|
||||
|
||||
console.log(`Total keywords found: ${initialPageInfo.total}`);
|
||||
|
||||
// Only modify show rows if we have more than 100 keywords
|
||||
if (initialPageInfo.total > 100) {
|
||||
console.log('More than 100 keywords found, setting show rows to 500');
|
||||
if (!await setShowRows500()) {
|
||||
throw new Error('Failed to set show rows to 500');
|
||||
}
|
||||
await waitForContent();
|
||||
} else {
|
||||
console.log('Less than 100 keywords found, skipping show rows modification');
|
||||
}
|
||||
|
||||
// Get updated page info after potential show rows change
|
||||
const pageInfo = getCurrentPageInfo();
|
||||
if (!pageInfo) {
|
||||
throw new Error('Could not get page information');
|
||||
}
|
||||
|
||||
console.log(`Starting extraction from page ${pageInfo.start} to ${pageInfo.end} of ${pageInfo.total}`);
|
||||
|
||||
const allKeywords = [];
|
||||
let currentPage = 1;
|
||||
|
||||
// Create initial progress notification
|
||||
progressNotificationId = createNotification(`Extracting keywords... (0/${pageInfo.total})`, 0, false, 'progress-notification');
|
||||
|
||||
do {
|
||||
console.log(`Processing page ${currentPage}`);
|
||||
|
||||
const keywords = await extractCurrentPage();
|
||||
if (!keywords) {
|
||||
throw new Error('Failed to extract keywords from current page');
|
||||
}
|
||||
|
||||
allKeywords.push(...keywords);
|
||||
console.log(`Total keywords collected: ${allKeywords.length}`);
|
||||
|
||||
// Update progress notification
|
||||
createNotification(`Extracting keywords... (${allKeywords.length}/${pageInfo.total})`, 0, false, progressNotificationId);
|
||||
|
||||
if (await isLastPage()) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!await goToNextPage()) {
|
||||
throw new Error('Failed to navigate to next page');
|
||||
}
|
||||
|
||||
currentPage++;
|
||||
|
||||
} while (true);
|
||||
|
||||
if (allKeywords.length === 0) {
|
||||
throw new Error('No keywords found');
|
||||
}
|
||||
|
||||
// Format the keywords and copy to clipboard
|
||||
const formattedKeywords = formatKeywords(allKeywords, window.keywordGrabberOptions?.includeHeaders ?? true);
|
||||
await navigator.clipboard.writeText(formattedKeywords);
|
||||
|
||||
console.log(`Successfully extracted ${allKeywords.length} keywords`);
|
||||
|
||||
// Remove progress notification before showing success
|
||||
createNotification('', 0, false, progressNotificationId, true);
|
||||
createNotification(`Extracted ${allKeywords.length} keywords`);
|
||||
|
||||
return allKeywords;
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error during keyword extraction:', error);
|
||||
// Remove progress notification before showing error
|
||||
if (progressNotificationId) {
|
||||
createNotification('', 0, false, progressNotificationId, true);
|
||||
}
|
||||
createNotification(error.message, 5000, true);
|
||||
throw error;
|
||||
} finally {
|
||||
isExtracting = false;
|
||||
hasStarted = false;
|
||||
// Ensure progress notification is removed
|
||||
if (progressNotificationId) {
|
||||
createNotification('', 0, false, progressNotificationId, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Since this is an Angular app, content might load dynamically
|
||||
|
|
@ -802,14 +830,14 @@
|
|||
const success = await loadAllRows();
|
||||
if (success && hasStarted) {
|
||||
await extractKeywords();
|
||||
} else {
|
||||
} else if (hasStarted) { // Only show error if we haven't already completed
|
||||
createNotification('Could not load all rows. Please try again.', 5000, true);
|
||||
hasStarted = false;
|
||||
}
|
||||
} else if (attempts < maxAttempts && hasStarted) {
|
||||
attempts++;
|
||||
setTimeout(tryFindContent, 1000); // Wait 1 second before trying again
|
||||
} else {
|
||||
} else if (hasStarted) { // Only show error if we haven't already completed
|
||||
createNotification('Could not find keyword content after multiple attempts. Please make sure you are on the correct page.', 5000, true);
|
||||
hasStarted = false;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue