Skip to content
Calquer

Export Website Data to Google Sheets (IMPORTHTML vs No-Code Tools)

By M H TawfikUpdated 12 min read

google sheetsimporthtmlno-code scraping

You can import data from a website to Google Sheets with one formula: type =IMPORTHTML("https://example.com/page", "table", 1) into any cell and Sheets fetches the page and fills in the first table it finds. Use IMPORTXML to grab specific elements and IMPORTDATA for URLs that point straight at a CSV file. When the page is rendered by JavaScript or sits behind a login, those formulas return #N/A — the fix is a no-code extension that collects the rows from the live page and pastes them into Sheets.

This guide walks through all three import formulas with copy-paste examples, the limits they share, the six errors you will actually hit, and the extension workflow for the pages formulas cannot reach.

How does IMPORTHTML pull a website table into Google Sheets?

IMPORTHTML asks Google's servers to fetch a URL, find the Nth table or list in the HTML, and spill its rows into your sheet. It takes three arguments: the page URL, the element type ("table" or "list"), and a 1-based index that says which table or list you want.

=IMPORTHTML("https://en.wikipedia.org/wiki/List_of_countries_by_population", "table", 1)

Paste that into cell A1 of a blank sheet and the population table appears, headers included. The three arguments in detail:

  • URL. The full address in quotes, including https://. It must be a public page — no login, no paywall.
  • "table" vs "list". Use "table" for real <table> elements (stats pages, schedules, financial data). Use "list" for <ul> or <ol> lists — rankings, link directories, bullet-point specs. Each list item becomes one row.
  • Index. 1 grabs the first matching element on the page, 2 the second, and so on. Pages often contain hidden navigation or layout tables, so the table you see first is not always index 1.

How do I find the right table index?

Instead of guessing indexes one at a time, probe them all at once. Put the URL in cell A1, paste this in B1, and drag it down ten rows:

=INDEX(IMPORTHTML($A$1, "table", ROW()), 1, 1)

Each row now shows the first cell of table 1, table 2, table 3, and so on — without the full arrays colliding with each other. Scan the column, spot the cell that matches your data, and that row number is your index. Delete the probes and write the real formula.

How do I extract specific elements with IMPORTXML?

IMPORTXML pulls individual elements — headings, links, prices, meta tags — using an XPath query instead of a table index. XPath is a path language for HTML: //h2 means "every <h2> anywhere on the page," //a/@href means "the href attribute of every link," and [@class='price'] filters by attribute value.

The three pieces of XPath that cover most spreadsheet jobs:

  • //tag — every element of that type, anywhere in the page.
  • //tag[@attribute='value'] — only elements whose attribute matches (use single quotes inside the XPath so they do not clash with the formula's double quotes).
  • /@attribute — return the attribute's value instead of the element's text.

Two copy-paste recipes. First, pull every heading and every link URL from a page — useful for outlining a competitor's article or auditing a resources page:

=IMPORTXML("https://example.com/page", "//h2")
=IMPORTXML("https://example.com/page", "//a/@href")

Second, grab a page's title and meta description — handy for building a quick content inventory across a list of URLs:

=IMPORTXML("https://example.com/page", "//title")
=IMPORTXML("https://example.com/page", "//meta[@name='description']/@content")

Point the second recipe at a column of URLs with cell references and you have a lightweight metadata audit in five minutes. The catch: XPath only matches what exists in the raw HTML the server sends. If a price or heading is injected by JavaScript after load, the query returns empty no matter how correct it is.

When should I use IMPORTDATA instead?

Use IMPORTDATA when the URL already points at a .csv or .tsv file rather than a web page. Many government portals, open-data sites, and reporting tools expose a direct file link — right-click a "Download CSV" button and choose Copy link address to find out.

=IMPORTDATA("https://example.com/exports/prices.csv")

Sheets fetches the file and splits it into columns automatically — no index, no XPath. Because the source is already structured data, this is the most reliable of the three formulas: there is no HTML parsing to go wrong. If a site offers a CSV endpoint, prefer it over scraping the rendered page every time.

What can't the IMPORT formulas do?

All three formulas share one architecture and therefore one set of limits: Google's servers fetch the raw HTML, and your sheet gets whatever was in that first response. That single fact explains nearly every failure:

  • No JavaScript-rendered content. Modern web apps ship an empty shell and draw the rows with scripts. The formulas never run those scripts, so the data simply is not there. You get #N/A with "Imported content is empty."
  • No login walls. The fetch comes from Google, not from your browser session. Dashboards, CRMs, member areas, and anything behind a cookie wall return a login page — or nothing.
  • #N/A and "Loading…" are routine. Beyond JS pages, you will see these when an index or XPath misses, or when your sheet queues too many fetches at once.
  • Refresh is roughly hourly, on Google's schedule. Imported data re-fetches about every hour while the sheet is open. You cannot set the interval or trigger a refresh on demand from the formula itself.
  • There is a fetch quota. A sheet stacked with dozens of import formulas will throttle, leaving some cells stuck on "Loading…" indefinitely.
  • Some sites block Google's fetcher. Because the request comes from a known Google source, sites that disallow automated access can refuse it outright. The formula fails even though the page opens fine in your browser.

A quick diagnostic: right-click the page and choose View page source, then search for a value you can see on screen. If it is not in the source, the content is JavaScript-rendered and no IMPORT formula will ever reach it.

Is Apps Script the step up?

Partly. Google Apps Script's UrlFetchApp gives you a programmable fetch with custom headers, error handling, and time-driven triggers for real scheduling:

const html = UrlFetchApp.fetch("https://example.com/page").getContentText();

You then parse the HTML yourself and write rows with setValues(). That buys control over when and how you fetch — but it is code, and it still neither executes the page's JavaScript nor carries your login session. For dynamic or gated pages, Apps Script hits the same wall with more effort.

How do I get JavaScript or logged-in pages into Sheets?

Use a browser extension that reads the live, fully rendered page and hands the rows to Sheets. Because it runs inside your own browser — Chrome, Firefox, or Edge — it sees the page after scripts run and with your login session, which is exactly what the IMPORT formulas cannot do. A no-code collector such as Calquer detects the repeating list, grid, or table on the page automatically, gathers every row, and gets the result into Sheets in one of two ways.

The full workflow:

  1. Open the page with the data — a product grid, a results list, a dashboard table — and let it finish loading.
  2. Launch the extension. It scans the rendered page and highlights the largest repeating pattern; no XPath or CSS selectors to write.
  3. Confirm the columns: toggle off what you do not need and rename the rest in plain English.
  4. Start collecting. The tool auto-scrolls lazy-loaded lists and follows "Next page" controls, so scroll-loaded and paginated rows all land in one dataset. The mechanics are covered in scrape infinite scroll and pagination to CSV.
  5. Get it into Sheets either way:
    • Copy to clipboard → click into cell A1 of your sheet → paste. The rows arrive as proper columns immediately.
    • Download CSV → in Sheets choose File → Import → Upload, pick the file, and select Replace current sheet or Insert new sheet(s). (JSON and TSV exports are there too if you need them.)

The clipboard route is the fastest path from "data on a page" to "data in a spreadsheet" — there is no file to manage at all. The CSV route is better when you want to keep a dated snapshot or share the raw file; the broader method works for any layout, as shown in how to export any website to CSV without code.

Everything happens on your device: the extension reads the page you are already viewing and nothing is uploaded to a server. For logged-in dashboards and internal tools, that is the difference between possible and off-limits.

Which method should you use?

Match the tool to the page, not the other way around. The formulas win on auto-refresh for static public pages; the extension wins everywhere the formulas go blind.

SituationBest tool
Static public <table> you want to auto-refreshIMPORTHTML with "table"
Ranked or bulleted list on a static pageIMPORTHTML with "list"
Specific elements — titles, links, meta tagsIMPORTXML with an XPath
URL that points straight at a .csv / .tsv fileIMPORTDATA
Scheduled fetches, custom headers, JSON APIsApps Script (UrlFetchApp)
JavaScript-rendered lists, grids, and div "tables"No-code extension
Infinite scroll or multi-page paginationNo-code extension
Logged-in dashboards and internal toolsOn-device extension
One-off grab you will never refreshExtension copy-to-clipboard

If Excel is your real destination rather than Sheets, the same decision logic applies with Power Query in the IMPORTHTML seat — see website to Excel for that side of the fence.

Why is IMPORTHTML returning #N/A, "Loading…", or #REF!?

Nearly every IMPORTHTML failure is one of six problems. Work down this list in order:

  1. #N/A — "Imported content is empty." The most common error. Either the table index is wrong, or the content is JavaScript-rendered and absent from the raw HTML. Run the index-probe trick from above; if no index returns your data, check the page source. Content missing from the source needs a rendered-page tool, not a different index.
  2. Stuck on "Loading…" Your sheet has hit Google's fetch quota or the request is queued. Reduce the number of import formulas (one formula pulling a whole table beats twenty pulling single cells), close and reopen the sheet, or cut the formula and paste it back to force a fresh fetch.
  3. #REF! — "Array result was not expanded." The import worked, but cells below or to the right of the formula already contain data, so the array has nowhere to spill. Clear the range under and beside the formula cell.
  4. #VALUE! or "Could not fetch URL." The URL is malformed — missing https://, stray spaces, smart quotes from a word processor — or the site refuses Google's fetcher. Retype the URL by hand with straight quotes. If the page opens in your browser but the formula still fails, the site is blocking automated access and no formula tweak will fix it.
  5. #ERROR! — "Formula parse error." A syntax issue, and very often a locale issue: in many European locales Sheets expects semicolons between arguments, as in =IMPORTHTML("url"; "table"; 1). Also re-check that every quote is a straight quote, not a curly one.
  6. Wrong or scrambled data comes back. The formula imported a layout or navigation table instead of your target (fix the index), or the "table" you see is really a styled <div> grid with no <table> markup — IMPORTHTML cannot see those at all. Merged cells (rowspan/colspan) can also shift values across columns. For div grids and merged-cell messes, collect from the rendered page instead.

FAQ

How do I import data from a website to Google Sheets automatically?

Use =IMPORTHTML("url", "table", 1) for tables, IMPORTXML for specific elements, or IMPORTDATA for direct CSV links. All three re-fetch roughly every hour while the sheet is open, so the data stays current without any action from you. The page must be public and static HTML for this to work.

Why does IMPORTHTML work on some websites but not others?

IMPORTHTML reads only the raw HTML that the server first returns. Sites that render content with JavaScript, require a login, or block Google's fetcher return #N/A or an error. Check View page source: if your data is not in the source, the formula cannot reach it and you need a tool that reads the rendered page.

Can IMPORTHTML read a page that requires login?

No. The fetch comes from Google's servers, which have no access to your session or cookies, so gated pages return a login screen or nothing. To get logged-in data into Sheets, use an on-device extension that reads the page in your own authenticated browser, then copies the rows to your clipboard or exports a CSV.

Reading public data that is already visible to you is generally fine, but it depends on the site's terms of service and whether personal data is involved — GDPR and CCPA apply to the latter. Be gentle with refresh frequency and check the site's terms. For a plain-English overview, see is web scraping legal.

What is the fastest way to paste website data straight into Sheets?

Collect the rows from the live page with an extension and use copy-to-clipboard: open your sheet, click cell A1, and paste — the rows land as proper columns instantly, with no file to import. Calquer does this for any list, grid, or table, including scroll-loaded and paginated ones, entirely on your device.


Ready to try it? Add Calquer to your browser and paste the next list, grid, or table you are viewing straight into Google Sheets — free, no code, 100% on-device.

Keep reading

← All articles