<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: MOON</title>
    <description>The latest articles on DEV Community by MOON (@cocomoon).</description>
    <link>https://dev.to/cocomoon</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4117091%2F6984bc49-c6fb-455e-a3b3-9657b0bd5899.png</url>
      <title>DEV Community: MOON</title>
      <link>https://dev.to/cocomoon</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/cocomoon"/>
    <language>en</language>
    <item>
      <title>Same Korean sunscreen, two stores: Korea writes reviews 5x faster, the rest of the world posts 2x the photos</title>
      <dc:creator>MOON</dc:creator>
      <pubDate>Sat, 10 Oct 2026 05:53:07 +0000</pubDate>
      <link>https://dev.to/cocomoon/same-korean-sunscreen-two-stores-korea-writes-reviews-5x-faster-the-rest-of-the-world-posts-2x-2244</link>
      <guid>https://dev.to/cocomoon/same-korean-sunscreen-two-stores-korea-writes-reviews-5x-faster-the-rest-of-the-world-posts-2x-2244</guid>
      <description>&lt;p&gt;Olive Young, Korea's biggest beauty retailer, runs two stores. The Korean one (oliveyoung.co.kr) sells to people in Korea. The Global one (global.oliveyoung.com) ships abroad. A product that is on both has two separate review sections, written by two different sets of buyers.&lt;/p&gt;

&lt;p&gt;I wanted to see how different those two crowds are, so on October 10 I took one product and pulled the newest 500 reviews from each store.&lt;/p&gt;

&lt;h2&gt;
  
  
  The product
&lt;/h2&gt;

&lt;p&gt;SKIN1004 Madagascar Centella Hyalu-Cica Water-Fit Sun Serum, one of the best-known Korean sunscreens abroad.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Korean store: 17,292 reviews, average 4.9&lt;/li&gt;
&lt;li&gt;Global store: 11,963 reviews, average 4.9&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I checked that it is the same item and not just a similar name. The Global listing is the twin pack with barcode &lt;code&gt;8809913830122&lt;/code&gt;. On the Korean store, every review carries the barcode of the exact option the reviewer bought, and that same barcode is there, next to the single tube and a gift set that share the listing.&lt;/p&gt;

&lt;p&gt;Same sunscreen, same 4.9. Everything else is different.&lt;/p&gt;

&lt;h2&gt;
  
  
  Korea reviews it five times faster
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Korean store&lt;/th&gt;
&lt;th&gt;Global store&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Newest 500 reviews go back to&lt;/td&gt;
&lt;td&gt;Sep 29&lt;/td&gt;
&lt;td&gt;Aug 7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Days covered&lt;/td&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;65&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reviews per day&lt;/td&gt;
&lt;td&gt;41.7&lt;/td&gt;
&lt;td&gt;7.7&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The Korean store collects 5.4 times as many reviews per day from one country as the Global store does from all the others. And it is October, not sunscreen season.&lt;/p&gt;

&lt;p&gt;Part of the reason is in the data: 163 of the 500 Korean reviews (32.6%) are marked as in-store purchases. People buy it at one of Olive Young's physical shops and review it in the app later. The Global store has no shops to feed it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The stars are the same
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Korean store&lt;/th&gt;
&lt;th&gt;Global store&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;5 stars&lt;/td&gt;
&lt;td&gt;455 (91.0%)&lt;/td&gt;
&lt;td&gt;453 (90.6%)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4 stars&lt;/td&gt;
&lt;td&gt;31&lt;/td&gt;
&lt;td&gt;41&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3 stars or lower&lt;/td&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If you only look at the rating, the two markets agree almost to the review. So the rating is the least useful column here.&lt;/p&gt;

&lt;h2&gt;
  
  
  The world posts photos, Korea doesn't
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Global store: 38.6% of reviews have a photo&lt;/li&gt;
&lt;li&gt;Korean store: 16.4%&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;International buyers also fill in their skin profile far more often: 342 of 500 (68.4%) against 142 of 500 (28.4%) in Korea.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two stores, two ideas of "skin tone"
&lt;/h2&gt;

&lt;p&gt;Both stores ask reviewers for a skin tone. They do not mean the same thing by it.&lt;/p&gt;

&lt;p&gt;The Korean store asks for your personal colour, the seasonal system that is everywhere in Korean beauty: cool, warm, spring warm, summer cool, autumn warm, winter cool. It is about undertone, not depth.&lt;/p&gt;

&lt;p&gt;The Global store asks how light or dark you are: porcelain, fair/light, medium, tan, olive, deep, dark, ebony. Of the 339 reviewers who answered:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Skin tone&lt;/th&gt;
&lt;th&gt;Reviewers&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Fair/Light&lt;/td&gt;
&lt;td&gt;155&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;98&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Porcelain&lt;/td&gt;
&lt;td&gt;45&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tan&lt;/td&gt;
&lt;td&gt;21&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Olive&lt;/td&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deep&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dark&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ebony&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For a sunscreen this matters. "No white cast" from a porcelain reviewer and from a deep-skinned reviewer are not the same claim, and only the Global store lets you tell them apart. In this sample you would have 41 reviews from tan-to-ebony skin to check it against.&lt;/p&gt;

&lt;h2&gt;
  
  
  Skin type is nearly identical. Concerns are not.
&lt;/h2&gt;

&lt;p&gt;Skin type, among reviewers who gave one:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Korean store (142)&lt;/th&gt;
&lt;th&gt;Global store (342)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Combination&lt;/td&gt;
&lt;td&gt;40.8%&lt;/td&gt;
&lt;td&gt;42.7%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dry&lt;/td&gt;
&lt;td&gt;25.4%&lt;/td&gt;
&lt;td&gt;20.2%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Oily&lt;/td&gt;
&lt;td&gt;16.9%&lt;/td&gt;
&lt;td&gt;11.1%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sensitive&lt;/td&gt;
&lt;td&gt;12.0%&lt;/td&gt;
&lt;td&gt;15.2%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Close enough that the product clearly sells to the same kind of skin everywhere. What those people worry about is another story. Top five skin concerns:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Korean store (129 reviewers)&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Global store (335 reviewers)&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Dark spots&lt;/td&gt;
&lt;td&gt;36.4%&lt;/td&gt;
&lt;td&gt;Blackheads&lt;/td&gt;
&lt;td&gt;47.5%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Brightening&lt;/td&gt;
&lt;td&gt;27.9%&lt;/td&gt;
&lt;td&gt;Acne&lt;/td&gt;
&lt;td&gt;41.8%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Breakouts&lt;/td&gt;
&lt;td&gt;27.1%&lt;/td&gt;
&lt;td&gt;Brightening&lt;/td&gt;
&lt;td&gt;40.9%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Flakiness&lt;/td&gt;
&lt;td&gt;24.8%&lt;/td&gt;
&lt;td&gt;Moisturising&lt;/td&gt;
&lt;td&gt;38.5%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pores&lt;/td&gt;
&lt;td&gt;19.4%&lt;/td&gt;
&lt;td&gt;Dullness&lt;/td&gt;
&lt;td&gt;27.2%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The Korean buyer of this sunscreen is thinking about pigmentation. The international buyer is thinking about blackheads and acne. Same tube, and a marketer would write two different product pages for it.&lt;/p&gt;

&lt;p&gt;(The two stores use different lists of concerns, so compare the rankings, not the exact percentages.)&lt;/p&gt;

&lt;h2&gt;
  
  
  A quarter of the "global" reviews are in Japanese
&lt;/h2&gt;

&lt;p&gt;I expected the Global store to be English. I sorted the 500 reviews by the script they are written in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Latin script (English, Spanish and so on): 341&lt;/li&gt;
&lt;li&gt;Japanese (contains kana): 117, or 23.4%&lt;/li&gt;
&lt;li&gt;Chinese characters only: 20&lt;/li&gt;
&lt;li&gt;Cyrillic: 13&lt;/li&gt;
&lt;li&gt;Korean: 7&lt;/li&gt;
&lt;li&gt;Arabic: 2&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a rough split by character set, not real language detection. But the Japanese share is hard to miss, and it is the kind of thing a "global" average hides.&lt;/p&gt;

&lt;h2&gt;
  
  
  What only one store can tell you
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Global store: a separate score for sun protection.&lt;/strong&gt; Each reviewer rates attributes as well as the product. Texture averages 4.88 and Sun protection 4.79. Of the 453 people who gave the product five stars, 51 gave its sun protection less than five. They love how it feels and are not fully sure it protects. You cannot see that in the star rating.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Korean store: how long people used it.&lt;/strong&gt; 285 of the 500 reviews (57.0%) carry Olive Young's flag for a review written after a month or more of use. The Global store has nothing like it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Limits
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;One product, the newest 500 reviews per store, collected on one day.&lt;/li&gt;
&lt;li&gt;The Korean store stops serving reviews after the first 500 of each sort order unless you log in. I did not log in, so 500 is the ceiling per sort there. Sorting another way gives a different 500. The Global store kept going to at least 1,300 when I tested it.&lt;/li&gt;
&lt;li&gt;Skin profiles are optional and self-reported.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How I got the data
&lt;/h2&gt;

&lt;p&gt;Both review sections load from JSON endpoints, so there is no HTML to parse. I used my own &lt;a href="https://apify.com/cocomoon/oliveyoung-review-scraper" rel="noopener noreferrer"&gt;Olive Young Reviews Scraper&lt;/a&gt; on Apify, which now takes product numbers from either store in the same run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"products"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"A000000215559"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"GA230518746"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"sortBy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"DATETIME_DESC"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"maxReviewsPerProduct"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;A…&lt;/code&gt; numbers are the Korean store, &lt;code&gt;GA…&lt;/code&gt; numbers are the Global store. Each row comes back with the same core fields (rating, text, date, photos, reviewer skin profile) plus whatever is specific to that store.&lt;/p&gt;

&lt;p&gt;If you have a product you would like compared across the two stores, tell me which one in the comments.&lt;/p&gt;

</description>
      <category>datascience</category>
      <category>webscraping</category>
      <category>showdev</category>
      <category>korea</category>
    </item>
    <item>
      <title>Olive Young has two best-seller charts. I matched them by barcode: 32 of the top 100 are the same product, and they cost 1.6x more abroad.</title>
      <dc:creator>MOON</dc:creator>
      <pubDate>Fri, 02 Oct 2026 08:05:40 +0000</pubDate>
      <link>https://dev.to/cocomoon/olive-young-has-two-best-seller-charts-i-matched-them-by-barcode-32-of-the-top-100-are-the-same-gmm</link>
      <guid>https://dev.to/cocomoon/olive-young-has-two-best-seller-charts-i-matched-them-by-barcode-32-of-the-top-100-are-the-same-gmm</guid>
      <description>&lt;p&gt;Olive Young, Korea's biggest beauty retailer, runs two stores. The Korean one (oliveyoung.co.kr) is in Korean, priced in won, and shows what people in Korea buy. The Global one (global.oliveyoung.com) is in English, priced in dollars, and ships abroad. Each has its own best-seller chart.&lt;/p&gt;

&lt;p&gt;Most "what's trending in K-beauty" lists quote one of them and call it Korea. I wanted to know how different the two really are, so on October 2 I pulled the top 100 of both and matched them product by product.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I matched them
&lt;/h2&gt;

&lt;p&gt;Product names are useless for this. The same item is &lt;code&gt;[4년 연속 1위] 어노브 딥 데미지 리페어 헤어 마스크…&lt;/code&gt; on one site and &lt;code&gt;UNOVE Deep Damage Repair Hair Mask 320mL Double Pack (6 Options)&lt;/code&gt; on the other.&lt;/p&gt;

&lt;p&gt;Barcodes work. Both stores expose the EAN of each product (the Global store per option, too), so the join is one line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;kr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;barcode&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;korea_top100&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;global_top100&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;codes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;barcode&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;barcode&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;options&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;
    &lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;kr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;codes&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;kr&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  32 of 100 are the same product
&lt;/h2&gt;

&lt;p&gt;Thirty-two products are on both charts with the same barcode. The #1 is identical: the Mediheal Essential sheet mask 10+1 set.&lt;/p&gt;

&lt;p&gt;The top of the Global chart is very Korean: 7 of its top 10 are also in Korea's top 100. Further down the two lists drift apart. By brand, the Global chart has 62 brands and the Korean one 68, and 31 are on both.&lt;/p&gt;

&lt;p&gt;So roughly a third overlap by product, half by brand. The other half is where it gets interesting.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Korea buys that the Global chart doesn't show
&lt;/h2&gt;

&lt;p&gt;Twelve of Korea's top 100 come from eight brands that aren't Korean at all: La Roche-Posay (three products, including #2 overall, Cicaplast Baume B5+), Bioderma, The Ordinary, Uriage, Paula's Choice, Dove, Johnson's, Senka.&lt;/p&gt;

&lt;p&gt;Korean shoppers use Olive Young the way Americans use a drugstore, French pharmacy brands included. On the Global chart there are two non-Korean brands in total, and one of them is Listerine.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the world buys that Korea's chart doesn't show
&lt;/h2&gt;

&lt;p&gt;The brands that are famous outside Korea are mostly missing from Korea's weekly top 100: Beauty of Joseon, SKIN1004, medicube, Purito Seoul, manyo, Rejuran and Centellian24 are all on the Global chart and none of them is on the Korean one.&lt;/p&gt;

&lt;p&gt;The category mix differs as well:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Global top 100&lt;/th&gt;
&lt;th&gt;Korea top 100&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Skincare, masks, cleansers, sun&lt;/td&gt;
&lt;td&gt;44&lt;/td&gt;
&lt;td&gt;49&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Makeup&lt;/td&gt;
&lt;td&gt;26&lt;/td&gt;
&lt;td&gt;30&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sunscreen only&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Supplements&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Food &amp;amp; drink&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Global #2 overall is a diet jelly. Probiotic sticks appear three times. International shoppers treat the store as a Korean pharmacy, not only a skincare shop.&lt;/p&gt;

&lt;h2&gt;
  
  
  Character editions sell better abroad than at home
&lt;/h2&gt;

&lt;p&gt;Fourteen of the Global top 100 are Sanrio editions (Korea: 8). Another eight are Anpanman editions, including a toothpaste, a mouthwash and a popcorn bucket. About a quarter of the international chart is a regular product in a cartoon box.&lt;/p&gt;

&lt;h2&gt;
  
  
  The same barcode costs 1.6x more on the Global store
&lt;/h2&gt;

&lt;p&gt;For the 32 matched products I compared the listed sale price on each store, converting won at 1,360 per dollar (the rate that day).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Median: the Global price is &lt;strong&gt;1.59x&lt;/strong&gt; the Korean price.&lt;/li&gt;
&lt;li&gt;22 of 32 are more than 1.5x.&lt;/li&gt;
&lt;li&gt;Range: 0.96x (Dr. Althea 345 Relief Cream set, $20.52 vs ₩29,000) to 2.27x (Anua PDRN capsule serum, Sanrio edition, $46.55 vs ₩27,900).&lt;/li&gt;
&lt;li&gt;The #1 sheet mask set: $13.50 abroad, ₩9,900 (about $7.28) in Korea.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both stores were running sales when I looked: 90 of the Global top 100 and 82 of the Korean top 100 were discounted, by a median of 26% and 29%.&lt;/p&gt;

&lt;h2&gt;
  
  
  Review counts live in different universes
&lt;/h2&gt;

&lt;p&gt;Korea's top 100 carries 5.15 million reviews in total, with a median of about 21,000 per product. The Global top 100: 105,902 in total, median 387. Fourteen Global best-sellers have no rating yet and 25 have fewer than 50 reviews.&lt;/p&gt;

&lt;p&gt;If you rank products by review count, on the Global store you're ranking by how long the listing has existed.&lt;/p&gt;

&lt;h2&gt;
  
  
  A few more things in the Global data
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Stock is visible.&lt;/strong&gt; The Global store reports units in stock: median 273 across the top 100, eight products under 50, and one set at #18 down to 3 units.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ingredients come in English.&lt;/strong&gt; 85 of the 100 have an ingredient list (median 46 ingredients). Ceramide NP is in 36%, Niacinamide in 35%, Adenosine in 35%, Sodium DNA (PDRN) in 16%. Fragrance: 28%.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Two thirds are sets&lt;/strong&gt; on both charts: double packs, refill bundles, "+ mini" gift sets. Single units are the exception.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not everything is made in Korea.&lt;/strong&gt; Six of the Global top 100 list another country of manufacture: four accessories from China, Listerine from Thailand, one highlighter from the USA.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Reproducing it
&lt;/h2&gt;

&lt;p&gt;The Global chart comes from my new &lt;a href="https://apify.com/cocomoon/oliveyoung-global-scraper" rel="noopener noreferrer"&gt;Olive Young Global Scraper&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bestsellers"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"includeDetails"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"maxItems"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Korean chart comes from the &lt;a href="https://apify.com/cocomoon/oliveyoung-scraper" rel="noopener noreferrer"&gt;Olive Young Scraper&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ranking"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"rankingCategories"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"all"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"rankingPeriod"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"WEEK"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"rankingTop"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both return a &lt;code&gt;barcode&lt;/code&gt; field, and the Global one returns &lt;code&gt;options[].barcode&lt;/code&gt; as well. The charts themselves come back in seconds; adding details takes a few minutes because it fetches three extra pages per product. Schedule both daily and you get a rank, price and stock history for each market.&lt;/p&gt;

&lt;h2&gt;
  
  
  Caveats
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;One day, one snapshot. The Korean chart is the weekly one; the Global store doesn't say what period its "Top Orders" chart covers.&lt;/li&gt;
&lt;li&gt;32 is a lower bound. A product sold as a single in one store and as a double pack in the other has two different barcodes and doesn't match.&lt;/li&gt;
&lt;li&gt;Korean prices include 10% VAT, and neither side includes shipping. The price gap is between list prices, not what lands on your card.&lt;/li&gt;
&lt;li&gt;For products with options I compared the matching option's price where the barcode matched an option, and the listing price otherwise.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you track K-beauty for a living, look at both charts. They agree on the #1 and on not much else.&lt;/p&gt;

</description>
      <category>datascience</category>
      <category>webscraping</category>
      <category>showdev</category>
      <category>korea</category>
    </item>
    <item>
      <title>Korean cosmetic labels are in Korean. I mapped 50,000 ingredient entries to English INCI names — here's what matched and what broke.</title>
      <dc:creator>MOON</dc:creator>
      <pubDate>Thu, 01 Oct 2026 16:50:05 +0000</pubDate>
      <link>https://dev.to/cocomoon/korean-cosmetic-labels-are-in-korean-i-mapped-50000-ingredient-entries-to-english-inci-names--edb</link>
      <guid>https://dev.to/cocomoon/korean-cosmetic-labels-are-in-korean-i-mapped-50000-ingredient-entries-to-english-inci-names--edb</guid>
      <description>&lt;p&gt;Two days ago I posted an &lt;a href="https://dev.to/cocomoon/i-pulled-the-full-ingredient-lists-of-olive-youngs-top-100-serums-71-of-them-contain-niacinamide-11kl"&gt;ingredient breakdown of Olive Young's top 100 serums&lt;/a&gt;, with one honest caveat at the bottom: the ingredient names came back in Korean, exactly as printed on the label, and I had grouped them by their Korean names myself.&lt;/p&gt;

&lt;p&gt;That's fine for one blog post and useless for anyone who wants to compare a Korean label with a US or EU product. &lt;code&gt;병풀추출물&lt;/code&gt; means nothing to an ingredient checker. &lt;code&gt;Centella Asiatica Extract&lt;/code&gt; does. So I added English INCI names to the scraper, and this is what it took.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: find a dictionary you're actually allowed to use
&lt;/h2&gt;

&lt;p&gt;Korean cosmetic labels use standardized Korean ingredient names, and each one maps to an INCI name. The obvious source is the industry association's online ingredient dictionary. It has a nice search page — and terms of use that forbid using the data commercially without prior consent. I charge for the scraper, so that was out.&lt;/p&gt;

&lt;p&gt;The answer turned out to be government open data. Korea's Ministry of Food and Drug Safety publishes its cosmetic ingredient list on the national open-data portal with no usage restrictions: 21,945 standard names, each with the English name, CAS number and a list of synonyms. One API key and 220 paged requests later I had a Korean-to-English map of about 24,000 names (standard names plus synonyms).&lt;/p&gt;

&lt;p&gt;If you scrape for a living: read the terms before you build. The second source was better anyway.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: labels are messier than dictionaries
&lt;/h2&gt;

&lt;p&gt;A plain exact-match lookup isn't enough, because a label is written by a person:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Amounts glued to the name.&lt;/strong&gt; &lt;code&gt;나이아신아마이드 20%&lt;/code&gt;, &lt;code&gt;소듐하이알루로네이트(1,000ppm)&lt;/code&gt;, &lt;code&gt;글라이콜릭애씨드(7%)&lt;/code&gt;. Strip trailing amounts and parentheses, but try the raw name first, because some real names end in a parenthesis.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Footnote markers.&lt;/strong&gt; &lt;code&gt;토코페롤*PDRN: 0.015%&lt;/code&gt; is tocopherol plus a footnote about something else. Everything after the &lt;code&gt;*&lt;/code&gt; goes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hyphens come and go.&lt;/strong&gt; The dictionary says &lt;code&gt;1,2-헥산다이올&lt;/code&gt;, labels say &lt;code&gt;1,2헥산다이올&lt;/code&gt;. I keep a second index with hyphens removed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Latin letters change case.&lt;/strong&gt; &lt;code&gt;T-부틸&lt;/code&gt; on the label, &lt;code&gt;t-부틸&lt;/code&gt; in the dictionary.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spaces and stray quotes&lt;/strong&gt; from copy-pasted spreadsheets.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The English side is messy too.&lt;/strong&gt; The source gives &lt;code&gt;Water,Aqua&lt;/code&gt; and &lt;code&gt;Titanium Dioxide,CI 77891&lt;/code&gt; — alternative names joined by a comma with no space — while &lt;code&gt;1,2-Hexanediol&lt;/code&gt; has a comma that belongs to the name. Splitting on "comma followed by a letter" keeps the first and leaves the second alone.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Result: 96.7% of entries, two thirds of products completely
&lt;/h2&gt;

&lt;p&gt;I tested on 966 popular products from 12 category searches (toner, cream, sunscreen, cleanser, sheet mask, cushion, lip, shampoo, body lotion, eye cream, essence, lotion): 49,843 ingredient entries in total.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;96.7% of entries&lt;/strong&gt; got an English name.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;66% of products&lt;/strong&gt; (641) were translated completely, every ingredient.&lt;/li&gt;
&lt;li&gt;The median product is 100% matched; the worst tenth sits around 92%.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What's left unmatched is mostly not a dictionary problem: label typos (&lt;code&gt;폴리그리세릴&lt;/code&gt; for &lt;code&gt;폴리글리세릴&lt;/code&gt;), marketing names that aren't standard names ("plant-derived squalane"), colorant lakes, and leftovers from shade-by-shade lists in makeup. Those come back as &lt;code&gt;null&lt;/code&gt; in that position, with the Korean original untouched next to it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you can see once it's in English
&lt;/h2&gt;

&lt;p&gt;With English names, the same 966 products become comparable with everything else you know. A few things that jumped out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Korean sunscreens run on filters the US doesn't have.&lt;/strong&gt; 68% of the sunscreen results contain Diethylamino Hydroxybenzoyl Hexyl Benzoate and 67% contain Ethylhexyl Triazone — neither is on the FDA's list of permitted sunscreen actives. Titanium Dioxide appears in 46%, Zinc Oxide in 29%.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cushion foundations are skincare claims in disguise.&lt;/strong&gt; 90% contain Niacinamide and 86% contain Adenosine, the two ingredients that let a Korean product be labelled brightening and anti-wrinkle.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;More than half the shampoos contain Salicylic Acid&lt;/strong&gt; (55%, versus 4% across the other categories) — scalp care is the selling point.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fragrance splits the store in two.&lt;/strong&gt; 82% of cushions, 81% of shampoos and 65% of body lotions list fragrance. Toners: 13%. Essences: 9%.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PDRN is spreading from serums into sheet masks&lt;/strong&gt;: 28% of the sheet-mask results list Sodium DNA.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And the boring backbone of all of it: Water (94%), Glycerin (84%), Butylene Glycol (81%), 1,2-Hexanediol (81%), Ethylhexylglycerin (68%).&lt;/p&gt;

&lt;h2&gt;
  
  
  Using it
&lt;/h2&gt;

&lt;p&gt;It's part of the &lt;a href="https://apify.com/cocomoon/oliveyoung-scraper" rel="noopener noreferrer"&gt;Olive Young Scraper&lt;/a&gt; on Apify. Same input as before:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"search"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"keywords"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"선크림"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"includeDetails"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"maxItems"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each product now carries both lists, in the same order:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ingredientList"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"정제수"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"다이부틸아디페이트"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"프로판다이올"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"…"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ingredientListEn"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Water"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Dibutyl Adipate"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Propanediol"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"…"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ingredientCount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ingredientsEnMatched"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;63&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So the counting script from the last post works unchanged — swap &lt;code&gt;ingredientList&lt;/code&gt; for &lt;code&gt;ingredientListEn&lt;/code&gt; and the output is readable without a Korean keyboard.&lt;/p&gt;

&lt;h2&gt;
  
  
  Caveats
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The category numbers are for search results on a keyword, not a curated category list; a few off-category products are in there.&lt;/li&gt;
&lt;li&gt;The English name is the first name the ministry lists for that ingredient. Where the EU and US names differ (Aqua vs. Water) you get one of them.&lt;/li&gt;
&lt;li&gt;96.7% is measured on these 966 products. Makeup with long shade lists matches worse than skincare.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you work with Korean ingredient data and something maps wrong, tell me — the dictionary is easy to patch.&lt;/p&gt;

</description>
      <category>datascience</category>
      <category>webscraping</category>
      <category>showdev</category>
      <category>korea</category>
    </item>
    <item>
      <title>I pulled the full ingredient lists of Olive Young's top 100 serums. 71 of them contain niacinamide.</title>
      <dc:creator>MOON</dc:creator>
      <pubDate>Wed, 30 Sep 2026 05:34:28 +0000</pubDate>
      <link>https://dev.to/cocomoon/i-pulled-the-full-ingredient-lists-of-olive-youngs-top-100-serums-71-of-them-contain-niacinamide-11kl</link>
      <guid>https://dev.to/cocomoon/i-pulled-the-full-ingredient-lists-of-olive-youngs-top-100-serums-71-of-them-contain-niacinamide-11kl</guid>
      <description>&lt;p&gt;Olive Young is where Korea buys its skincare — 1,300+ stores and the dominant online mall. Its search results are ranked by the site's own popularity order, so the first 100 results for &lt;code&gt;세럼&lt;/code&gt; (serum) are, in practice, the serums Koreans are buying right now.&lt;/p&gt;

&lt;p&gt;Every product page also carries the legally required full ingredient list (전성분). So I pulled the top 100 serum listings with their complete ingredient lists and counted what's actually inside them.&lt;/p&gt;

&lt;p&gt;The sample: 100 listings from 52 brands, collected on 2026-09-30. Average rating 4.8, a little over one million reviews between them. Median price ₩28,900 (about US$21); 70 of the 100 were on discount that day.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's in a best-selling Korean serum
&lt;/h2&gt;

&lt;p&gt;How many of the 100 listings contain each ingredient family:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Ingredient&lt;/th&gt;
&lt;th&gt;Listings&lt;/th&gt;
&lt;th&gt;What it's there for&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Niacinamide&lt;/td&gt;
&lt;td&gt;71&lt;/td&gt;
&lt;td&gt;Brightening&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hyaluronic acid (any form)&lt;/td&gt;
&lt;td&gt;68&lt;/td&gt;
&lt;td&gt;Hydration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Adenosine&lt;/td&gt;
&lt;td&gt;54&lt;/td&gt;
&lt;td&gt;Anti-wrinkle&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Panthenol&lt;/td&gt;
&lt;td&gt;53&lt;/td&gt;
&lt;td&gt;Barrier, soothing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Allantoin&lt;/td&gt;
&lt;td&gt;43&lt;/td&gt;
&lt;td&gt;Soothing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Centella (extract, madecassoside, asiaticoside…)&lt;/td&gt;
&lt;td&gt;42&lt;/td&gt;
&lt;td&gt;Soothing, "cica"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ceramides&lt;/td&gt;
&lt;td&gt;30&lt;/td&gt;
&lt;td&gt;Barrier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vitamin C (ascorbic acid and derivatives)&lt;/td&gt;
&lt;td&gt;25&lt;/td&gt;
&lt;td&gt;Brightening&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Peptides&lt;/td&gt;
&lt;td&gt;24&lt;/td&gt;
&lt;td&gt;Firming&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Beta-glucan&lt;/td&gt;
&lt;td&gt;24&lt;/td&gt;
&lt;td&gt;Hydration, soothing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PDRN (sodium DNA)&lt;/td&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;td&gt;The current hype&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Salicylic acid / BHA&lt;/td&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;td&gt;Pores, breakouts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Retinoids (retinol, retinal)&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;Anti-aging&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tranexamic acid&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Dark spots&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Five things that stood out
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Niacinamide and adenosine are nearly default.&lt;/strong&gt; 71 and 54 listings. That's not only formulator taste: both are on Korea's list of notified "functional cosmetic" ingredients, so including them at the specified level lets a brand legally label the product as brightening or anti-wrinkle. The ingredient list is partly a regulatory artifact.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. One hyaluronic acid is not enough anymore.&lt;/strong&gt; 68 listings contain some form of it, 20 contain three or more different forms, and 14 contain five or more (sodium hyaluronate, hydrolyzed hyaluronic acid, sodium acetylated hyaluronate, crosspolymers…). One product lists ten. "Multi-weight hyaluronic" has gone from a selling point to table stakes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. PDRN has arrived, including at #1.&lt;/strong&gt; 14 of the 100 list sodium DNA — the label name for PDRN, the salmon-DNA ingredient popularized by Korean skin-booster treatments. The #1 result, Anua's PDRN Hyaluronic Acid Capsule serum, has 25,242 reviews. Medicube's PDRN Pink Peptide ampoule shows up three times in different bundles. Retinoids, for comparison, appear in 7.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Korea has quietly replaced its preservatives.&lt;/strong&gt; 79 listings use 1,2-hexanediol and 73 use ethylhexylglycerin; only 10 use phenoxyethanol. Only 15 list fragrance (향료) and 7 list ethanol. If you formulate for the Korean market, that's the expected profile.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Formula length tells you nothing about sales.&lt;/strong&gt; The median serum has 38 ingredients, the longest has 88 — and the shortest has 3: a ₩5,700 (about $4) niacinamide 20% serum that's just rose water, niacinamide and glycerin. It sits at #13 with 20,328 reviews, ahead of products that cost five times as much.&lt;/p&gt;

&lt;p&gt;One more for anyone sourcing: 84 of the 100 are made in Korea, and a third of all listings come from just three contract manufacturers — Cosmax (15), Kolmar Korea (9) and Cosvision (9). The brand on the box is often not who made it; the ingredient-and-manufacturer field tells you who did.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I got the data
&lt;/h2&gt;

&lt;p&gt;Olive Young has no public API, so I used a scraper I built and published on Apify: &lt;a href="https://apify.com/cocomoon/oliveyoung-scraper" rel="noopener noreferrer"&gt;Olive Young Scraper&lt;/a&gt;. Its search mode returns products in popularity order, and a new option adds each product's detail page — full ingredient list, volume, shelf life, manufacturer, country of origin, barcodes and current promotion. The whole run was this input:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"search"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"keywords"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"세럼"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"includeDetails"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"maxItems"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It took about two and a half minutes. Each product comes back with &lt;code&gt;ingredients&lt;/code&gt; (the raw text) and &lt;code&gt;ingredientList&lt;/code&gt; (parsed into an array), so the counting is a few lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;collections&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Counter&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;apify_client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ApifyClient&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ApifyClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YOUR_APIFY_TOKEN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;actor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cocomoon/oliveyoung-scraper&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;run_input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mode&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;search&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;keywords&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;세럼&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;includeDetails&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;maxItems&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="n"&gt;items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;defaultDatasetId&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;iterate_items&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

&lt;span class="n"&gt;counts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Counter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;counts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ingredientList&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;counts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;most_common&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Swap the keyword for &lt;code&gt;토너&lt;/code&gt; (toner), &lt;code&gt;선크림&lt;/code&gt; (sunscreen) or a brand name and you get the same breakdown for that category.&lt;/p&gt;

&lt;h2&gt;
  
  
  Caveats
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;These are 100 &lt;em&gt;listings&lt;/em&gt;, not 100 unique formulas — Olive Young sells the same serum in several bundles, and popular products appear more than once. I left them in, because that's what the shelf looks like.&lt;/li&gt;
&lt;li&gt;The keyword search returns a few non-serums that match the word (one is a finishing powder).&lt;/li&gt;
&lt;li&gt;Ingredient names come back in Korean, as printed on the label. I matched families by name (for example every ingredient containing 하이알루로 counts as hyaluronic acid), so treat the counts as close, not exact. The English names and the "what it's for" column are mine.&lt;/li&gt;
&lt;li&gt;Popularity order is Olive Young's own ranking on one day; it moves with promotions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If there's a category you'd like to see broken down the same way, tell me in the comments.&lt;/p&gt;

</description>
      <category>datascience</category>
      <category>webscraping</category>
      <category>showdev</category>
      <category>korea</category>
    </item>
    <item>
      <title>Local SEO in Korea runs on Naver Map — and your rank changes every 500 meters</title>
      <dc:creator>MOON</dc:creator>
      <pubDate>Mon, 28 Sep 2026 04:08:24 +0000</pubDate>
      <link>https://dev.to/cocomoon/local-seo-in-korea-runs-on-naver-map-and-your-rank-changes-every-500-meters-o8f</link>
      <guid>https://dev.to/cocomoon/local-seo-in-korea-runs-on-naver-map-and-your-rank-changes-every-500-meters-o8f</guid>
      <description>&lt;p&gt;If you do local SEO for businesses in Korea, Google Maps is not where the fight happens. Koreans look for cafés, restaurants, salons and academies on &lt;strong&gt;Naver Map&lt;/strong&gt; (Naver Place), and the order of that list decides who gets the visit.&lt;/p&gt;

&lt;p&gt;Agencies here track that order every day — usually by opening the Naver app on one phone, at one desk, and counting.&lt;/p&gt;

&lt;p&gt;The catch: Naver ranks places by relevance &lt;strong&gt;and by distance from the person searching&lt;/strong&gt;. A rank checked from the office is the rank &lt;em&gt;for the office&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;So I measured how much it actually moves.&lt;/p&gt;

&lt;h2&gt;
  
  
  The experiment: 25 searches, 500 m apart
&lt;/h2&gt;

&lt;p&gt;Keyword: &lt;code&gt;카페&lt;/code&gt; (café). A 5×5 grid of search points, 500 m apart, centred on Gangnam Station in Seoul — about 2 km × 2 km. At each point I pulled Naver Place's top 100 and looked up two cafés near the station.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fofymgo76xtulch0xg2u1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fofymgo76xtulch0xg2u1.png" alt="Naver Place rank for 카페 on a 5x5 grid around Gangnam Station" width="800" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Café A is #1 at Gangnam Station.&lt;/strong&gt; It is in the top 3 at only 5 of the 25 points (20%), and &lt;strong&gt;not in the top 100 at all at 9 of them&lt;/strong&gt;. It still has the best average rank of every café on the grid — the whole top of the list reshuffles as you move.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Café B is not in the top 100 at the station&lt;/strong&gt; — but &lt;strong&gt;#1 just 500 m north&lt;/strong&gt;, and #2–#3 in the north-west corner. Checked from the station, you would report "we don't rank". Checked from the north exit, "we're #1". Both are true.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Two neighbouring cafés, the same keyword, and completely different "territories".&lt;/p&gt;

&lt;h2&gt;
  
  
  One gotcha: keywords with a place name
&lt;/h2&gt;

&lt;p&gt;If the keyword itself names an area — &lt;code&gt;강남역 카페&lt;/code&gt; ("Gangnam Station café"), &lt;code&gt;압구정 영어학원&lt;/code&gt; — Naver anchors results to that area. In my tests every grid point then returned the same rank. The geo-grid only tells you something for keywords &lt;strong&gt;without&lt;/strong&gt; a place name (&lt;code&gt;카페&lt;/code&gt;, &lt;code&gt;헤어샵&lt;/code&gt;, &lt;code&gt;영어학원&lt;/code&gt;), which is exactly how people search on their phone when they are already nearby.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the check works
&lt;/h2&gt;

&lt;p&gt;Naver's mobile place list accepts the searcher's coordinates and returns the top 100 places for a keyword, with IDs, categories, review counts and the separate paid-ad slots. So a rank check is one plain HTTP request per keyword per point — no browser, no login. A 5×5 grid is 25 requests and the whole run finishes in under a minute.&lt;/p&gt;

&lt;p&gt;I wrapped it into an Apify Actor so it can be scheduled and shared: &lt;strong&gt;&lt;a href="https://apify.com/cocomoon/naver-place-rank-tracker" rel="noopener noreferrer"&gt;Naver Place Rank Tracker&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Many keywords × many places per run (your business + competitors), by place ID, URL or name&lt;/li&gt;
&lt;li&gt;Any location, or a 3×3 / 5×5 / 7×7 geo-grid around it&lt;/li&gt;
&lt;li&gt;Organic rank and ad slot reported separately, plus the top competitors at each point&lt;/li&gt;
&lt;li&gt;A summary (average rank, best/worst, % of points in the top 3/10/20) and an &lt;strong&gt;HTML heat-map report&lt;/strong&gt; like the one above, generated on every run
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"keywords"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"카페"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"targetPlaces"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"https://m.place.naver.com/place/123456789"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"locations"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Gangnam Station=37.4979,127.0276"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"gridSize"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"gridSpacingMeters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pricing is per search (one keyword at one point): $0.003. The 5×5 grid above cost $0.075. Checking 10 keywords from one location every weekday is about $0.66 a month.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd do with it
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Stop reporting a single number.&lt;/strong&gt; "#1" means nothing without "where". Report the share of the neighbourhood where you are top 3.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Aim ad and offline spend at the gaps.&lt;/strong&gt; The grey cells are where the organic list does not show you — that is where a Naver Place ad, a flyer or a local blog review campaign has room to work.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Measure changes over the whole area.&lt;/strong&gt; Run the same grid weekly and compare the share of top-3 cells, not the rank from your desk.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you work on Korean local search, I'd love to hear what else you would want in the output.&lt;/p&gt;

</description>
      <category>seo</category>
      <category>webscraping</category>
      <category>showdev</category>
      <category>korea</category>
    </item>
    <item>
      <title>Korea shuts down for three days this week for Chuseok. Does your country have a holiday like this?</title>
      <dc:creator>MOON</dc:creator>
      <pubDate>Wed, 23 Sep 2026 02:01:58 +0000</pubDate>
      <link>https://dev.to/cocomoon/korea-shuts-down-for-three-days-this-week-for-chuseok-does-your-country-have-a-holiday-like-this-15hj</link>
      <guid>https://dev.to/cocomoon/korea-shuts-down-for-three-days-this-week-for-chuseok-does-your-country-have-a-holiday-like-this-15hj</guid>
      <description>&lt;p&gt;This Thursday to Saturday (Sept 24–26) South Korea basically closes. It's Chuseok (추석) — our harvest festival, held on the 15th day of the 8th lunar month, when the moon is supposed to be the biggest and brightest of the year. This year that's Friday the 25th.&lt;/p&gt;

&lt;p&gt;I work in marketing in Seoul, and the week before Chuseok is a strange mix: everyone is scrambling to finish things before the break, and the whole city is carrying gift boxes. Spam sets, fruit sets, toothpaste sets (yes, really), Korean beef, dried yellow corvina. The subway smells like pears.&lt;/p&gt;

&lt;p&gt;What Chuseok actually looks like for most families:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The migration.&lt;/strong&gt; Tens of millions of people drive to their hometowns, so a trip that normally takes 3 hours takes 8. The traffic map on the news is its own genre of entertainment — every year someone spots a car stuck at the same exit as last year.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Charye (차례).&lt;/strong&gt; A memorial table for ancestors on the morning of Chuseok: rice, soup, fruit stacked in odd numbers, jeon (savory pancakes), and always the family argument about which side of the table the fish goes on. More families are skipping or simplifying it every year, and there's a running joke about who actually stands over the frying pan for six hours the day before.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Songpyeon (송편).&lt;/strong&gt; Half-moon rice cakes with sesame or bean filling, steamed over pine needles. Legend says if you make pretty ones you'll have a pretty baby. Nobody's songpyeon is pretty.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Beolcho (벌초).&lt;/strong&gt; In the weeks before, families go out to cut the grass on their ancestors' grave mounds. Trimmers everywhere.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The moon.&lt;/strong&gt; After dinner, people go outside to look at the full moon and make a wish. It's genuinely the one part of the holiday nobody complains about.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What surprised me when I started working with people overseas is how many places have the same idea on the same day. The Mid-Autumn Festival in China, Tết Trung Thu in Vietnam (where it's more of a children's lantern festival), and Tsukimi in Japan (moon-viewing with round dango) all land on the same lunar date — so this Friday, a big chunk of East Asia is looking at the same moon and eating something round.&lt;/p&gt;

&lt;p&gt;And then there are the harvest festivals that aren't about the moon at all: Thanksgiving in the US and Canada, Erntedankfest in Germany, Sukkot, Pongal in southern India. Different dates, same instinct — the crops are in, gather the family, eat too much, argue about something.&lt;/p&gt;

&lt;p&gt;So I'm curious:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Does your country have a "go home, see the family, eat the special food" holiday? What's the food?&lt;/li&gt;
&lt;li&gt;Is there a traffic-jam or airport-chaos tradition around it?&lt;/li&gt;
&lt;li&gt;Is there a task everyone secretly dreads (our answer is standing at the frying pan)?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Happy Chuseok from Seoul 🌕 — I'll be reading replies from the passenger seat somewhere on the Gyeongbu Expressway.&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>watercooler</category>
      <category>culture</category>
      <category>korea</category>
    </item>
    <item>
      <title>Korea's #1 sunscreen gets 165 reviews a day. I analyzed the newest 500 — here's what Koreans actually say</title>
      <dc:creator>MOON</dc:creator>
      <pubDate>Mon, 21 Sep 2026 07:39:59 +0000</pubDate>
      <link>https://dev.to/cocomoon/koreas-1-sunscreen-gets-165-reviews-a-day-i-analyzed-the-newest-500-heres-what-koreans-2odj</link>
      <guid>https://dev.to/cocomoon/koreas-1-sunscreen-gets-165-reviews-a-day-i-analyzed-the-newest-500-heres-what-koreans-2odj</guid>
      <description>&lt;p&gt;If you follow K-beauty you've seen the Mediheal Madecassoside Moisture Sun Serum SPF50+ PA++++ — a "sun serum" that's currently the #1 sunscreen at Olive Young, Korea's biggest beauty retailer. It had &lt;strong&gt;17,189 reviews and a 4.9 average&lt;/strong&gt; on Olive Young's Korean site when I collected the data.&lt;/p&gt;

&lt;p&gt;Western reviews of Korean sunscreens are written by people who paid $25 on Amazon. Korean reviews are written by people who picked up a discounted bundle at the store down the street and are on their fifth tube. I wanted the second group's opinion.&lt;/p&gt;

&lt;p&gt;So I pulled the &lt;strong&gt;500 most recent reviews&lt;/strong&gt; from Olive Young — with star rating, repurchase flag, photo flag, and the reviewer's self-reported skin type, skin tone and skin concerns — and read them.&lt;/p&gt;

&lt;h2&gt;
  
  
  The pace alone is a data point
&lt;/h2&gt;

&lt;p&gt;The 500 newest reviews were all posted between &lt;strong&gt;September 5 and September 7, 2026&lt;/strong&gt;. That's roughly &lt;strong&gt;165 reviews per day&lt;/strong&gt; for one sunscreen, in early September. Korean sunscreen season doesn't end in August.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ratings: 92% five stars
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Stars&lt;/th&gt;
&lt;th&gt;Reviews&lt;/th&gt;
&lt;th&gt;Share&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;★★★★★&lt;/td&gt;
&lt;td&gt;460&lt;/td&gt;
&lt;td&gt;92.0%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;★★★★&lt;/td&gt;
&lt;td&gt;27&lt;/td&gt;
&lt;td&gt;5.4%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;★★★&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;1.6%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;★★&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;0.2%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;★&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;0.8%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;31.4% are marked as repurchases.&lt;/strong&gt; Olive Young verifies this from order history, so that's nearly a third of recent reviewers buying it again.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;32% include photos.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;8.4% are "one-month-use" reviews (written after 30+ days of use — Olive Young tags these separately).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Who is buying it (self-reported skin profile)
&lt;/h2&gt;

&lt;p&gt;Of reviewers who disclosed a skin type: &lt;strong&gt;combination 21, dry 18, oily 13, sensitive 6, acne-prone 2, normal 1.&lt;/strong&gt; So it's not a "dry skin only" product — combination and oily users are a majority.&lt;/p&gt;

&lt;p&gt;Skin tones skew cool: summer cool 17, cool 12, spring warm 9, warm 9, autumn warm 8, winter cool 5.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Top skin concerns among reviewers:&lt;/strong&gt; dark spots (28), brightening (19), breakouts (15), flakiness (11), wrinkles (10). This tracks — "madecassoside" and "trace repair" (흔적 리페어) in the name are aimed at post-acne marks, and buyers are self-selecting for it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the reviews actually talk about
&lt;/h2&gt;

&lt;p&gt;I counted how many of the 500 reviews mention each theme (Korean keywords, translated):&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Theme&lt;/th&gt;
&lt;th&gt;Reviews mentioning it&lt;/th&gt;
&lt;th&gt;What they say&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;"Hydrating / moist" (촉촉)&lt;/td&gt;
&lt;td&gt;213 (43%)&lt;/td&gt;
&lt;td&gt;The single most common word. Reviewers describe it as a moisturizer that happens to be SPF 50.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Sticky" (끈적)&lt;/td&gt;
&lt;td&gt;105 (21%)&lt;/td&gt;
&lt;td&gt;Almost always in the negative: &lt;em&gt;"not sticky"&lt;/em&gt;. This is the #1 fear with Korean sunscreens and this one passes.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Makeup / base" (화장)&lt;/td&gt;
&lt;td&gt;101 (20%)&lt;/td&gt;
&lt;td&gt;Used as a makeup base; the recurring claim is that foundation doesn't pill or slide over it.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Moisture" (수분)&lt;/td&gt;
&lt;td&gt;100 (20%)&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"White cast" (백탁)&lt;/td&gt;
&lt;td&gt;80 (16%)&lt;/td&gt;
&lt;td&gt;Overwhelmingly &lt;em&gt;"no white cast"&lt;/em&gt;. A handful of dissenters.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Absorbs" (흡수)&lt;/td&gt;
&lt;td&gt;67 (13%)&lt;/td&gt;
&lt;td&gt;Fast absorption.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Stuffy / heavy" (답답)&lt;/td&gt;
&lt;td&gt;51 (10%)&lt;/td&gt;
&lt;td&gt;Again mostly &lt;em&gt;"not stuffy"&lt;/em&gt; — the sunscreen-that-doesn't-feel-like-sunscreen theme.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Irritation" (자극)&lt;/td&gt;
&lt;td&gt;50 (10%)&lt;/td&gt;
&lt;td&gt;Mostly &lt;em&gt;"no irritation"&lt;/em&gt;, including on sensitive skin.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Light" (가벼)&lt;/td&gt;
&lt;td&gt;43 (9%)&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Summer" (여름)&lt;/td&gt;
&lt;td&gt;33 (7%)&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Pilling" (밀림)&lt;/td&gt;
&lt;td&gt;30 (6%)&lt;/td&gt;
&lt;td&gt;Mixed — a few mention pilling under makeup.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;"Eye stinging" (눈시림)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;29 (6%)&lt;/td&gt;
&lt;td&gt;The most common &lt;em&gt;actual&lt;/em&gt; complaint — but many say it &lt;em&gt;doesn't&lt;/em&gt; sting, which for Korean users is a selling point.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Trace / marks" (흔적)&lt;/td&gt;
&lt;td&gt;22 (4%)&lt;/td&gt;
&lt;td&gt;People buying it for post-acne marks, per the name.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The negative themes to watch if you sell this: eye stinging (a minority but real) and pilling under heavy makeup.&lt;/p&gt;

&lt;h2&gt;
  
  
  In their words (translated)
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;"It's a sunscreen but feels like a serum, so I keep reaching for it. I didn't even realize it was sunscreen at first — the texture is thin and soft, and it stays moist." — ★5, repurchase&lt;/p&gt;

&lt;p&gt;"I have dry skin and most sunscreens make my face feel tight by afternoon. This one has real hydration, so I use it as my daily sun serum." — ★5, dry skin&lt;/p&gt;

&lt;p&gt;"Almost no white cast, glides on soft and moist. I hate sunscreens that turn me white; this one just absorbs naturally. Not too sticky either. My daily sunscreen now." — ★5, repurchase&lt;/p&gt;

&lt;p&gt;"Sunscreen always felt stuffy so I avoided it. This one goes on like a hydrating serum, light. I can use it every morning without dreading it." — ★5&lt;/p&gt;

&lt;p&gt;"Doesn't pill or feel thick under makeup, and it preps the skin so base goes on smoothly." — ★5, repurchase&lt;/p&gt;

&lt;p&gt;"It's really easy to control how much comes out — it doesn't gush, and you need very little. A small amount covers the whole face, and it's not heavy, so it was genuinely useful all summer." — ★5, repurchase&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What this means if you're outside Korea
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;This is a "sunscreen for people who hate sunscreen."&lt;/strong&gt; Every dominant theme is the absence of a sunscreen negative — not sticky, not heavy, no white cast, no stuffiness. That's the pitch Korean users respond to, and it's the pitch that works abroad.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Repurchase is the metric that matters.&lt;/strong&gt; 31% repurchase in the newest 500 is unusually high for a sunscreen; hype products get five-star first reviews, staples get repurchases.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Combination/oily buyers are the majority&lt;/strong&gt;, despite "moisture" in the name. Don't position it as dry-skin-only.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The bundle is the product.&lt;/strong&gt; 85% of reviewers bought a bundle — 48% the 50+50+15 g set and 36% the 50+50 g double pack — and only 13% the single tube. Olive Young's "기획" (bundle promotion) is where the volume is.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Methodology
&lt;/h2&gt;

&lt;p&gt;500 most recent reviews of goods no. A000000232672 on oliveyoung.co.kr, collected 2026-09-07 with the review API's own fields (star rating, repurchase flag, one-month-use flag, photo flag, reviewer skin type/tone/concern codes). Skin profile is self-reported and optional, so counts don't sum to 500. Theme counts are keyword matches on the Korean text; translations are mine.&lt;/p&gt;

&lt;p&gt;I collected the reviews with a scraper I built and published on Apify: &lt;a href="https://apify.com/cocomoon/oliveyoung-review-scraper" rel="noopener noreferrer"&gt;Olive Young Reviews Scraper&lt;/a&gt;. It returns the same fields for any Olive Young product — star rating, verified repurchase flag, photos, and the reviewer's skin type / tone / concerns already translated to English — so you can run this exact analysis on your own product or a competitor's. Apify's free plan covers roughly 1,600 reviews a month.&lt;/p&gt;

&lt;p&gt;To find product numbers by keyword or brand, I use the companion &lt;a href="https://apify.com/cocomoon/oliveyoung-scraper" rel="noopener noreferrer"&gt;Olive Young Scraper&lt;/a&gt;; there's a step-by-step walkthrough in my earlier post, &lt;em&gt;How to get Olive Young and Daiso Korea product data as JSON&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;If there's a K-beauty product you'd like me to run this on next, tell me in the comments.&lt;/p&gt;

</description>
      <category>datascience</category>
      <category>webscraping</category>
      <category>analytics</category>
      <category>showdev</category>
    </item>
    <item>
      <title>I shipped a paid SaaS in 3 days with no user accounts: the billing setup and 3 bugs that bit me</title>
      <dc:creator>MOON</dc:creator>
      <pubDate>Thu, 17 Sep 2026 09:17:45 +0000</pubDate>
      <link>https://dev.to/cocomoon/i-shipped-a-paid-saas-in-3-days-with-no-user-accounts-the-billing-setup-and-3-bugs-that-bit-me-4n54</link>
      <guid>https://dev.to/cocomoon/i-shipped-a-paid-saas-in-3-days-with-no-user-accounts-the-billing-setup-and-3-bugs-that-bit-me-4n54</guid>
      <description>&lt;p&gt;I write a small blog on the side. Every time I picked a topic I hit the same wall: Ahrefs and Semrush are $130+ a month, and even when I had the numbers, "volume 590, difficulty 17" didn't tell me whether to write the post or skip it.&lt;/p&gt;

&lt;p&gt;So I built &lt;a href="https://keyword-brief.vercel.app" rel="noopener noreferrer"&gt;Keyword Brief&lt;/a&gt;. You type a keyword and get a plain-language &lt;strong&gt;GO / MAYBE / SKIP&lt;/strong&gt;, real Google volume and difficulty, a read of what the top 10 pages actually cover, and an outline with the gaps they left open. It deliberately does not write the article for you.&lt;/p&gt;

&lt;p&gt;This post is about how it's built, because the part I'm happiest with is the part users never see: &lt;strong&gt;there are no accounts&lt;/strong&gt;. No signup, no password reset, no user table, and it still takes payments.&lt;/p&gt;

&lt;h2&gt;
  
  
  The stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Next.js&lt;/strong&gt; on Vercel&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DataForSEO&lt;/strong&gt; for search volume, difficulty, and the live top 10&lt;/li&gt;
&lt;li&gt;A plain &lt;code&gt;fetch&lt;/code&gt; + cheerio pass to read the H2/H3 headings off each ranking page (free, and more honest than a "content score")&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Claude&lt;/strong&gt; to turn those headings and the People Also Ask questions into an outline&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lemon Squeezy&lt;/strong&gt; for subscriptions and license keys&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One check costs me roughly $0.10. Pro is $19.90 a month.&lt;/p&gt;

&lt;h2&gt;
  
  
  Billing without accounts
&lt;/h2&gt;

&lt;p&gt;Here's the whole model:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Free tier:&lt;/strong&gt; 3 checks per browser, counted in an HMAC-signed cookie. You can't edit the number, and I don't need a database row to remember you.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Paid:&lt;/strong&gt; a Lemon Squeezy subscription with "Generate license keys" turned on.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One-click activation:&lt;/strong&gt; Lemon Squeezy lets you put variables in the confirmation button link. Mine is:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://keyword-brief.vercel.app/activate?key=[license_key]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After checkout the customer clicks one button, lands on &lt;code&gt;/activate&lt;/code&gt;, and the page activates the key for that browser and strips it from the URL. No copy and paste. The same link is on the receipt email as a fallback.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Staying honest:&lt;/strong&gt; the server re-validates the stored key at most once an hour. Cancel or refund, and Pro switches off on its own.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// First time a key is seen in this browser: register the browser as one "instance" of the key.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;json&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;lsPost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;activate&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;license_key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;instance_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`web-&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;activated&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="c1"&gt;// cookie = sign(`${key}|${json.instance.id}`)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The expensive call (the Claude outline) is a second request, so it's gated too: the first request issues a short-lived, keyword-bound token, and the outline endpoint refuses to run without it. Otherwise anyone could skip the free counter by calling that endpoint directly.&lt;/p&gt;

&lt;p&gt;Yes, someone can clear cookies to get 3 more free checks. For a $19.90 tool that's a trade I'll take in exchange for zero signup friction.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bug 1: every new customer was "inactive"
&lt;/h2&gt;

&lt;p&gt;My first test purchase failed with &lt;em&gt;"This key is inactive."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A fresh Lemon Squeezy key has status &lt;code&gt;inactive&lt;/code&gt;. That doesn't mean invalid. It means "not activated on any device yet" (0/5). I was calling &lt;code&gt;/validate&lt;/code&gt; and rejecting anything that wasn't &lt;code&gt;active&lt;/code&gt;, which means I was rejecting every brand-new paying customer.&lt;/p&gt;

&lt;p&gt;The fix is to call &lt;code&gt;/activate&lt;/code&gt; the first time you see a key (that's what flips it to &lt;code&gt;active&lt;/code&gt; and enforces the device limit), then &lt;code&gt;/validate&lt;/code&gt; with the &lt;code&gt;instance_id&lt;/code&gt; afterwards, and &lt;code&gt;/deactivate&lt;/code&gt; when the user removes the key so the slot is freed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bug 2: structured outputs ignored my array limits
&lt;/h2&gt;

&lt;p&gt;I defined the outline schema with zod, including things like "at most 4 points per section":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;points&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;About one request in three blew up with a validation error. Structured outputs guarantee the &lt;em&gt;shape&lt;/em&gt;, but array length constraints aren't enforced during generation. The model wrote 5 good points, and my own validator threw the whole response away.&lt;/p&gt;

&lt;p&gt;Now the schema has no length limits. The lengths live in the prompt, and I trim in code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;sections&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sections&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;points&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;points&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Bug 3: "top 10" returned 6 results
&lt;/h2&gt;

&lt;p&gt;DataForSEO's SERP &lt;code&gt;depth: 10&lt;/code&gt; doesn't mean 10 organic results. It counts every element on the page: videos, People Also Ask, image packs. I was getting 6 organic links and confidently telling users "the top 10 has plenty of small sites."&lt;/p&gt;

&lt;p&gt;Ask for &lt;code&gt;depth: 30&lt;/code&gt;, filter to &lt;code&gt;type === "organic"&lt;/code&gt;, take the first 10.&lt;/p&gt;

&lt;h2&gt;
  
  
  A feature I didn't plan
&lt;/h2&gt;

&lt;p&gt;I'm not a native English speaker, and while testing I typed &lt;em&gt;"how to fishing well"&lt;/em&gt;. No data at all, because nobody searches that.&lt;/p&gt;

&lt;p&gt;Returning "no demand" would have been wrong and a bit insulting. Now, when a phrase has no data, Claude rewrites it into 4 to 6 natural queries, I verify those against DataForSEO in one batch call, and the page shows what people actually search, with volumes: &lt;em&gt;fishing tips (1,600), fishing tips for beginners (320), how to catch more fish (140)&lt;/em&gt;. Those "no data" lookups don't count against the free checks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Perceived speed
&lt;/h2&gt;

&lt;p&gt;A full check took about 36 seconds, nearly all of it the outline. I split it in two: the verdict, numbers, and page-one analysis render in about 7 seconds, and the brief fills in underneath while you're reading. Same total time, completely different feel.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://keyword-brief.vercel.app" rel="noopener noreferrer"&gt;keyword-brief.vercel.app&lt;/a&gt; gives you one free check straight away, no signup. Sign in with Google and you get two more.&lt;/p&gt;

&lt;p&gt;Pro is open now — $19.90 a month, or $89 for six months, or $149 a year. It lifts the check limit and follows your account to any device. Payments go through Gumroad, and you can cancel from the receipt at any time.&lt;/p&gt;

&lt;p&gt;The thing I most want to hear: &lt;strong&gt;try a keyword you know well and tell me if the verdict is wrong.&lt;/strong&gt; The GO / MAYBE / SKIP rules are simple and transparent on purpose, and real counterexamples are how they get better.&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>saas</category>
      <category>nextjs</category>
      <category>webdev</category>
    </item>
    <item>
      <title>I pulled the real sales numbers from Daiso Korea's website. Here are the 48 products Koreans actually buy.</title>
      <dc:creator>MOON</dc:creator>
      <pubDate>Wed, 09 Sep 2026 09:01:57 +0000</pubDate>
      <link>https://dev.to/cocomoon/i-pulled-the-real-sales-numbers-from-daiso-koreas-website-here-are-the-48-products-koreans-1ahm</link>
      <guid>https://dev.to/cocomoon/i-pulled-the-real-sales-numbers-from-daiso-koreas-website-here-are-the-48-products-koreans-1ahm</guid>
      <description>&lt;p&gt;Every "Korean Daiso haul" video tells you what one person bought. I wanted to know what &lt;strong&gt;everyone&lt;/strong&gt; buys.&lt;/p&gt;

&lt;p&gt;It turns out Daiso Korea's online mall (daisomall.co.kr) exposes a number most retailers hide: the &lt;strong&gt;cumulative units ordered&lt;/strong&gt; for every product. So I collected 2,349 unique products across 15 categories — beauty, skincare, kitchen, cleaning, storage, stationery, pets, snacks — and ranked them by real sales volume. Together these 2,349 products have sold &lt;strong&gt;24.8 million units&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Here is what the data says. (Prices in Korean won; ₩1,000 ≈ US$0.74.)&lt;/p&gt;

&lt;h2&gt;
  
  
  The headline numbers
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;33 of the 48 best-sellers are beauty or personal care.&lt;/strong&gt; Daiso Korea is, by volume, a beauty store that also sells kitchen towels.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;23 of the 48 cost ₩1,000 (~$0.74) or less.&lt;/strong&gt; Nothing costs more than ₩5,000 ($3.70) — 13 sit right at that ceiling.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Average rating of the 48: 4.80 / 5.&lt;/strong&gt; Not one of them is sold out — Daiso keeps its winners in stock.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The single best-selling item is a pack of wet wipes: 994,677 units.&lt;/strong&gt; Not glamorous, but that's a million packs of one SKU from one online channel.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Where the volume is (by category, whole sample)
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Products sampled&lt;/th&gt;
&lt;th&gt;Units sold&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Beauty &amp;amp; hygiene&lt;/td&gt;
&lt;td&gt;906&lt;/td&gt;
&lt;td&gt;13.6M&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cleaning &amp;amp; bathroom&lt;/td&gt;
&lt;td&gt;325&lt;/td&gt;
&lt;td&gt;4.6M&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Storage &amp;amp; organization&lt;/td&gt;
&lt;td&gt;175&lt;/td&gt;
&lt;td&gt;1.6M&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Kitchen&lt;/td&gt;
&lt;td&gt;129&lt;/td&gt;
&lt;td&gt;1.5M&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Food &amp;amp; snacks&lt;/td&gt;
&lt;td&gt;206&lt;/td&gt;
&lt;td&gt;1.0M&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stationery&lt;/td&gt;
&lt;td&gt;187&lt;/td&gt;
&lt;td&gt;0.9M&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sports &amp;amp; hobby&lt;/td&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;0.8M&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pet supplies&lt;/td&gt;
&lt;td&gt;178&lt;/td&gt;
&lt;td&gt;0.6M&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Beauty alone is 55% of all units in the sample.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 50 best-selling products at Daiso Korea (by cumulative units)
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Daiso lists many products twice (single unit and bulk box) sharing the same sales counter; duplicates were merged, so 50 listings = 48 unique products.&lt;/em&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;Product&lt;/th&gt;
&lt;th&gt;Price&lt;/th&gt;
&lt;th&gt;Units sold&lt;/th&gt;
&lt;th&gt;Rating (reviews)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Eclat clean wet wipes, cap-type, 150 sheets&lt;/td&gt;
&lt;td&gt;₩1,000&lt;/td&gt;
&lt;td&gt;994,677&lt;/td&gt;
&lt;td&gt;4.8 (25,764)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Living pull-out kitchen towels, 150 sheets&lt;/td&gt;
&lt;td&gt;₩1,000&lt;/td&gt;
&lt;td&gt;770,852&lt;/td&gt;
&lt;td&gt;4.9 (20,361)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Tempo toilet paper roll, 24 m&lt;/td&gt;
&lt;td&gt;₩500&lt;/td&gt;
&lt;td&gt;590,389&lt;/td&gt;
&lt;td&gt;4.9 (4,923)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;VT PDRN Glow sheet mask&lt;/strong&gt; (1 sheet)&lt;/td&gt;
&lt;td&gt;₩1,000&lt;/td&gt;
&lt;td&gt;499,272&lt;/td&gt;
&lt;td&gt;4.9 (7,781)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Mommy Care sea grape skin pads, 80 pads&lt;/td&gt;
&lt;td&gt;₩5,000&lt;/td&gt;
&lt;td&gt;342,377&lt;/td&gt;
&lt;td&gt;4.9 (18,304)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Limescale &amp;amp; urine-stone remover, 500 ml&lt;/td&gt;
&lt;td&gt;₩3,000&lt;/td&gt;
&lt;td&gt;288,291&lt;/td&gt;
&lt;td&gt;4.7 (15,913)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;Egg capsule wash-off pack&lt;/td&gt;
&lt;td&gt;₩500&lt;/td&gt;
&lt;td&gt;276,379&lt;/td&gt;
&lt;td&gt;4.8 (6,926)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Boncep Vita C freeze-dried double-shot ampoule kit&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;₩5,000&lt;/td&gt;
&lt;td&gt;267,685&lt;/td&gt;
&lt;td&gt;4.8 (14,596)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;Celderma Daily azulene calming sheet mask&lt;/td&gt;
&lt;td&gt;₩2,000&lt;/td&gt;
&lt;td&gt;257,712&lt;/td&gt;
&lt;td&gt;4.8 (6,562)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;Puppy moist cushion puff&lt;/td&gt;
&lt;td&gt;₩1,000&lt;/td&gt;
&lt;td&gt;228,709&lt;/td&gt;
&lt;td&gt;4.8 (6,796)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;"Personal info eraser" (ink to hide your address on parcel labels), lavender&lt;/td&gt;
&lt;td&gt;₩1,000&lt;/td&gt;
&lt;td&gt;218,965&lt;/td&gt;
&lt;td&gt;4.8 (12,019)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;VT PDRN Glow toner, 200 ml&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;₩5,000&lt;/td&gt;
&lt;td&gt;212,668&lt;/td&gt;
&lt;td&gt;4.8 (13,854)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;13&lt;/td&gt;
&lt;td&gt;Baking-soda cleaning wipes, 100 sheets&lt;/td&gt;
&lt;td&gt;₩1,000&lt;/td&gt;
&lt;td&gt;204,761&lt;/td&gt;
&lt;td&gt;4.8 (10,611)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;td&gt;Madeca 21 Teca Solution soothing mist toner, 200 ml&lt;/td&gt;
&lt;td&gt;₩5,000&lt;/td&gt;
&lt;td&gt;201,463&lt;/td&gt;
&lt;td&gt;4.9 (15,615)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;td&gt;Air cushion puff, 2-pack&lt;/td&gt;
&lt;td&gt;₩1,000&lt;/td&gt;
&lt;td&gt;199,857&lt;/td&gt;
&lt;td&gt;4.8 (9,436)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;Puppy glow cushion water puff&lt;/td&gt;
&lt;td&gt;₩1,000&lt;/td&gt;
&lt;td&gt;174,653&lt;/td&gt;
&lt;td&gt;4.8 (5,372)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;17&lt;/td&gt;
&lt;td&gt;2-in-1 fruit fly trap set&lt;/td&gt;
&lt;td&gt;₩2,000&lt;/td&gt;
&lt;td&gt;166,858&lt;/td&gt;
&lt;td&gt;4.8 (9,520)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;18&lt;/td&gt;
&lt;td&gt;Pack Me In hydrogel V-line mask&lt;/td&gt;
&lt;td&gt;₩1,000&lt;/td&gt;
&lt;td&gt;157,695&lt;/td&gt;
&lt;td&gt;4.7 (5,190)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;19&lt;/td&gt;
&lt;td&gt;Bathroom cleaning sponges, 10-pack&lt;/td&gt;
&lt;td&gt;₩2,000&lt;/td&gt;
&lt;td&gt;153,081&lt;/td&gt;
&lt;td&gt;4.8 (7,839)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;Pull-out kitchen towels, 150 sheets (2nd listing)&lt;/td&gt;
&lt;td&gt;₩1,000&lt;/td&gt;
&lt;td&gt;150,732&lt;/td&gt;
&lt;td&gt;4.9 (4,520)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;21&lt;/td&gt;
&lt;td&gt;Rectangular storage box, 26×10×9 cm&lt;/td&gt;
&lt;td&gt;₩1,000&lt;/td&gt;
&lt;td&gt;150,133&lt;/td&gt;
&lt;td&gt;4.9 (4,813)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;22&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;VT Reedle Shot 100 first ampoule, 2 ml × 6&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;₩3,000&lt;/td&gt;
&lt;td&gt;149,840&lt;/td&gt;
&lt;td&gt;4.8 (16,760)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;23&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;VT Reedle Shot 300 first ampoule, 2 ml × 6&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;₩3,000&lt;/td&gt;
&lt;td&gt;142,578&lt;/td&gt;
&lt;td&gt;4.9 (16,154)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;24&lt;/td&gt;
&lt;td&gt;Foam-type "magic cleaner", 550 ml&lt;/td&gt;
&lt;td&gt;₩3,000&lt;/td&gt;
&lt;td&gt;140,933&lt;/td&gt;
&lt;td&gt;4.7 (5,442)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;25&lt;/td&gt;
&lt;td&gt;Fine-mist cosmetic spray bottle, 120 ml&lt;/td&gt;
&lt;td&gt;₩1,000&lt;/td&gt;
&lt;td&gt;137,129&lt;/td&gt;
&lt;td&gt;4.8 (9,696)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;26&lt;/td&gt;
&lt;td&gt;Boncep Retinol 2500 IU wrinkle-shot perfector, 15 ml&lt;/td&gt;
&lt;td&gt;₩5,000&lt;/td&gt;
&lt;td&gt;136,202&lt;/td&gt;
&lt;td&gt;4.8 (10,462)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;27&lt;/td&gt;
&lt;td&gt;Dong-A laundry stain stick&lt;/td&gt;
&lt;td&gt;₩1,500&lt;/td&gt;
&lt;td&gt;120,619&lt;/td&gt;
&lt;td&gt;4.7 (8,355)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;28&lt;/td&gt;
&lt;td&gt;The Lab by Blanc Doux hyaluronic glow booster ampoule, 30 ml&lt;/td&gt;
&lt;td&gt;₩5,000&lt;/td&gt;
&lt;td&gt;117,256&lt;/td&gt;
&lt;td&gt;4.8 (7,287)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;29&lt;/td&gt;
&lt;td&gt;Homestar 3X foam bleach cleaner (floral)&lt;/td&gt;
&lt;td&gt;₩3,000&lt;/td&gt;
&lt;td&gt;107,982&lt;/td&gt;
&lt;td&gt;4.9 (5,629)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;30&lt;/td&gt;
&lt;td&gt;Puppy fitting cushion puff&lt;/td&gt;
&lt;td&gt;₩1,000&lt;/td&gt;
&lt;td&gt;106,729&lt;/td&gt;
&lt;td&gt;4.8 (3,193)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;31&lt;/td&gt;
&lt;td&gt;VT PDRN Glow cream, 50 ml&lt;/td&gt;
&lt;td&gt;₩5,000&lt;/td&gt;
&lt;td&gt;104,014&lt;/td&gt;
&lt;td&gt;4.8 (5,514)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;32&lt;/td&gt;
&lt;td&gt;The Lab by Blanc Doux hyaluronic glow cream, 50 ml&lt;/td&gt;
&lt;td&gt;₩5,000&lt;/td&gt;
&lt;td&gt;101,822&lt;/td&gt;
&lt;td&gt;4.8 (6,992)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;33&lt;/td&gt;
&lt;td&gt;Medi-Peel Melanon X dark-spot cream, 30 ml&lt;/td&gt;
&lt;td&gt;₩5,000&lt;/td&gt;
&lt;td&gt;100,437&lt;/td&gt;
&lt;td&gt;4.7 (4,457)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;34&lt;/td&gt;
&lt;td&gt;Steambase daily eye warmer, cypress scent&lt;/td&gt;
&lt;td&gt;₩1,000&lt;/td&gt;
&lt;td&gt;98,611&lt;/td&gt;
&lt;td&gt;4.8 (3,022)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;35&lt;/td&gt;
&lt;td&gt;Portable lens cleaner wipes, 24-pack&lt;/td&gt;
&lt;td&gt;₩1,000&lt;/td&gt;
&lt;td&gt;96,052&lt;/td&gt;
&lt;td&gt;4.8 (6,259)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;36&lt;/td&gt;
&lt;td&gt;Vaseline intensive moisture sheet mask&lt;/td&gt;
&lt;td&gt;₩1,000&lt;/td&gt;
&lt;td&gt;95,926&lt;/td&gt;
&lt;td&gt;4.8 (3,631)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;37&lt;/td&gt;
&lt;td&gt;Induction-cooktop grease wipes, 60 sheets&lt;/td&gt;
&lt;td&gt;₩2,000&lt;/td&gt;
&lt;td&gt;95,671&lt;/td&gt;
&lt;td&gt;4.8 (5,327)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;38&lt;/td&gt;
&lt;td&gt;Madeca 21 Teca Solution soothing cream, 50 ml&lt;/td&gt;
&lt;td&gt;₩5,000&lt;/td&gt;
&lt;td&gt;93,664&lt;/td&gt;
&lt;td&gt;4.8 (8,528)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;39&lt;/td&gt;
&lt;td&gt;Glass &amp;amp; mirror cleaning wipes, 25 sheets&lt;/td&gt;
&lt;td&gt;₩1,000&lt;/td&gt;
&lt;td&gt;93,106&lt;/td&gt;
&lt;td&gt;4.6 (4,969)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;40&lt;/td&gt;
&lt;td&gt;Boncep retinol serum sheet mask&lt;/td&gt;
&lt;td&gt;₩1,000&lt;/td&gt;
&lt;td&gt;86,650&lt;/td&gt;
&lt;td&gt;4.8 (2,884)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;41&lt;/td&gt;
&lt;td&gt;Boncep Retinol 500 IU serum, 30 ml&lt;/td&gt;
&lt;td&gt;₩5,000&lt;/td&gt;
&lt;td&gt;86,072&lt;/td&gt;
&lt;td&gt;4.8 (7,323)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;42&lt;/td&gt;
&lt;td&gt;Celderma Daily collagen essence gel mask&lt;/td&gt;
&lt;td&gt;₩1,000&lt;/td&gt;
&lt;td&gt;85,652&lt;/td&gt;
&lt;td&gt;4.7 (2,326)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;43&lt;/td&gt;
&lt;td&gt;Real Barrier Cera Base calming moisturizing cream, 50 ml&lt;/td&gt;
&lt;td&gt;₩5,000&lt;/td&gt;
&lt;td&gt;85,421&lt;/td&gt;
&lt;td&gt;4.8 (6,397)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;44&lt;/td&gt;
&lt;td&gt;VT PDRN Glow lifting mask + essence&lt;/td&gt;
&lt;td&gt;₩2,000&lt;/td&gt;
&lt;td&gt;83,381&lt;/td&gt;
&lt;td&gt;4.8 (2,043)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;45&lt;/td&gt;
&lt;td&gt;Mini powder puff, 2-pack&lt;/td&gt;
&lt;td&gt;₩1,000&lt;/td&gt;
&lt;td&gt;81,183&lt;/td&gt;
&lt;td&gt;4.9 (5,539)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;46&lt;/td&gt;
&lt;td&gt;3-tier stacking drawer&lt;/td&gt;
&lt;td&gt;₩3,000&lt;/td&gt;
&lt;td&gt;79,704&lt;/td&gt;
&lt;td&gt;4.8 (4,721)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;47&lt;/td&gt;
&lt;td&gt;Pation Noscarnine first-step scar ampoule, 30 ml&lt;/td&gt;
&lt;td&gt;₩5,000&lt;/td&gt;
&lt;td&gt;79,630&lt;/td&gt;
&lt;td&gt;4.8 (4,628)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;48&lt;/td&gt;
&lt;td&gt;Potato capsule wash-off pack&lt;/td&gt;
&lt;td&gt;₩500&lt;/td&gt;
&lt;td&gt;78,964&lt;/td&gt;
&lt;td&gt;4.8 (3,052)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Five things the numbers say
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. VT is the brand that owns Daiso Korea.&lt;/strong&gt; The Reedle Shot ampoules (the ones that went viral on TikTok in 2024–25) sit at #22 and #23 with ~145k units &lt;em&gt;each&lt;/em&gt;, but VT's PDRN "Glow" line is now bigger: the PDRN sheet mask alone has sold 499k units at ₩1,000, and the PDRN toner, cream and lifting mask are all in the top 50. Six VT products in the top 48. If you're sourcing K-beauty, VT-at-Daiso is the story of the year.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. "Dermocosmetic actives at dollar-store prices" is the winning formula.&lt;/strong&gt; Freeze-dried vitamin C (Boncep, #8), retinol 2500 IU (#26) and 500 IU (#41), PDRN (VT), madecassoside (Madeca 21, #14/#38), noscarnine scar ampoule (#47), a dark-spot cream (#33). Koreans are buying &lt;em&gt;actives&lt;/em&gt;, not just sheet masks — at ₩3,000–5,000 ($2.20–3.70).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Sheet masks are still the volume engine.&lt;/strong&gt; Nine sheet/capsule masks in the top 48, all ₩500–2,000. The ₩500 egg capsule pack (#7) and potato capsule pack (#48) are Daiso originals that don't exist anywhere else.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Makeup sponges are a quiet monster.&lt;/strong&gt; Five cushion puffs in the top 48 (#10, #15, #16, #30, #45) — around 790k units combined. Nobody talks about them; everybody buys them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Cleaning products are the sleeper category.&lt;/strong&gt; A limescale remover with 288k units and 15,913 reviews (#6). Baking-soda wipes, induction wipes, glass wipes, a fruit-fly trap with 167k units. If you sell home goods, Korea's cleaning aisle is a product-development goldmine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Methodology
&lt;/h2&gt;

&lt;p&gt;Data was collected on 2026-09-07 from daisomall.co.kr search results for 15 category keywords (cosmetics, skincare, sheet masks, lip, sunscreen, cleansing, shampoo, storage, kitchen, cleaning, bathroom, stationery, pets, camping, snacks), 3,072 listings → 2,349 unique products. The &lt;code&gt;totalSold&lt;/code&gt; field is Daiso's own cumulative order count per listing. This is a category sample, not the full catalogue — there may be best-sellers in categories I didn't search.&lt;/p&gt;

&lt;p&gt;I collected it with a scraper I built and published on Apify (&lt;a href="https://apify.com/cocomoon/daiso-scraper" rel="noopener noreferrer"&gt;Daiso Korea Scraper&lt;/a&gt; — it returns price, rating, review count and units sold per product, and can also pull the reviews). If you want to run it yourself, I wrote a &lt;a href="https://dev.to/cocomoon/how-to-get-olive-young-and-daiso-korea-product-data-as-json-no-code-no-korean-ip-59nf"&gt;step-by-step walkthrough&lt;/a&gt; — no code needed. Happy to answer questions about the data or the method in the comments.&lt;/p&gt;

</description>
      <category>data</category>
      <category>webscraping</category>
      <category>ecommerce</category>
      <category>datascience</category>
    </item>
    <item>
      <title>How to get Olive Young and Daiso Korea product data as JSON — no code, no Korean IP</title>
      <dc:creator>MOON</dc:creator>
      <pubDate>Wed, 09 Sep 2026 08:28:58 +0000</pubDate>
      <link>https://dev.to/cocomoon/how-to-get-olive-young-and-daiso-korea-product-data-as-json-no-code-no-korean-ip-59nf</link>
      <guid>https://dev.to/cocomoon/how-to-get-olive-young-and-daiso-korea-product-data-as-json-no-code-no-korean-ip-59nf</guid>
      <description>&lt;p&gt;If you sell, source, or research K-beauty, the two Korean retailers you actually want data from are &lt;strong&gt;Olive Young&lt;/strong&gt; (Korea's #1 beauty retailer, ~1,300 stores) and &lt;strong&gt;Daiso Korea&lt;/strong&gt; (the ₩1,000 store where VT Reedle Shot went viral). Both have Korean-only websites, both block most scrapers, and neither has a public API.&lt;/p&gt;

&lt;p&gt;This is a 5-minute walkthrough for getting their data as clean JSON or CSV using three small scrapers I published on Apify. No coding required; there's an API/Python section at the end if you want to automate it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you can get
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Source&lt;/th&gt;
&lt;th&gt;What it returns&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Olive Young search&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Products for any keyword (Korean or English), ordered by Olive Young's popularity ranking: price, sale price, discount %, rating, review count, brand (Korean + English), category, sold-out / coupon / today's-special flags&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Olive Young reviews&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Reviews for any product: text, star rating, date, photos, verified repurchase flag, one-month-use flag, helpful votes, reviewer skin type / tone / concerns&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Daiso Korea&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Products for any keyword with price, rating, review count and &lt;strong&gt;cumulative units sold&lt;/strong&gt; — plus reviews with repurchase flag, attribute ratings and photos&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Step 1 — Create a free Apify account
&lt;/h2&gt;

&lt;p&gt;Go to &lt;a href="https://apify.com" rel="noopener noreferrer"&gt;apify.com&lt;/a&gt; and sign up (Google login works). The free plan includes $5 of platform credit every month, which is enough for a few thousand results — no card needed to try this.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2 — Open the Actor and enter a keyword
&lt;/h2&gt;

&lt;p&gt;Apify calls each scraper an "Actor". Open one of these:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://apify.com/cocomoon/oliveyoung-scraper" rel="noopener noreferrer"&gt;Oliveyoung Scraper — K-Beauty Search&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://apify.com/cocomoon/oliveyoung-review-scraper" rel="noopener noreferrer"&gt;Oliveyoung Review Scraper&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://apify.com/cocomoon/daiso-scraper" rel="noopener noreferrer"&gt;Daiso Korea Scraper — Real Units Sold + Reviews&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Click &lt;strong&gt;Try for free&lt;/strong&gt;. You'll land on an input form. For the Olive Young search scraper:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Keywords&lt;/strong&gt;: one per line. Korean gives the best results (&lt;code&gt;선크림&lt;/code&gt; = sunscreen, &lt;code&gt;토너&lt;/code&gt; = toner, &lt;code&gt;앰플&lt;/code&gt; = ampoule), but English brand names work too (&lt;code&gt;anua&lt;/code&gt;, &lt;code&gt;mediheal&lt;/code&gt;, &lt;code&gt;cosrx&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Max items&lt;/strong&gt;: how many products to collect in total. Start with 100.&lt;/li&gt;
&lt;li&gt;Leave proxy settings on the default.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Click &lt;strong&gt;Start&lt;/strong&gt;. A typical run takes 10–30 seconds.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3 — Look at the results and export
&lt;/h2&gt;

&lt;p&gt;When the run finishes, open the &lt;strong&gt;Output&lt;/strong&gt; tab. You'll see a table with an image, name, prices, rating and review count per product. Click &lt;strong&gt;Export&lt;/strong&gt; to download it as &lt;strong&gt;JSON, CSV, Excel, or XML&lt;/strong&gt;, or copy the dataset URL to load it directly into Google Sheets.&lt;/p&gt;

&lt;p&gt;A single Olive Young product row looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"keyword"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"선크림"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"position"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"totalResults"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;614&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"goodsNo"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"A000000232672"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"[미니어처 단독기획] 메디힐 마데카소사이드 수분 선세럼 흔적 리페어 50+50+15g 기획"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"brand"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"메디힐"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"brandEn"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mediheal"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"originalPrice"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;34900&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"salePrice"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;21200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"discountRate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;39&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"currency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"KRW"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rating"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;4.9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"reviewCount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;16595&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"isRepurchase"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"hasCoupon"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"isTodaySpecial"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"isSoldOut"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"categoryMid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"선케어"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://www.oliveyoung.co.kr/store/goods/getGoodsDetail.do?goodsNo=A000000232672"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4 — Get the reviews for a product
&lt;/h2&gt;

&lt;p&gt;Copy the &lt;code&gt;goodsNo&lt;/code&gt; value from the search results (e.g. &lt;code&gt;A000000232672&lt;/code&gt;) and paste it into the &lt;strong&gt;Products&lt;/strong&gt; field of the &lt;a href="https://apify.com/cocomoon/oliveyoung-review-scraper" rel="noopener noreferrer"&gt;Oliveyoung Review Scraper&lt;/a&gt;. You can paste product URLs instead of IDs.&lt;/p&gt;

&lt;p&gt;Useful options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sort by&lt;/strong&gt;: newest first (default), most helpful, highest / lowest rating.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Review type&lt;/strong&gt;: all, photo reviews only, one-month-use reviews, or repurchase reviews only.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Max reviews per product&lt;/strong&gt;: 100 by default; a hit product has 10,000+.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each review comes back with &lt;code&gt;rating&lt;/code&gt;, &lt;code&gt;text&lt;/code&gt;, &lt;code&gt;date&lt;/code&gt;, &lt;code&gt;isRepurchase&lt;/code&gt;, &lt;code&gt;isOneMonthUse&lt;/code&gt;, &lt;code&gt;images&lt;/code&gt;, &lt;code&gt;helpfulCount&lt;/code&gt;, and a &lt;code&gt;reviewer&lt;/code&gt; object with &lt;code&gt;skinType&lt;/code&gt;, &lt;code&gt;skinTone&lt;/code&gt; and &lt;code&gt;skinConcerns&lt;/code&gt; in English (Olive Young stores these as codes; the Actor translates them).&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5 — Daiso Korea: products with real sales volume
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://apify.com/cocomoon/daiso-scraper" rel="noopener noreferrer"&gt;Daiso Korea Scraper&lt;/a&gt; works the same way. Enter keywords (&lt;code&gt;화장품&lt;/code&gt; cosmetics, &lt;code&gt;마스크팩&lt;/code&gt; sheet mask, &lt;code&gt;주방&lt;/code&gt; kitchen, &lt;code&gt;수납&lt;/code&gt; storage…) and you get every matching product with a field most retailers never expose:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"[수분충전]VT PDRN 광채 시트 마스크 1매 25 g"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"price"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rating"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;4.9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"reviewCount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;7781&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"totalSold"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;499272&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"categorySmall"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"시트팩"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"isSoldOut"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;totalSold&lt;/code&gt; is Daiso's cumulative order count for the listing. Sort your export by that column and you have Daiso Korea's real best-seller list for any category.&lt;/p&gt;

&lt;p&gt;Switch the Actor's &lt;strong&gt;Mode&lt;/strong&gt; to &lt;em&gt;reviews&lt;/em&gt; and paste &lt;code&gt;productNo&lt;/code&gt; values to get review text, star rating, repurchase flag and Daiso's structured attribute ratings ("thickness: thicker than it looks", "durability: sturdy").&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6 — Schedule it (price / trend monitoring)
&lt;/h2&gt;

&lt;p&gt;On any finished run, click &lt;strong&gt;Save as a task&lt;/strong&gt;, then &lt;strong&gt;Schedule&lt;/strong&gt; the task (daily, weekly, cron). Each run writes a fresh dataset; you can push it to Google Sheets, S3, a webhook, or Slack from the &lt;strong&gt;Integrations&lt;/strong&gt; tab. That's a K-beauty price/rating monitor for a few cents a day.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optional — Run it from code
&lt;/h2&gt;

&lt;p&gt;Every Actor has a REST API. With the Apify Python client:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;apify_client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ApifyClient&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ApifyClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YOUR_APIFY_TOKEN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;actor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cocomoon/oliveyoung-scraper&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;run_input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;keywords&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;선크림&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;toner&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;maxItems&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;defaultDatasetId&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;iterate_items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;brandEn&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;salePrice&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rating&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;reviewCount&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or with curl:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"https://api.apify.com/v2/acts/cocomoon~oliveyoung-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"keywords": ["선크림"], "maxItems": 50}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Actors also work as tools for AI agents through Apify's MCP server, so Claude, Cursor or a custom agent can query Olive Young or Daiso directly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pricing and limits
&lt;/h2&gt;

&lt;p&gt;All three are pay-per-result: $3–4 per 1,000 results plus a fraction of a cent per run, with platform usage included. The $5 monthly free credit covers roughly 1,000+ results, so you can evaluate the data before paying anything.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Do I need a Korean IP?&lt;/strong&gt; No. The Actors handle proxies; the review scraper uses Korean residential proxies by default because Olive Young's review API blocks datacenter IPs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Korean or English keywords?&lt;/strong&gt; Both work on Olive Young. Korean returns more results; English works for brand names. Daiso is Korean-only.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is it legal?&lt;/strong&gt; The Actors read publicly listed product and review data — no login, no personal data (reviewer names on Daiso are masked by the platform; Olive Young exposes only nicknames). You're responsible for how you use the data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Something broke?&lt;/strong&gt; Open an issue on the Actor page — retailers change their sites and I maintain these.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I'm a marketer in Seoul who works with Korean retail data daily; I built these because every foreign brand and seller I talked to was copying Olive Young rankings by hand. If there's a Korean platform you need data from, tell me in the comments.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webscraping</category>
      <category>api</category>
      <category>tutorial</category>
      <category>data</category>
    </item>
  </channel>
</rss>
