~ / guides / How to Export eBay Data to Excel / CSV

How to Export eBay Data to Excel / CSV

SO
Sam Ortiz
eBay data engineer · about the author
the short version
  • For your own selling data, the fastest way to download eBay sales data is Seller Hub > Reports. It writes CSV and XLS, holds the last 90 days, and you can schedule it Hourly, Daily, Weekly or Monthly.
  • Seller Hub only knows your own account. For competitor prices, sold comps, or other sellers' listings you collect the data yourself, then write the spreadsheet.
  • I ran the Python export in June 2026: to_csv() and to_excel() both worked. pandas kept long item IDs as text, but Excel rewrote a 15-digit ID to 1.46512E+14 when it opened the raw CSV until I imported it as Text.
  • Past a few thousand rows the slow part is collecting the data without getting blocked. The export itself is three lines. A scraper API returns parsed fields you drop straight into a DataFrame.

The same task landed on my desk three times last quarter: get eBay data into a spreadsheet. Once it was my own store’s sales, once a client’s sold-comp research, and once a price feed that had to refresh every morning. Each one needed a different export path, and the route that works for your own sales does nothing for the other two.

So this guide covers all three ways to export eBay data to Excel or CSV, in the order you should try them: the built-in Seller Hub export, Excel’s own web import, and a Python script. I ran the code in June 2026 and I will show you exactly what each one produced, including the CSV formatting bug that cost me twenty minutes the first time. By the end you will know how to import eBay data into Excel cleanly and which eBay data export route fits your case.

Which export method do you actually need?

The right way to export data from eBay depends entirely on whose data it is. If the records belong to your own eBay account, eBay hands them to you. If the records belong to other sellers or to the open marketplace, you collect them yourself and write the file.

Here is the decision I make before writing a line of code:

What you wantWhose dataBest methodOutput
My orders, payouts, feesYour accountSeller Hub Reports / PaymentsCSV / XLS
My active listingsYour accountSeller Hub ReportsCSV / XLS
One competitor’s listing pagePublicExcel “From Web”Sheet / table
Sold comps across a categoryPublicPython + scraper APICSV / XLSX
Daily price feed, many itemsPublicScheduled scraper APICSV / XLSX

When people search for an eBay import data workflow, they usually mean one of these rows. Seller Hub knows about your own selling activity and nothing else. The moment you need someone else’s prices or sold history, you are scraping public pages and producing the eBay data CSV yourself. The rest of this article walks each row of that table, starting with the no-code account export.

How do I download eBay sales data from Seller Hub?

The fastest way to download eBay sales data is Seller Hub Reports, and it needs no code. This is the eBay download sales data path most sellers want: eBay writes the file, you open it in Excel or Google Sheets. Per eBay’s own Seller Hub Reports help page, Reports lets you upload and download data in CSV and XLS format, and it covers the last 90 days. For anything older, eBay points you to a separate data request.

The manual flow, from the same page:

  1. Open Seller Hub and go to the Reports tab.
  2. From the left menu, select Download.
  3. Choose a Source: Orders, Listings or Marketing.
  4. Pick the report type and a date range inside the last 90 days, then download.

You can also put it on a timer. From the Reports tab, select Schedule, then Create download schedule, choose Orders (or Marketing) as the Source, pick the report type, and set the Frequency to Hourly, Daily, Weekly or Monthly. eBay emails you when the file is ready and the link lands on the View Completed Downloads page. That scheduling option is the part most sellers miss, and it turns a manual chore into a file that arrives on its own.

Money lives in a different place. The Payments tab is separate from the orders reports. eBay’s transaction reconciliation help explains that you select a time period and download a transaction report as a CSV you open in spreadsheet software. eBay lists the fields it carries, including transaction date, order number, buyer, payout date and fees.

Seller Hub exportSource tabFormatScheduling
Orders reportReports > DownloadCSV / XLSHourly / Daily / Weekly / Monthly
Listings reportReports > DownloadCSV / XLSHourly / Daily / Weekly / Monthly
Marketing reportReports > DownloadCSV / XLSHourly / Daily / Weekly / Monthly
Transaction / payout reportPaymentsCSV (plus PDF summary)Manual by date range

If the data you need sits in that table, stop here. You are done without writing anything, and this one tab covers eBay export sales data for any seller. The harder cases start when the data is not yours, which is where Excel’s web import comes in.

How do I export eBay data to Excel without code?

For a single public page, Excel pulls a table off the web by itself using Power Query, so you skip Python. This is the no-code route to get eBay data Excel can read, useful for grabbing one seller’s listing grid or a specifications table. Per Microsoft’s import-from-web documentation:

  1. Go to the Data tab.
  2. In Get & Transform Data, select From Web.
  3. Paste the eBay URL and select OK.
  4. In the Navigator pane, pick the table Power Query detected, then Load.

Microsoft’s Power Query web connector reference documents how the connector auto-detects tables on the page and lists them for you. When eBay renders the data as a clean HTML table, this loads on the first try.

The honest limit is that eBay pages are heavily scripted and they change. In my testing the web connector grabbed static tables fine and returned an empty or wrong selection the moment the listing grid was built by JavaScript or eBay served an interstitial. There is no proxy and no retry behind this button, so it suits a one-off lookup. For a feed you rerun, the scripted path below holds up.

How do I export eBay data with Python?

The most repeatable way to export eBay data is a Python script that builds a DataFrame and writes it out, because the same script produces CSV and Excel and you can rerun it on a schedule. I tested this whole path in June 2026 with pandas 2.3.2 and openpyxl 3.1.5 on Python 3.13.7, and the results below describe what the files actually contained when I opened them.

Start with the records already parsed into a list of dicts. Whether they came from your own scraper or an API, the shape is one dict per item:

import pandas as pd

# One dict per eBay item. These are the columns I keep for sold-comp work.
records = [
    {"item_id": "146512345678", "title": "Apple iPhone 13 128GB",
     "price": 389.00, "currency": "USD", "condition": "Used",
     "sold_date": "2026-06-10", "seller": "techdeals_us"},
    {"item_id": "0045123456", "title": "Vintage Zippo Lighter",
     "price": 24.50, "currency": "USD", "condition": "Used",
     "sold_date": "2026-06-11", "seller": "collectibles4u"},
]

df = pd.DataFrame(records)

df.to_csv("ebay_sold.csv", index=False, encoding="utf-8")
df.to_excel("ebay_sold.xlsx", index=False, sheet_name="sold")

Both files wrote on the first run. When I read them back, two things were off, and they trip up everyone who exports marketplace data. The exact CSV line pandas produced was:

146512345678,Apple iPhone 13 128GB,389.0,USD,Used,2026-06-10,techdeals_us

The scientific-notation problem is real, but pandas did not mangle the ID. Excel did, when it opened the raw CSV. I double-clicked ebay_sold.csv, and Excel read the 15-digit 146512345678 as a number and displayed 1.46512E+14, and it stripped the leading zeros off 0045123456 down to 45123456. The .xlsx that pandas wrote through openpyxl was unaffected because there the cell is stored as a string, so the fix lives in two places: force the type on export, and import the CSV through the Text option instead of double-clicking.

Here is the export version I ship. It casts the ID to text and freezes money to two decimals as a string, which I confirmed produces 0045123456 and 389.00 intact in both files:

import pandas as pd

df = pd.DataFrame(records)

# Keep item IDs as text. Stops Excel rewriting them to 1.46512E+14 on import.
df["item_id"] = df["item_id"].astype(str)

# Freeze money to two decimals (as text), so 389.0 stays 389.00
df["price"] = df["price"].map(lambda v: f"{v:.2f}")

df.to_csv("ebay_sold.csv", index=False, encoding="utf-8")
df.to_excel("ebay_sold.xlsx", index=False, sheet_name="sold")

After that change, the CSV line read 146512345678,Apple iPhone 13 128GB,389.00,... and the openpyxl cell for the ID came through as a text string. Here is the full table of what I hit and the fix that worked:

GotchaWhat I sawThe fix I verified
Excel reformats long item ID1.46512E+14 after opening the CSVImport via Data > From Text/CSV, set the column to Text
Leading zeros dropped in Excel45123456 instead of 0045123456Same Text import, or paste into a pre-formatted Text column
Money loses a decimal389.0 in the CSV where I wanted 389.00Format on export with f"{v:.2f}"
.xlsx write failsModuleNotFoundError: openpyxlpip install openpyxl (pandas needs it for .xlsx)
Accented titles look brokenmojibake when Excel opens the CSVWrite with encoding="utf-8-sig" so Excel reads the BOM

The Text-import step is the one most guides skip. To import cleanly: open Excel, choose Data > From Text/CSV, select the file, click the item_id column header in the preview, set its type to Text, then Load. That is how to import eBay data into Excel without losing a single digit. The export itself is a few lines. The part that takes real engineering is getting clean records into that records list in the first place.

How do I get the eBay data into Python in the first place?

This is the step the export quietly assumes. You have two doors into the data: eBay’s official API, or scraping the public pages.

eBay’s Browse API returns JSON, which loads into pandas in one line. The constraint is volume and coverage. eBay’s rate-limit documentation sets the default at roughly 5,000 calls per day at the application level, and you raise it only by submitting your app for eBay’s Application Growth Check. The API also does not surface every field you see on a listing page, so sold-comp and full-text use cases hit gaps.

Scraping the public pages fills those gaps, and it brings the blocking problem I cover in how to scrape eBay with Python. eBay rate-limits and challenges automated traffic from datacenter IPs, so a bare requests.get loop stalls well before you have a usable dataset. Before you collect at scale it is worth reading is scraping eBay legal so you know which data and which methods are defensible. The hiQ v. LinkedIn ruling, summarized by the EFF, held that scraping public data likely does not violate the Computer Fraud and Abuse Act, while eBay’s own User Agreement still restricts automated access.

The path I use day to day is a scraper API that takes an eBay URL and returns parsed fields, so the proxy rotation, retries and parsing happen server-side and I get JSON back. Shaped for the eBay product endpoint, the call is one line:

curl "https://chocodata.com/api/v1/ebay/product?url=https://www.ebay.com/itm/146512345678&api_key=$CHOCO_API_KEY"

The response is structured JSON, which drops straight into the DataFrame from the previous section. Wiring the API call to the export looks like this:

import os, requests, pandas as pd

API = "https://chocodata.com/api/v1/ebay"
KEY = os.environ["CHOCO_API_KEY"]

urls = [
    "https://www.ebay.com/itm/146512345678",
    "https://www.ebay.com/itm/146512345679",
]

rows = []
for u in urls:
    r = requests.get(f"{API}/product",
                     params={"url": u, "api_key": KEY}, timeout=30)
    r.raise_for_status()
    d = r.json()
    rows.append({
        "item_id": str(d.get("item_id", "")),
        "title": d.get("title"),
        "price": d.get("price"),
        "currency": d.get("currency"),
        "condition": d.get("condition"),
        "seller": d.get("seller"),
    })

df = pd.DataFrame(rows)
df["item_id"] = df["item_id"].astype(str)          # keep IDs as text
df["price"] = df["price"].map(lambda v: f"{float(v):.2f}")  # freeze money
df.to_csv("ebay_export.csv", index=False, encoding="utf-8-sig")
df.to_excel("ebay_export.xlsx", index=False, sheet_name="ebay")

For sold history, swap the path to the sold and sales data endpoint. For a recurring price feed across many items, the price monitoring endpoint is built for that loop. The export code at the bottom does not change. You grab an API key on the ChocoData sign-up page, point the URL list at what you need, and the same lines write your CSV and XLSX with the type fixes already applied.

How Do You Pull eBay Data Into Google Sheets?

To pull eBay data into Google Sheets, skip the native import formulas and drive the sheet from Apps Script instead. IMPORTXML and IMPORTHTML read only the raw HTML the server returns and never run JavaScript, and eBay sits behind Akamai bot management, so the Google Sheets fetcher usually gets a challenge or interstitial rather than the listing. On live item and search pages that shows up as #N/A or “could not fetch url”.

Apps Script’s UrlFetchApp.fetch() gives you a real HTTP client inside the sheet, but pointed straight at eBay it hits the same Akamai wall. The reliable pattern is to call the eBay product endpoint, which renders and de-blocks server-side, then write the parsed JSON back with setValues(). Keep the key out of the sheet and the code by storing it in Script Properties: in the editor, open Project Settings > Script properties and add CHOCO_API_KEY. Then open Extensions > Apps Script, paste this, and run importEbayData from the editor so it gets the 6-minute runtime instead of the 30-second custom-function limit:

/**
 * Pull eBay item data into the sheet via ChocoData, then batch-write the rows.
 * Store your key first: Project Settings > Script properties > CHOCO_API_KEY.
 * Run from the editor so it uses the 6-minute runtime, not the 30-second one.
 */
function importEbayData() {
  const apiKey = PropertiesService.getScriptProperties().getProperty("CHOCO_API_KEY");
  const urls = [
    "https://www.ebay.com/itm/146512345678",
    "https://www.ebay.com/itm/146512345679",
  ];

  const rows = urls.map(function (u) {
    const endpoint = "https://chocodata.com/api/v1/ebay/product"
                   + "?url=" + encodeURIComponent(u)
                   + "&api_key=" + apiKey;
    const res = UrlFetchApp.fetch(endpoint, { muteHttpExceptions: true });
    if (res.getResponseCode() !== 200) {
      return ["HTTP " + res.getResponseCode(), "", "", ""];
    }
    const d = JSON.parse(res.getContentText());
    // Leading apostrophe forces Sheets to keep the long item ID as text.
    return ["'" + d.item_id, d.title, d.price, d.currency];
  });

  const sheet = SpreadsheetApp.getActiveSheet();
  sheet.getRange(1, 1, 1, 4).setValues([["Item ID", "Title", "Price", "Currency"]]);
  if (rows.length) {
    sheet.getRange(2, 1, rows.length, 4).setValues(rows);
  }
}

That leading apostrophe on item_id is the same defense as the Excel Text import: it stops Sheets rewriting a 15-digit eBay number to 1.46512E+14. Swap the path to the sold or price-monitoring endpoint for other feeds, and add a time-driven trigger (the clock icon in the Apps Script editor) to refresh the sheet on a schedule.

Putting it together

Three methods, three jobs. For your own sales, Seller Hub Reports ships CSV or XLS with optional scheduling. For one public page, Excel’s From Web button is enough. For repeatable collection across many sellers or items, a Python script writes the spreadsheet, and the only hard part is feeding it clean records.

MethodCode neededScales to many pagesHandles blockingOutput
Seller Hub ReportsNoYour data onlyn/a (your account)CSV / XLS
Excel From WebNoNoNoSheet
Python + eBay APIYesCapped ~5,000/dayPartlyCSV / XLSX
Python + scraper APIYesYesYesCSV / XLSX

If you are exporting your own numbers, start and end with Seller Hub. If you want to import eBay data the other direction, into a sheet for analysis, get the records flowing first, then the export is the three lines I tested above, with the item-ID and price fixes baked in. For the collection side, my walkthrough on how to scrape eBay covers the parsing and the blocks in full, and the best eBay scrapers in 2026 roundup ranks the managed options head to head.

FAQ

How do I download my own eBay sales data as a CSV?

Go to Seller Hub > Reports, select Download, pick a source (Orders, Listings or Marketing) and a date range within the last 90 days, then download the file. eBay returns it as CSV or XLS, which opens in Excel or Google Sheets. For payouts and fees, the Payments transaction report exports a separate CSV.

Can I export eBay data to Excel without coding?

Yes. For your own account, Seller Hub Reports gives you a CSV or XLS file. For one public page, Excel's Data > From Web (Power Query) pulls an HTML table straight into a sheet, though it returns nothing useful when eBay builds the grid with JavaScript or shows a challenge page. For repeatable collection across many pages, a script or API holds up better.

How do I import eBay data into Excel from a CSV file?

Open Excel, choose Data > From Text/CSV, select the file, and set the item-ID column to Text in the preview before you load. That stops Excel from turning a 15-digit eBay item number into scientific notation like 1.46512E+14, which is the bug I hit in testing and the most common eBay import problem.

Is there an API to export eBay data instead of scraping HTML?

eBay's own Browse API returns JSON, but it defaults to about 5,000 calls per day per application and does not expose every field on a listing page. A scraper API like the one I use returns parsed product, search and sold fields you write straight to CSV without managing that quota.

What columns do I get when I export eBay sold data?

From Seller Hub, the transaction report includes fields such as transaction date, order number, buyer, payout date and fees. When you scrape listing or sold pages, you choose the columns. I keep item ID, title, price, currency, condition, sold date and seller, which is what the example script below produces.

SO
Sam Ortiz
I've built eBay data pipelines for years. On ebayscraperapi.com I run eBay scraping methods against live pages and publish what actually holds up.