The YouTube API stops you at 100 searches a day. Web Unlocker returns every search page you ask for, up to 20 videos on each, for $0.98 per 1,000. No Google API key needed.
1,000 free requests · Pay only on success · 195+ countries · Claude ready
YouTube pages take 15 to 30 seconds to load. It is still working, no need to click again.
Ready for your own searches? Get an API key or book a demo.
Tell us a little about your team and get:
Web Unlocker bills a YouTube search results page as one page, with all of its up to 20 videos. YouTube scrapers on Apify and Bright Data bill each of those videos as a row of its own.
The API stops at 100 searches a day.
Here 1,000 searches cost $0.98.
Filter the search the way YouTube does, by upload date or by views: each filter is one more page at the same price.
What 1,000 searches with 20 videos each cost
1,000 search pages and 20,000 videos, at published prices
SerpApi bills each search. Bright Data bills each video as a record, $1.50 per 1,000. The most used YouTube scraper on Apify bills each video, $2.40 to $4.00 per 1,000.
The YouTube Data API is free until its 100 searches a day run out, and YouTube scrapers bill every video. Here is what each route takes for the same 1,000 searches.
| What it takes | YouTube Data API | Apify | SerpApi | |
|---|---|---|---|---|
| Searches a day | No cap | 100 | No cap | By plan |
| You pay for | A page | Free within quota | Each video | Each search |
| 1,000 searches with 20 videos | $0.98 | 10 days of quota | $48 to $80 | $25 |
| Transcripts of any video | With Cloud Browser | Own videos only | Yes | No |
| Start without a Google project | Yes | No | Yes | Yes |
| The whole page in HTML | Yes | No | No | No |
Scraping more than YouTube? Web Unlocker returns any page the same way, at the same price.
A channel's uploads playlist lists 100 videos on its first page, and every next page brings 78 more. Web Unlocker bills each page once: 10 pages, 802 videos, $0.0098.
Apify bills $2.40 to $4.00 per 1,000 videos.
Here 800 cost 1 cent.
YouTube keeps every video on a page as JSON inside its HTML. Web Unlocker returns that HTML, and a few lines of code read the videos out of it.
Fill in the form above. The key arrives by email within one business day.
A search for your keyword, a video for its numbers, or a channel's uploads for every video it has.
Each video on the page carries its title, views, channel, date and length.
pip install requestsGOLOGIN_SCRAPING_API_KEY=your_key python youtube_search.pyhttps://parsing.webunlocker.gologin.com/v1/scrapeimport json
import os
import time
from urllib.parse import quote_plus
import requests
search = "home espresso"
def scrape(url):
for attempt in range(3):
response = requests.get(
"https://parsing.webunlocker.gologin.com/v1/scrape",
params={"url": url, "geo": "us", "format": "json"},
headers={"apikey": os.environ["GOLOGIN_SCRAPING_API_KEY"]},
timeout=90,
)
page = response.json().get("data", {}).get("html", "") if response.ok else ""
if '"videoRenderer"' in page:
return page
time.sleep(5)
raise RuntimeError("No videos came back, try again later")
def find(node, key):
if isinstance(node, dict):
for name, value in node.items():
if name == key:
yield value
yield from find(value, key)
elif isinstance(node, list):
for item in node:
yield from find(item, key)
def text(field):
if not field:
return None
return field.get("simpleText") or "".join(run["text"] for run in field.get("runs", []))
page = scrape(f"https://www.youtube.com/results?search_query={quote_plus(search)}")
data = json.loads(page.split("var ytInitialData = ")[1].split(";</script>")[0])
videos = {}
for video in find(data, "videoRenderer"):
videos[video["videoId"]] = {
"title": text(video.get("title")),
"url": f"https://www.youtube.com/watch?v={video['videoId']}",
"channel": text(video.get("ownerText")),
"views": text(video.get("viewCountText")),
"published": text(video.get("publishedTimeText")),
"length": text(video.get("lengthText")),
}
print(json.dumps(list(videos.values()), indent=2, ensure_ascii=False))
print(f"{len(videos)} videos from one search page")GOLOGIN_SCRAPING_API_KEY=your_key node youtube-channel.mjshttps://parsing.webunlocker.gologin.com/v1/scrapeconst channelId = 'UCBJycsmduvYEL83R_U4JriQ';
const wanted = 800;
const uploads = `UU${channelId.slice(2)}`;
async function scrape(url) {
for (let attempt = 1; attempt <= 3; attempt++) {
const params = new URLSearchParams({ url, geo: 'us', format: 'json' });
const response = await fetch(`https://parsing.webunlocker.gologin.com/v1/scrape?${params}`, {
headers: { apikey: process.env.GOLOGIN_SCRAPING_API_KEY },
});
const page = response.ok ? (await response.json()).data?.html : '';
if (page?.includes('var ytInitialData = ')) return JSON.parse(page.split('var ytInitialData = ')[1].split(';</script>')[0]);
await new Promise((resolve) => setTimeout(resolve, 5000));
}
throw new Error('The page came back without videos, try again later');
}
function* find(node, key) {
if (Array.isArray(node)) for (const item of node) yield* find(item, key);
else if (node && typeof node === 'object') {
for (const [name, value] of Object.entries(node)) {
if (name === key) yield value;
yield* find(value, key);
}
}
}
const videos = new Map();
for (const item of find(await scrape(`https://www.youtube.com/playlist?list=${uploads}`), 'lockupViewModel')) {
if (item.contentType === 'LOCKUP_CONTENT_TYPE_VIDEO') videos.set(item.contentId, item.metadata.lockupMetadataViewModel.title.content);
}
let pages = 1;
while (videos.size < wanted) {
const last = [...videos.keys()].at(-1);
const before = videos.size;
for (const item of find(await scrape(`https://www.youtube.com/watch?v=${last}&list=${uploads}`), 'playlistPanelVideoRenderer')) {
videos.set(item.videoId, item.title.simpleText);
}
pages++;
if (videos.size === before) break;
}
console.table([...videos].slice(0, 5).map(([id, title]) => ({ title, url: `https://www.youtube.com/watch?v=${id}` })));
console.log(`${videos.size} videos in ${pages} pages: $${(pages * 0.00098).toFixed(4)} on the Growth plan`);GOLOGIN_SCRAPING_API_KEY=your_key node youtube-video.mjshttps://parsing.webunlocker.gologin.com/v1/scrapeconst video = 'https://www.youtube.com/watch?v=jNQXAC9IVRw';
async function scrape(url) {
for (let attempt = 1; attempt <= 3; attempt++) {
const params = new URLSearchParams({ url, geo: 'us', format: 'json' });
const response = await fetch(`https://parsing.webunlocker.gologin.com/v1/scrape?${params}`, {
headers: { apikey: process.env.GOLOGIN_SCRAPING_API_KEY },
});
const page = response.ok ? (await response.json()).data?.html : '';
if (page?.includes('var ytInitialPlayerResponse = ')) return page;
await new Promise((resolve) => setTimeout(resolve, 5000));
}
throw new Error('The video page came back empty, try again later');
}
const page = await scrape(video);
const player = JSON.parse(page.split('var ytInitialPlayerResponse = ')[1].split(';var meta')[0]);
const { videoDetails: details, microformat, captions } = player;
console.log({
title: details.title,
channel: details.author,
views: Number(details.viewCount),
likes: Number(page.match(/along with ([\d,]+) other/)?.[1].replaceAll(',', '')),
comments: page.match(/"contextualInfo":\{"runs":\[\{"text":"([^"]+)"/)?.[1],
published: microformat.playerMicroformatRenderer.publishDate,
seconds: Number(details.lengthSeconds),
tags: details.keywords ?? [],
captions: captions?.playerCaptionsTracklistRenderer.captionTracks.map((track) => track.languageCode) ?? [],
});Ready to run it on your own searches? Get your API key and free requests.
Web Unlocker returns the page as YouTube first sends it. Comments load only as you scroll, and transcripts only when you click. Cloud Browser is the add-on that scrolls and clicks for you, from $4.50 a month for 50 browser hours.
100 comments from each of 1,000 videos come to $6.95: 8.3 browser hours and 6.2 GB of traffic. Apify bills $30 to $200 for the same.
The YouTube API gives transcripts of your own videos only, and servers get an empty file. Cloud Browser opens the transcript the way a viewer does, in 25 seconds.
Each session runs on a residential IP in the country you pick. Traffic past your plan is $1/GB.
Run it from Playwright, Puppeteer or Claude. See Cloud Browser.
One account, one proxy network, one ecosystem. Pick the product the job needs.
Scraping more sites? See the Reddit, Google Maps and Amazon scrapers, or every web scraping tool.
Yes. Web Unlocker is a YouTube scraper API: send it a search, a video or a channel's uploads, and it loads the page in a real browser and returns it with the data YouTube keeps inside it: titles, views, channels, dates and lengths. $0.98 per 1,000 pages, and the code above reads it.
Yes. A YouTube video page brings its exact views, likes, comment count, description, tags, publish date and caption languages, plus 20 related videos, billed as one page. The Video stats tab above reads them.
Send youtube.com/results with your keyword. One page brings up to 20 videos and up to 25 Shorts, each with its views, channel, age and length, billed as one page. Add YouTube's own filters, by upload date or by views, for other results.
100 search calls a day per project by default, each with up to 50 results. More takes a quota request and an audit by Google. Web Unlocker has no daily cap: you pay per page, $0.98 per 1,000.
Yes, within its quota: 10,000 units a day for most calls, plus 100 searches. Past that, Google raises the quota only after an audit of your project.
Yes. Search, video and channel pages are public and load without a login. Web Unlocker returns them the way a visitor's browser sees them, with no Google project and no API key.
Open the channel's uploads playlist: the first page lists 100 videos with their views and age. Then open its last video with that playlist: each such page lists 78 more. 10 pages bring 802 videos, for 1 cent.
YouTube loads comments as you scroll, so Web Unlocker does not return them. Cloud Browser scrolls the video for you: 100 comments in 26 seconds, and 100 comments from each of 1,000 videos for $6.95.
Yes, with Cloud Browser. The YouTube API gives transcripts of your own videos only, and requests from servers get an empty file. Cloud Browser opens the transcript the way a viewer does, in 25 seconds a video.
Send the search address to Web Unlocker with the requests library and read the videos from the page. The Python tab above is a complete script, tested on the live API.
Yes. A search page brings up to 25 Shorts with their titles and views, a channel's Shorts tab lists 48, and a Short's own page has its likes, comment count and date.
Web Unlocker returns the page, not a table, so nothing is cut before you see it. Turning it into a CSV takes a few lines of code, or one prompt: hand the page to Claude with the Gologin scraping skill and ask for a CSV.
$0.98 per 1,000 pages, the same for every page. A search with up to 20 videos is one page, a video with its numbers is one page. A page that fails to load costs nothing. Plans start at $49 a month for 50,000 requests.
Yes, to start: Web Unlocker comes with 1,000 free requests, enough for 1,000 searches or 1,000 videos.
It depends on the job. The YouTube API is free for 100 searches a day. Apify and Bright Data sell ready rows and bill every video. Web Unlocker returns the whole page at one price, so 20 videos cost the same as one.
Search, video and channel pages are public pages that load without a login. Web Unlocker loads them the way a visitor's browser does and returns the page. What you collect and how you use it is your call, so check it against the rules that apply to your project.
Tell us a little about your team and get: