Pre-Black Friday: 20% off, for as long as you stayEARLYBFon Solo and AgencyEnds Nov 28Start free

How-to guide

How to Scrape Data from Any Website (No Code)

One formula for the page, one API call for everything the page does not tell you.

Get your free API key →Free to start. No credit card. 1,000 records to spend whenever you like.

For a public page with a table or list, one Google Sheets formula pulls it into rows with no code. For anything the page does not show, such as headcount, industry or tech stack, do not scrape each company's site. Look the company up by domain.

This guide does both, in that order. It is the short version, with the requests and the output.

TL;DR

  • Pull a public table into Google Sheets with IMPORTHTML. About 2 minutes.
  • Enrich each domain with POST /v1/companies/enrich. About 15 minutes for a first run of 10 domains, 10 records.
  • Size a bigger list for free with GET /v1/companies/count before you spend anything.

Prerequisites

  • A Google account for Sheets.
  • A LeadOcean API key from app.leadocean.io. The free plan gives 1,000 records for life, no card, 5 requests a second.
  • curl in a terminal, or any HTTP client. Export the key: export LEADOCEAN_API_KEY=your_key.
  • A public page you are allowed to read. Check its terms and robots.txt first, and never scrape pages behind a login.

Step 1: Pull the table with IMPORTHTML

IMPORTHTML fetches a table or list from a URL and writes it into the sheet. Its syntax is IMPORTHTML(url, query, index): query is "table" or "list", and index counts tables from 1 (Google Docs Editors Help, October 2026).

Put this in cell A1 of a blank sheet:

code
=IMPORTHTML("https://example.com/members", "table", 1)

If the cells stay empty, try index 2, 3 and so on. Tables rendered by JavaScript after the page loads will not appear, because the formula reads the raw HTML. For those, use a browser extension scraper, or copy the visible table by hand. The next steps work the same on any list of domains.

Step 2: Reduce it to a column of domains

Enrichment needs one key per company: the website domain. Add a column that strips the URL down.

code
=REGEXEXTRACT(C2, "^(?:https?://)?(?:www\.)?([^/]+)")

Fill it down. You want a clean column like acme.com, one row per company, no duplicates. Use Data, Data cleanup, Remove duplicates.

Step 3: Look up one company by domain

Test one row before you run the list. POST /v1/companies/enrich takes a domain or a linkedin_url (API reference, October 2026).

bash
curl -s -X POST https://api.leadocean.io/v1/companies/enrich \
  -H "x-api-key: $LEADOCEAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"domain": "acme.com"}'

A company we hold nothing for returns 404 and costs nothing. A hit costs one record.

Step 4: Replace site-by-site scraping with a filter

The usual reason to scrape a company's own site is to learn what it runs, such as live chat or a CRM. LeadOcean holds detected technologies for about 7.8M crawled sites, so you can search on them instead. First size the list. Counts are free.

bash
curl -s -G https://api.leadocean.io/v1/companies/count \
  -H "x-api-key: $LEADOCEAN_API_KEY" \
  --data-urlencode "technologyCategories=Live chat" \
  --data-urlencode "hqCountry=US"

technologyCategories takes a category from a list of 105, such as Live chat or CRM. Check exact values with GET /v1/enums/tech_category before you guess. The response is an exact total plus breakdowns by industry, headcount band, HQ country, HQ state and NAICS.

Step 5: Pull the rows you want

When the count looks right, run the same filters as a search. The body is flat JSON, filters are arrays, and limit runs 1 to 100.

bash
curl -s -X POST https://api.leadocean.io/v1/companies/search \
  -H "x-api-key: $LEADOCEAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"technologyCategories": ["Live chat"], "hqCountry": ["US"], "limit": 10}'

Each company returned is one record, so this spends 10. Page with meta.nextCursor. One search pages to 10,000 rows, then meta.depthCapped turns true. Narrow the filters instead of paging harder.

Step 6: Skip the terminal with an MCP client

If you would rather type than curl, add the LeadOcean MCP server at https://api.leadocean.io/mcp to Claude Code or another MCP client. Sign-in is OAuth, so you paste no key. Then ask:

code
Count US companies that use a live chat tool, by headcount band.
Do not pull any rows yet.

The model calls leadocean_count_companies, which is free. To run the same calls on a schedule, see the n8n integration.

What you get

Response shape from the API reference, with placeholder values. POST /v1/companies/enrich returns a data object with these top-level groups:

json
{
  "success": true,
  "data": {
    "company_data": {
      "company_name": "Acme",
      "company_domain": "acme.com",
      "company_technology_categories": ["Live chat", "Analytics"]
    },
    "company_detected_technologies": {},
    "company_metrics": {},
    "meta": { "fetched_at": "2026-10-01", "schema": "leadocean.company.v1" }
  },
  "meta": { "credits": 1 }
}

The Step 4 count is a real result. On 2026-10-21 the free leadocean_count_companies tool returned this for technologyCategories Live chat and hqCountry US (trimmed):

json
{
  "total": 11359,
  "totalIsExact": true,
  "facets": {
    "employee_range": [
      { "value": "1-10", "count": 6679 },
      { "value": "11-50", "count": 2759 },
      { "value": "51-200", "count": 977 }
    ],
    "hq_state": [
      { "value": "California", "count": 1588 },
      { "value": "Florida", "count": 1110 },
      { "value": "Texas", "count": 1037 }
    ]
  },
  "credits": 0
}

That is 11,359 companies, not people. Most are under 11 staff, so add employeeRange before you pull rows.

Troubleshooting

ErrorCauseFix
Sheet cell shows #N/A or stays emptyPage is rendered by JavaScript, or the index is wrongTry other index values. Use a browser extension scraper for JS pages.
401Missing or wrong x-api-keyCheck $LEADOCEAN_API_KEY is exported in this shell.
429Over the plan's rate limit (5 a second on Free, 200 on Agency)Honor Retry-After, then slow the loop.
402Records spent. The free plan is 1,000 for lifeAdd a plan on pricing.
Empty resultsEnum value is not exact, such as a lowercase categoryRead GET /v1/enums and copy the string as written.
meta.depthCapped is trueOne search reached 10,000 rowsSplit the search by country or headcount band.

FAQ

Is web scraping legal?

Reading public pages is generally allowed, but terms of service, copyright and privacy law still apply. Skip login-gated pages, respect robots.txt, and do not collect personal data you have no basis to hold. This is not legal advice.

What if the page loads data with JavaScript?

IMPORTHTML sees only the raw HTML, so a JS-rendered table stays empty. Use a browser extension scraper, or find the page's data download. You only need the list of domains out of it.

How many records does this guide use?

Ten enrichments or ten search rows is 10 records. Counts, 404s and empty pages are free. The free plan holds 1,000 records.

Can I scrape emails and phones from company sites?

You can, but it is slow and the hit rate is poor. Find the people with people search, then call GET /v2/people/email/work or GET /v2/people/phone with their linkedin_url or person_id. Each v2 call costs one record, even on a miss.

See also: how to scrape LinkedIn data, scrape a website into Excel or Sheets, and personalized emails from website data.

Stop scraping sites one at a time. Look the company up by domain.

Free to start. No credit card. 1,000 records to spend whenever you like.

Get your free API key →