IMPORTHTML pulls a table or a list from a web page into your sheet and refreshes it automatically. It is the easiest way to bring public data, such as rankings, price tables, sports results or Wikipedia tables, into a spreadsheet without writing any code.
Syntax
=IMPORTHTML(url, query, index)
url: The address of the web page, in quotes (or in a cell), includinghttps://.query: Either"table"or"list": which kind of element to import.index: Which table or list on the page, starting from 1, in the order they appear in the page's HTML.
Basic examples
=IMPORTHTML("https://en.wikipedia.org/wiki/List_of_largest_companies_by_revenue", "table", 1)
Imports the first table on the page. Change 1 to 2 for the second table, and so on.
=IMPORTHTML("https://example.com/page", "list", 1)
Imports the first bulleted or numbered list.
Finding the right index
The index counts every <table> (or list) on the page, including ones that are hidden or look like layout. There is no visual way to see the number, so the practical approach is to try values until the right table appears:
- Start with
1. - Increase the number until you find the table you want.
- If you get an error for a high number, the page has fewer tables than that.
What the result looks like
The table spills into the cells below and to the right, including the header row. Numbers are converted to numbers where possible, though values with currency symbols, footnotes or text units stay as text. The result needs empty space; if anything blocks the spill area, you get #REF!.
Practical patterns
Pick a few columns
Use QUERY on the imported table, referring to columns as Col1, Col2, and so on:
=QUERY(IMPORTHTML("https://example.com/stats", "table", 1), "select Col1, Col3 where Col3 > 100", 1)
Clean up numbers
Imported numbers often contain symbols, footnote markers or thousand separators. Clean them with REGEXREPLACE and VALUE:
=ARRAYFORMULA(IFERROR(VALUE(REGEXREPLACE(B2:B, "[^0-9.]", ""))))
Get one cell from a table
=INDEX(IMPORTHTML("https://example.com/stats", "table", 1), 3, 2)
Returns the cell in the 3rd row and 2nd column, which is handy for pulling a single number, such as a current rate, into a model.
Build the URL from a cell
=IMPORTHTML("https://example.com/team/" & A2, "table", 1)
Change A2 and the table updates.
Flip the orientation
=TRANSPOSE(IMPORTHTML("https://example.com/stats", "table", 1))
Keep a snapshot
Imported data refreshes and the page may change or disappear. To keep a fixed copy, copy the cells and paste as values only.
Limits and refresh
- Public pages only. The page must be reachable without logging in. Pages behind a login or paywall return nothing.
- Static HTML only.
IMPORTHTMLreads the HTML the server sends. Tables built later by JavaScript (many modern dashboards) are not visible to it. If you see the table in your browser butIMPORTHTMLcan't find it, this is the likely reason. Look for a page that serves the table as plain HTML, or for an API or CSV link, and useIMPORTDATAorIMPORTXML. - Refresh rate. Imported data refreshes periodically (roughly hourly), not instantly. Editing the formula forces a fresh fetch.
- Request limits. Many
IMPORTHTMLcalls in one spreadsheet can lead to "Loading..." or errors. Import once into a data sheet and refer to it. - Blocking. Some sites block automated requests, and
IMPORTHTMLthen returns an error. - Terms of use. Check that the site allows this use of its data.
Common errors
#N/A: "Imported content is empty". The table index doesn't exist, the page is built with JavaScript, or the site blocked the request.#N/Aor error: "Could not fetch URL". The URL is wrong, the site is down or blocking, or the page needs a login.#VALUE!: "Resource at url contents exceeds maximum size". The page is too large. Try a lighter page, or another source.- An error about the query argument.
querymust be exactly"table"or"list", in quotes. #REF!: "Array result was not expanded". Cells in the spill area are not empty.- Wrong table. The index points at a different table than you expected. Try neighboring numbers.
- The layout changed. The site changed its page, shifting the table index. Re-check the index when results go wrong.
IMPORTHTML vs. IMPORTXML vs. IMPORTDATA vs. IMPORTRANGE
IMPORTHTML: tables and lists on a web page.IMPORTXML: any element of a web page or XML file, selected with XPath. More flexible, and more technical.IMPORTDATA: a CSV or TSV file from a URL.IMPORTRANGE: a range from another Google Sheet.IMPORTFEED: RSS and Atom feeds.
Frequently asked questions
How do I know which table number to use? Try 1, 2, 3 until the right one appears.
Can it import several tables at once? One call imports one table. Use several formulas.
Can it import pages that need a login? No.
Why is the table missing even though I see it in my browser? It is probably generated by JavaScript.
Related Functions
IMPORTXML: Import data from web pages with XPath.IMPORTDATA: Import a CSV file from a URL.IMPORTRANGE: Import a range from another spreadsheet.QUERY: Filter and aggregate imported data.INDEX: Pick a value from the imported table.