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, transformed</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.95% 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
Start with 25 requests per day — no account, no credit card. Add an API key when you are ready to scale.
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
Start with 25 requests per day — no account, no credit card. Add an API key when you are ready to scale.
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?
The free tier gives you 25 requests per day with no account, no credit card, and no API key. Just call the endpoint and start extracting.
When you need more throughput or caching control, add an
apiKey header and requests route to the Pro tier. 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
Get 25 requests/day with zero commitment — no account and no credit card. Send your first request and get HTML back in minutes.
No login needed
25 reqs/day free
No credit card