Python HTML API
Get the fully rendered HTML of any URL with one HTTP request in Python — real Chromium under the hood, none to maintain.
GET api.microlink.io?url=microlink.io → data
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Microlink | The web, ready for AI</title>
<meta name="description" content="A single API for turning any URL into data." />
<meta property="og:image" content="https://microlink.io/images/og/home.png" />
</head>
<body>
<header class="hero">…</header>
<main>…</main>
</body>
</html>Get HTML in Python
No package and no browser — the Microlink REST API renders any URL and returns the HTML with a single HTTP GET. Here it is with urllib and json from the Python standard library.
Step 01 · Extract any URL
A few lines with the standard library — no pip install, no Chromium download. Point it at a page and read the rendered HTML from the JSON response.
fetch.py
import json
import urllib.parse
import urllib.request
params = urllib.parse.urlencode({
'url': 'https://microlink.io',
'data.html.attr': 'html'
})
with urllib.request.urlopen(f'https://api.microlink.io?{params}') as res:
data = json.load(res)['data']
print(len(data['html'])) # full rendered document
print(data['html'][:15]) # '<!DOCTYPE html>'Step 02 · Scope to a selector
Return the whole document or only the subtree you need — smaller responses, less parsing and lower token cost downstream.
selector.py
import json
import urllib.parse
import urllib.request
params = urllib.parse.urlencode({
'url': 'https://microlink.io/blog',
'data.html.attr': 'html',
'data.html.selector': 'main' # only the <main> subtree
})
with urllib.request.urlopen(f'https://api.microlink.io?{params}') as res:
data = json.load(res)['data']
# No nav, no footer — just the content you asked for
print(data['html'])Step 03 · Render JavaScript pages
Client-rendered apps only produce their markup after JavaScript runs — prerender in a real browser and wait for it, still one request.
spa.py
import json
import urllib.parse
import urllib.request
params = urllib.parse.urlencode({
'url': 'https://app.example.com',
'data.html.attr': 'html',
'prerender': 'true', # render JS in a real browser first
'waitForSelector': 'h1' # capture only when the content exists
})
with urllib.request.urlopen(f'https://api.microlink.io?{params}') as res:
data = json.load(res)['data']
print(data['html'])Step 04 · Serve the raw HTML
Ask for embed=html and the API answers with text/html directly — proxy it straight to a browser or write it to a file.
raw.py
import urllib.parse
import urllib.request
params = urllib.parse.urlencode({
'url': 'https://microlink.io',
'data.html.attr': 'html',
'embed': 'html' # respond with text/html, no JSON
})
with urllib.request.urlopen(f'https://api.microlink.io?{params}') as res:
html = res.read().decode() # ready to serve or storeDrop it into your framework
A FastAPI route, a Flask endpoint, or a page archiver — the same request becomes your own rendering endpoint.
- FastAPI
- Flask
- Archiver
- Plain Python
from flask import Flask, Response, request
import json
import urllib.parse
import urllib.request
app = Flask(__name__)
@app.route('/render')
def render():
params = urllib.parse.urlencode({
'url': request.args['url'],
'data.html.attr': 'html'
})
with urllib.request.urlopen(f'https://api.microlink.io?{params}') as res:
data = json.load(res)['data']
return Response(data['html'], mimetype='text/html')Skip the browser-farm ops
Rolling your own means running Playwright or Selenium, shipping a 300 MB Chromium binary, writing per-site wait logic, and fighting antibot walls. The API returns the rendered HTML of any page without any of the moving parts.
DIY rendering stack
- Run and patch your own headless Chromium fleet
- Write per-site wait logic for JavaScript-rendered pages
- Fight antibot walls and CAPTCHAs with your own proxy pool
- Each browser eats hundreds of MB of RAM per worker
- You build the caching, retries and autoscaling
- Every Chromium upgrade breaks a selector somewhere
Microlink for Python
- One HTTP request — no rendering infrastructure to run
- Fully rendered HTML from managed Chromium, JS included
- Selector scoping to return only the subtree you need
- Antibot and CAPTCHA resolution handled for you
- Cached responses from a global edge network
- Autoscaled fleet with a 99.9% uptime SLA
Built for the way you write Python.
A REST API that feels native in Python — one call, JSON back, and at home in anything from a script to a web framework. Read the API overview to go deeper.
Real Browser Rendering
Every request runs in managed Chromium, so client-rendered apps return complete markup instead of an empty shell.
Standard Library Only
urllib and json ship with Python — the examples run with no pip install and no Chromium binary to manage.
Selector Scoping
Return the full document or a single subtree with a selector — smaller payloads and less parsing downstream.
JSON or Raw HTML
Read data.html from the JSON response, or ask for embed=html and get the document back as text/html — no JSON involved.
Readiness You Control
waitUntil and waitForSelector let you block on network idle or on a specific element before the HTML is captured.
One Call, Many Formats
Request HTML together with markdown, text, metadata, screenshots or PDFs and pay for a single render instead of several.
Framework Friendly
Drop it into FastAPI, Flask, or an archive worker as a route or a few-line function.
Zero Infrastructure
Managed Headless Chrome, autoscaled and load-balanced. No browser pool, no servers, no patching to maintain.
Generous Free Tier
Sign up for a free API key: 100 requests per month with every Pro feature, no credit card.
Real Browser Rendering
Every request runs in managed Chromium, so client-rendered apps return complete markup instead of an empty shell.Standard Library Only
urllib and json ship with Python — the examples run with no pip install and no Chromium binary to manage.Selector Scoping
Return the full document or a single subtree with a selector — smaller payloads and less parsing downstream.
JSON or Raw HTML
Read data.html from the JSON response, or ask for embed=html and get the document back as text/html — no JSON involved.Readiness You Control
waitUntil and waitForSelector let you block on network idle or on a specific element before the HTML is captured.One Call, Many Formats
Request HTML together with markdown, text, metadata, screenshots or PDFs and pay for a single render instead of several.
Framework Friendly
Drop it into FastAPI, Flask, or an archive worker as a route or a few-line function.Zero Infrastructure
Managed Headless Chrome, autoscaled and load-balanced. No browser pool, no servers, no patching to maintain.Generous Free Tier
Sign up for a free API key: 100 requests per month with every Pro feature, no credit card.
Try it live in the playground
Paste a URL and see the rendered output before you write a line of Python.
Python HTML API FAQ
Everything Python developers ask before integrating the Microlink HTML API.
Do I get the source HTML or the rendered DOM?
Every request runs in a real Chromium instance, so data.html is the fully rendered DOM — JavaScript executed, lazy content loaded. Control the capture point with waitUntil and waitForSelector.
Do I need to install a package or a browser?
No. The examples use urllib and json from the Python standard library, and rendering runs on Microlink — no Playwright, no Selenium, no Chromium to manage.
How do I control when the HTML is captured?
Use
waitUntil to block on network idle or a fixed delay, and waitForSelector to hold the capture until a specific element exists — the HTML comes back exactly when your page is ready, still in one request.Can I get only part of the page?
Yes. Add a
selector to the extraction rule and only that subtree comes back — ideal for articles, product cards or pricing tables, with smaller payloads and less parsing downstream.Is there a free tier or do I need an API key?
Yes, and it is free: sign up for an API key and you get 100 requests per month with every Pro feature, no credit card. Add it as x-api-key and start extracting.
When you need more volume, pick a paid plan: same key, bigger quota. See pricing for the limits.
How fresh is the HTML?
Responses are cached at the edge with a sane default TTL, and you control freshness per request — see the API overview for cache parameters.
Start extracting in Python
Sign up for a free API key: 100 requests per month with every Pro feature, no credit card. Send your first request and get HTML back in minutes.
Free API key
100 requests/month
No credit card