Scraping Naver: Bypass Blocks and Extract Product Data
Naver is South Korea’s most important search engine, ecommerce platform, and digital ecosystem; all rolled into one.
It dominates over 60% of Korea’s search market, powers countless Smart Stores (its e-commerce platform), and handles everything from news to payments.
If you’re scraping Korean web data, you’ll hit Naver sooner or later.
But scraping Naver isn’t easy.
Why Is Scraping Naver Hard?
Naver isn’t just a search engine; it’s the backbone of Korean internet.
This level of influence comes with tight control over access especially to its ecommerce data.
Whether you’re trying to extract product details or search listings, you’ll quickly notice that Naver doesn’t want to be scraped.
Here’s why most scrapers fail.
Datacenter Proxies Are Blocked Instantly
Naver actively blocks traffic from known datacenter IP ranges. Be ready to get familiar with this page really quickly:
If you’re sending requests from AWS, GCP, or any commercial proxy provider, you’re almost guaranteed to hit:
403 Forbidden
— request denied outright429 Too Many Requests
— rate-limited before you even start502 Bad Gateway
— fallback error, often shown when WAFs intervene
You won’t even get through the front door.
To avoid this, you’ll need residential or mobile IPs, ideally from Korean ISPs, with session stickiness and rotating headers or you’ll get flagged immediately.
JavaScript Rendering Isn’t Enough
Even with a powerful headless browser, you might still end up with a blank page.
That’s because Naver uses multi-layered JavaScript challenges; sometimes tied to region, sometimes tied to session behavior.
And if your scraper doesn’t match expected patterns (browser fingerprint, TLS, execution timing), rendering will silently fail or loop endlessly.
Some pages return 200 OK and look like they load (like below), but never actually return real content unless every script executes correctly, in the right sequence.
That’s what makes Naver different: it doesn’t just check if you’re a bot, it tests if you behave like a real user inside a Korean browser session.
How Scrape.do Bypasses These Challenges
Scraping Naver with your own setup?
You’ll get blocked before the page even loads.
That’s because Naver checks everything; where you’re connecting from, how your browser behaves, and whether your session looks natural.
Even well-configured headless browsers fail without the right IP and session setup.
Scrape.do handles all of this under the hood, so you don’t have to.
- KR residential IPs 🇰🇷
- Sticky sessions 📌
- Rotating headers & TLS fingerprints 🔄
- Full JavaScript rendering 🖼️
Without extensive setup and maintenance, you just send the URL and get the real page back, instantly.
Scrape Naver Product Details Directly From Product Page
This is the most common approach: go directly to the product page, extract name, price, and other key details.
It works well if you can get past the initial blocks. For this tutorial, we’ll scrape the product page for a SteelSeries headset using Python and Scrape.do.
Before we send our first request, let’s make sure we have the tools we need.
Prerequisites
We’ll use Python and a few simple libraries:
requests
: To send our HTTP requests.re
: To locate desired elements from the returned HTML.- Scrape.do API Token: You’ll need a Scrape.do token to access the page without getting blocked. You can sign up here for free and get 1000 credits to start.
Install requests
if you don’t have it:
pip install requests
Sending the First Request
Let’s hit the product page and make sure we’re getting a real response.
We’ll use super=true
to activate premium proxy routing — this is especially important for Naver, where regular IPs get blocked fast.
Here’s how to send the request:
import requests
import urllib.parse
# Your Scrape.do token
token = "<your_token>"
# Naver product URL
target_url = "https://brand.naver.com/steelseries/products/11800715035"
encoded_url = urllib.parse.quote_plus(target_url)
# Scrape.do API endpoint with super=true for premium proxy routing
url = f"https://api.scrape.do?token={token}&url={encoded_url}&super=true"
# Send the request
response = requests.get(url)
# Print status code
print(response)
If the setup is working, you should see:
<Response [200]>
That means Naver let you in and we’re ready to start extracting data.
Extracting Product Name and Price
Now that we’ve confirmed we’re getting a valid response, we can extract the product name and price directly from the page source.
❗ Usually we find on the page the information we’re trying to scrape and hit Inspect to get the element we need, but it won’t work this time. We need to go to the page source and find information we’re looking for there.
If you scroll through the HTML response, you’ll find that Naver injects all product information into a large embedded JSON block.
This is part of their internal state object, and it contains fields like "dispName"
for the product title and "dispDiscountedSalePrice"
for the final price shown on the page:
We don’t need to parse the entire JSON. A simple regular expression will do the job.
Here’s how:
import requests
import urllib.parse
import re
# Your Scrape.do token
token = "<your_token>"
# Target URL
target_url = urllib.parse.quote_plus("https://brand.naver.com/steelseries/products/11800715035")
# Scrape.do API endpoint with premium proxy routing
url = f"https://api.scrape.do?token={token}&url={target_url}&super=true"
# Send the request
response = requests.get(url)
# Extract the values via regex
html = response.text
product_name = re.search(r'"dispName":"([^"]+)"', html).group(1)
discounted_price = int(re.search(r'"dispDiscountedSalePrice":([0-9]+)', html).group(1))
# Print product name and price
print("Product Name:", product_name)
print("Price:", f"{discounted_price:,}₩")
You output should look like this:
Product Name: [QcK Heavy M 증정] 스틸시리즈 Arctis Nova 5 무선 게이밍 헤드셋 - 블랙 / 화이트
Price: 176,000₩
And voila! You’ve scraped a product from Naver.
However, my experience using this method has been inconsistent.
The security at Naver is TIGHT!
So, I’ve found a slightly different approach that uses their API endpoint:
Scrape Naver API Endpoint for Product Details
If you want something faster, more stable, and easier to parse, Naver’s own API is the better option. It returns clean JSON, loads faster, and is more consistent across products.
The only catch?
You need to build the API request yourself.
But the good news is: it’s easier than it sounds.
You only need two things:
channelUid
: the store identifier (like a brand or seller)productNo
: the product ID (already in the URL)
And chances are, if you’re scraping Naver, you’re targeting specific stores anyway, which means you can reuse the channelUid
across dozens or hundreds of products.
Let me show you how to find it:
Find channelUid
The easiest way to find channelUid
is by inspecting the page source.
Right-click anywhere on the product page and hit Inspect, or press F12
.
Once DevTools opens, press Ctrl + F
and search for:
channelUid
You’ll see it in plain text, should look like this:
That’s the value you need.
This ID is unique to the store (in this case, SteelSeries), and it’ll stay the same across all their product pages so once you grab it, you can reuse it for as many products as you want from that seller.
Find Product ID
This one’s even easier.
Just look at the URL:
https://brand.naver.com/steelseries/products/11800715035
11800715035
is the product ID, also referred to as productNo
in Naver’s API.
No need to inspect anything. If you have the product URL, you already have the ID.
Now that we’ve got both the channelUid
and productNo
, let’s build the API request.
Sending the Request
We now have both pieces we need:
channelUid
:2sWE13PU92zxrIFi44IbY
productNo
:11800715035
These two values are all you need to hit Naver’s internal API. We’ll also append withWindow=false
to skip extra UI data and get a lighter, cleaner JSON response.
Here’s how to build and send the request using Scrape.do:
import requests
import urllib.parse
# Your Scrape.do token
token = "<your_token>"
# Product identifiers
channel_uid = "2sWDw6fJMaeiT9eyhAmGd"
product_id = "11800715035"
# Naver API target
target_url = f"https://brand.naver.com/n/v2/channels/{channel_uid}/products/{product_id}?withWindow=false"
encoded_url = urllib.parse.quote_plus(target_url)
# Scrape.do API endpoint
api_url = f"https://api.scrape.do?token={token}&url={encoded_url}&super=true"
# Send the request
response = requests.get(api_url)
# Print response status
print(response)
If everything works, you’ll see:
<Response [200]>
That means Naver responded with the full product data; no HTML, no noise, just clean JSON we can work with next.
Parse and Export
Once we get a successful 200 response from Naver’s API, you’ll see that the rest is easy.
Here are the 5 key fields we’ll extract:
- Product Name →
dispName
- Discounted Price →
discountedSalePrice
- Discount Ratio →
benefitsView.discountedRatio
- Image URL →
representImage.url
- Stock Quantity →
stockQuantity
Let’s print them first:
import requests
import urllib.parse
# Your Scrape.do token
token = "<your_token>"
# Product identifiers
channel_uid = "2sWDw6fJMaeiT9eyhAmGd"
product_id = "11800715035"
# Build the Naver API URL
target_url = f"https://brand.naver.com/n/v2/channels/{channel_uid}/products/{product_id}?withWindow=false"
encoded_url = urllib.parse.quote_plus(target_url)
api_url = f"https://api.scrape.do?token={token}&url={encoded_url}&super=true"
# Send the request
response = requests.get(api_url)
data = response.json()
# Extract fields
name = data["dispName"]
price = data["discountedSalePrice"]
discount = data["benefitsView"]["discountedRatio"]
image = data["representImage"]["url"]
stock = data["stockQuantity"]
# Print the results
print("Product Name:", name)
print("Price:", f"{price:,}₩")
print("Discount:", f"{discount}%")
print("Image URL:", image)
print("Stock Quantity:", stock)
Here’s what will print out:
Product Name: [QcK Heavy M 증정] 스틸시리즈 Arctis Nova 5 무선 게이밍 헤드셋 - 블랙 / 화이트
Price: 176,000₩
Discount: 11%
Image URL: https://shop-phinf.pstatic.net/20250507_71/1746586488548DMoJN_PNG/1170543923217933_1817156307.png
Stock Quantity: 968
Now that we’ve confirmed the values are correct, let’s export them to a .csv
file so we can reuse the data later or analyze it at scale.
Here’s the final version with export:
import requests
import urllib.parse
import csv
# Your Scrape.do token
token = "<your_token>"
# Product identifiers
channel_uid = "2sWDw6fJMaeiT9eyhAmGd"
product_id = "11800715035"
# Build request
target_url = f"https://brand.naver.com/n/v2/channels/{channel_uid}/products/{product_id}?withWindow=false"
encoded_url = urllib.parse.quote_plus(target_url)
api_url = f"https://api.scrape.do?token={token}&url={encoded_url}&super=true"
# Request and parse
response = requests.get(api_url)
data = response.json()
# Extract details
name = data["dispName"]
price = data["discountedSalePrice"]
discount = data["benefitsView"]["discountedRatio"]
image = data["representImage"]["url"]
stock = data["stockQuantity"]
# Export to CSV
with open("naver_product_data.csv", "w", newline="", encoding="utf-8-sig") as f:
writer = csv.writer(f)
writer.writerow(["Product Name", "Price", "Discount", "Image URL", "Stock Quantity"])
writer.writerow([name, price, f"{discount}%", image, stock])
print("Data saved to naver_product_data.csv")
You should see:
Data saved to naver_product_data.csv
And that’s clean, reliable product data straight from Naver’s internal API.
Blocked? Here’s (Probably) Why
If your request fails — especially with a 403, 429, or a blank page — it usually comes down to one of two things:
You’re Geo-Restricted
Naver’s product pages and APIs are region-locked. If your IP isn’t coming from South Korea, you’ll likely be blocked or shown incomplete content.
To fix this, just add &geoCode=kr
to the end of your Scrape.do request URL.
So your final request should look like this:
https://api.scrape.do?token=<your_token>&url=<encoded_url>&super=true&geoCode=kr
This tells Scrape.do to route your request through a Korean residential IP, which is required for consistent access to Naver.
The API Endpoint Has Been Changed
Naver doesn’t officially document their internal API and they do change it from time to time.
If your API request suddenly stops working, you’ll need to reconfirm the endpoint:
- Open the product page in Chrome
- Press
F12
to open DevTools - Go to the Network tab
- Refresh the page
- In the “Filter” input, type the product ID plus
?withWindow=false
(e.g.11800715035?withWindow=false
) - Click the matching request that appears
- The full Request URL will be the internal API endpoint
That’s the real URL you need to use and it may change depending on Naver’s current architecture.
If you’re ever unsure, fall back to this method and rebuild your API request accordingly.
Conclusion
Naver is a tough target for e-commerce scraping; between geo-blocking, headless rendering traps, and a constantly shifting internal structure, most scrapers fail before they even get a 200 response.
But once you know how to extract channelUid
, use the internal API, and route your requests through the right proxies, it becomes simple and repeatable.
And with Scrape.do, you don’t need to worry about:
- Proxy rotation or fingerprinting
- Session headers or TLS configs
- JavaScript rendering or CAPTCHA solving
Just send the request and get clean, fast, and unblocked access to important data.