Last active
January 18, 2025 22:46
-
-
Save AKASGaming/f11c088e54ae4051544da5751485e5b9 to your computer and use it in GitHub Desktop.
Exports your car's Service History from the CarFax.com Service History page to CSV
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
// Paste the following code into Chrome's Developer Tools (Ctrl + Shift + I) | |
(function () { | |
const serviceRecords = []; | |
const serviceRecordElements = document.querySelectorAll('[id^="service-record-"]'); | |
let lastValidOdometer = 0; // Default for missing odometer values | |
// Iterate through all service records visible on the page | |
serviceRecordElements.forEach((serviceRecordElement) => { | |
const dateSelector = '.service-history-header > div.flex-row.flex-wrap > div:nth-child(1) > div'; | |
const odometerSelector = '.service-history-header > div.flex-row.flex-wrap > div:nth-child(2) > div'; | |
const servicesPerformedSelector = '.service-performed ul'; | |
const shopSelector = '.service-history-header__title'; | |
const shopLinkSelector = '.service-history-header__title a'; | |
// Extract data for each record | |
const dateElement = serviceRecordElement.querySelector(dateSelector); | |
const odometerElement = serviceRecordElement.querySelector(odometerSelector); | |
const servicesPerformedElement = serviceRecordElement.querySelector(servicesPerformedSelector); | |
const shopElement = serviceRecordElement.querySelector(shopSelector); | |
const shopLinkElement = serviceRecordElement.querySelector(shopLinkSelector); | |
const dateServiced = dateElement ? dateElement.textContent.trim() : ''; | |
let odometer = odometerElement ? odometerElement.textContent.trim() : ''; | |
odometer = odometer.replace(/[^\d]/g, ''); // Remove all non-numeric characters | |
// If odometer is empty, use the last valid value | |
if (!odometer) { | |
odometer = lastValidOdometer; | |
} else { | |
lastValidOdometer = odometer; // Update last valid odometer | |
} | |
const servicesPerformed = Array.from(servicesPerformedElement?.querySelectorAll('li') || []) | |
.map(li => li.textContent.trim()) | |
.join(', '); | |
const shop = shopElement ? shopElement.textContent.trim() : ''; | |
const shopLink = shopLinkElement ? shopLinkElement.href : ''; | |
// Use Markdown formatting for the shop name with a link | |
const notes = shopLink ? `[${shop}](${shopLink})` : shop; | |
// Add to service records | |
serviceRecords.push({ | |
Date: dateServiced, | |
Odometer: parseInt(odometer, 10), // Ensure numeric value | |
Description: servicesPerformed, | |
Notes: notes, | |
Cost: 0 // Numeric cost | |
}); | |
}); | |
// Log records to the console or export as CSV | |
console.table(serviceRecords); | |
// Optionally download as CSV | |
const csvContent = "data:text/csv;charset=utf-8," + | |
["Date,Odometer,Description,Notes,Cost"] | |
.concat(serviceRecords.map(record => | |
`"${record.Date}",${record.Odometer},"${record.Description}","${record.Notes}",${record.Cost}`) | |
).join("\n"); | |
const encodedUri = encodeURI(csvContent); | |
const link = document.createElement("a"); | |
link.setAttribute("href", encodedUri); | |
link.setAttribute("download", "service_records.csv"); | |
document.body.appendChild(link); | |
link.click(); | |
document.body.removeChild(link); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment