
Last Update: March 22, 2022 6 min read
BY
eric
Export an HTML Table to CSV or JSON in Chrome with Mr. Table
Mr. Table is a small Chrome extension I wrote at TYO Lab. It reads the tables on the page you're looking at and saves them as CSV or JSON. It handles normal HTML <table> tables out of the box, and "tables" built from <div> tags if you tell it which CSS selectors to use.
The short version:
- Install Mr. Table from the Chrome Web Store and pin it to the toolbar.
- Open the page with the table and click the Mr. Table icon.
- Pick CSV or JSON under Output Format.
- Click Export All. A window lists every table it found. Flick to the one you want and click Download.
- If the page uses
<div>tables, open Advanced Options first and set the five selectors (explained below).
I built it because data I needed for work was often only published as a web page table. One example from the original version of this post: the ASX code changes table, which I wanted for my algorithmic trading system.
When to use it (and when not to)
There are other ways to get a table out of a web page. Pick the one that fits:
Install and pin it
Install it from the Chrome Web Store with Add to Chrome. Then open the puzzle-piece Extensions menu and pin Mr. Table so the icon stays on the toolbar. The icon looks like this:

Clicking it opens this popup:

Exporting a normal HTML table
A standard HTML table is built from these tags:
<table>wraps the whole thing<thead>and<tbody>group the header and body (optional)<tr>is a row<th>is a header cell<td>is a data cell
For tables like that you don't need to change anything. These are the defaults under Advanced Options:

Header and data rows can both be tr because the exporter only treats a row as a header if it contains header cells, and as a data row if it contains data cells. In the underlying table-exporter library this is literally tr:has(th) and tr:has(td).
Example: the ASX code changes table
The ASX publishes ticker code and name changes on its ASX code changes page. With the default selectors, Export All found the tables on the page and showed each one in the preview window, with a Download button per table:

Two things to notice in that screenshot:
- It found several tables. The dots at the bottom are one per table. Use the arrows or dots to get to the one you want, then click Download. If you only want one table, it's quicker to click inside it on the page first and use Export Selected.
- Grouped headers come out with blanks. The ASX table has "Old details" and "New details" headings that each span two columns (code and name). The export has one header cell per heading, so two columns end up with no name. Rename them in your spreadsheet or code after export.
Here's the same thing on a Wikipedia article, in an earlier build of the extension. It found six tables on that page:

Exporting a div (CSS) table
Many sites don't use <table> at all. They build a grid out of <div> tags and use CSS to lay it out. The default selectors find nothing on those pages, so you have to tell Mr. Table what the table, rows and cells look like.
Here's a small div table rendered with CSS:
And its HTML:
<div class="table">
<div>
<div class="table-header">
<div class="table-header-cell">ID</div>
<div class="table-header-cell">Name</div>
<div class="table-header-cell">Age</div>
</div>
</div>
<div>
<div class="table-row">
<div class="table-cell">1</div>
<div class="table-cell">John Doe</div>
<div class="table-cell">23</div>
</div>
</div>
<div>
<div class="table-row">
<div class="table-cell">2</div>
<div class="table-cell">John Smith</div>
<div class="table-cell">37</div>
</div>
</div>
</div>
The selectors map straight onto the class names:
Enter them under Advanced Options:

Then click Export All. The preview shows the two data rows:

Finding the selectors on a real site
Real sites rarely use class names as tidy as .table-row. To find them:
- Right-click a cell in the table and choose Inspect. Chrome DevTools opens with that element highlighted.
- Walk up the tree in the Elements panel. Note the class of the cell, the row that wraps the cells, and the element that wraps all the rows.
- Prefer class names that describe the structure (
row,cell,item) over long generated ones likecss-1x2ab3. Generated classes can change on the next site deploy. - Check a selector before you use it. In the DevTools Console, run:
document.querySelectorAll('.table-row').length
It should return the number of rows you can see. Zero means the selector is wrong. A much bigger number means it's matching more than the table.
A few CSS selector reminders:
.namematches a class,#namean id,diva tag..row.header(no space) matches an element with both classes..list .row(with a space) matches.rowelements anywhere inside.list.- Lists work too. For a
<ul>where each<li>is a row, uselias the row selector and whatever is inside it as the cell selector.
Troubleshooting
Nothing is found. Either the selectors don't match (check them in the Console as above), or the table hasn't loaded yet. Scroll it into view or wait until the data appears, then run the export again. Mr. Table can only see what's on the page right now. For paginated or "load more" tables, it only gets the rows currently shown.
No header row. The header row selector has to match a row that contains the header cell selector. If the site uses the same class for header and data cells, set the header cell selector to something only the header has, or rename the columns after export.
Columns are shifted in the CSV. Check for commas inside cells, such as "1,234" or "Smith, John". If those cells aren't quoted in your file, a spreadsheet will split them into two columns. Export as JSON instead and the cell values stay intact.
Export Selected doesn't pick the table you want. Click on a cell inside the table you want (or select some of its text) before opening the popup.
Respect the site. Exporting a table you can already see is fine for personal use. Check the site's terms before reusing or republishing the data, and don't use a browser extension to bulk-scrape.
Doing it in code instead
The extension is built on my table-exporter library, which you can also use in Node.js. The current version is table-exporter-ts (also on npm as table-exporter-ts). The older table-exporter repo is deprecated. Both take the same idea, a table selector plus header, row and cell selectors, and return each table as headers and rows, ready to save as CSV or JSON.
If you want to go further with market data in code, see building a trading gateway with the MT5 Python library for getting prices straight from a broker's API instead of from web pages.
Feedback
Mr. Table is free. If a table on a public page won't export, let me know the URL:
- X: Eric Tang
- Email: [email protected]
Previous Article
Next Article
Mar 22, 2022








Comments (0)
Leave a Comment