Skip to content

Commit bacb0f7

Browse files
Ahad690claude
andcommitted
Keep seller_country as a market signal (regional pricing), no longer stripped
Country is coarse and not tied to any identifier, so it's kept while all seller-identifying fields stay stripped. Useful long-term for regional price analysis. - contribute.py: seller_country moved from FORBIDDEN to KEEP - scrape.py (kyurish + apify) and import_profile.py now capture seller_country - merge_kaggle canonical fields + benchmarks.sample.json backfilled (null) - DATA_POLICY.md updated: country kept, rationale documented; identifiers still dropped - tests assert country is kept/validated and captured (suite 69/69) Verified live: fresh scrape captured seller_country (PK) for the rag niche. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 60dccfe commit bacb0f7

8 files changed

Lines changed: 72 additions & 9 deletions

File tree

DATA_POLICY.md

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,15 @@ user account data, and it never scrapes by default.
88
When you use the live scrape (opt-in, your own key) or contribute data, only
99
**public listing metadata** is processed. The canonical record (PRD §7.1) is:
1010

11-
`scraped_at, category, subcategory, title, seller_level, rating, review_count,
12-
basic_price, standard_price, premium_price, basic_delivery_days,
13-
standard_delivery_days, premium_delivery_days, tags, gig_count_in_search,
14-
currency, original_currency`.
11+
`scraped_at, category, subcategory, title, seller_level, seller_country,
12+
rating, review_count, basic_price, standard_price, premium_price,
13+
basic_delivery_days, standard_delivery_days, premium_delivery_days, tags,
14+
gig_count_in_search, currency, original_currency`.
15+
16+
`seller_country` is a coarse market signal (a country code) kept for regional
17+
pricing analysis. It is *not* tied to a username, profile, or any other
18+
identifier — those are always stripped (below) — so a row cannot be traced back
19+
to a specific seller.
1520

1621
## What is kept vs stripped on contribution
1722

@@ -20,8 +25,8 @@ Contribution is **opt-in** and defaults to nothing. When you contribute,
2025
seller-identifying fields before anything leaves your machine:
2126

2227
**Dropped (hard requirement):** seller username, seller display name, profile
23-
URL, gig URL, profile photo URL, seller country, any free-text review content,
24-
any image URLs, any ID fields.
28+
URL, gig URL, seller profile URL, profile photo URL, any free-text review
29+
content, any image URLs, any ID fields.
2530

2631
A PII guard (`assert_no_pii`) runs before any upload and aborts if a non-keep
2732
field is present. Use `contribute.py --dry-run` to inspect the exact cleaned,

skills/fiverr-gig-optimizer/references/benchmarks.sample.json

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"subcategory": "AI Development > AI Chatbots",
66
"title": "I will build a custom AI chatbot for your website with openai",
77
"seller_level": "level_two_seller",
8+
"seller_country": null,
89
"rating": 4.9,
910
"review_count": 847,
1011
"basic_price": 75,
@@ -30,6 +31,7 @@
3031
"subcategory": "AI Development > AI Chatbots",
3132
"title": "I will create an ai chatbot using openai and langchain",
3233
"seller_level": "level_one_seller",
34+
"seller_country": null,
3335
"rating": 4.8,
3436
"review_count": 312,
3537
"basic_price": 60,
@@ -55,6 +57,7 @@
5557
"subcategory": "AI Development > AI Chatbots",
5658
"title": "I will develop ai chatbot and n8n automation workflows",
5759
"seller_level": "top_rated_seller",
60+
"seller_country": null,
5861
"rating": 5.0,
5962
"review_count": 1203,
6063
"basic_price": 120,
@@ -80,6 +83,7 @@
8083
"subcategory": "AI Development > AI Chatbots",
8184
"title": "I will make a whatsapp ai chatbot with openai gpt",
8285
"seller_level": "level_two_seller",
86+
"seller_country": null,
8387
"rating": 4.7,
8488
"review_count": 198,
8589
"basic_price": 90,
@@ -105,6 +109,7 @@
105109
"subcategory": "AI Development > AI Chatbots",
106110
"title": "I will build an ai customer support chatbot with automation",
107111
"seller_level": "level_one_seller",
112+
"seller_country": null,
108113
"rating": 4.6,
109114
"review_count": 87,
110115
"basic_price": 50,
@@ -130,6 +135,7 @@
130135
"subcategory": "AI Development > AI Chatbots",
131136
"title": "I will create a rag ai chatbot trained on your data",
132137
"seller_level": "level_two_seller",
138+
"seller_country": null,
133139
"rating": 4.9,
134140
"review_count": 534,
135141
"basic_price": 110,
@@ -155,6 +161,7 @@
155161
"subcategory": "Logo & Brand Identity > Logo Design",
156162
"title": "I will design a modern minimalist logo for your brand",
157163
"seller_level": "top_rated_seller",
164+
"seller_country": null,
158165
"rating": 5.0,
159166
"review_count": 2890,
160167
"basic_price": 25,
@@ -180,6 +187,7 @@
180187
"subcategory": "Logo & Brand Identity > Logo Design",
181188
"title": "I will create a professional logo design with source files",
182189
"seller_level": "level_two_seller",
190+
"seller_country": null,
183191
"rating": 4.8,
184192
"review_count": 1450,
185193
"basic_price": 20,
@@ -205,6 +213,7 @@
205213
"subcategory": "Logo & Brand Identity > Logo Design",
206214
"title": "I will do a hand drawn vintage logo design",
207215
"seller_level": "level_one_seller",
216+
"seller_country": null,
208217
"rating": 4.7,
209218
"review_count": 410,
210219
"basic_price": 35,
@@ -230,6 +239,7 @@
230239
"subcategory": "Search > SEO",
231240
"title": "I will do complete on page seo optimization for your website",
232241
"seller_level": "level_two_seller",
242+
"seller_country": null,
233243
"rating": 4.9,
234244
"review_count": 980,
235245
"basic_price": 45,
@@ -255,6 +265,7 @@
255265
"subcategory": "Search > SEO",
256266
"title": "I will be your seo expert for keyword research and strategy",
257267
"seller_level": "top_rated_seller",
268+
"seller_country": null,
258269
"rating": 5.0,
259270
"review_count": 1670,
260271
"basic_price": 60,
@@ -280,6 +291,7 @@
280291
"subcategory": "Search > SEO",
281292
"title": "I will write seo optimized blog articles and content",
282293
"seller_level": "level_one_seller",
294+
"seller_country": null,
283295
"rating": 4.6,
284296
"review_count": 220,
285297
"basic_price": 30,
@@ -305,6 +317,7 @@
305317
"subcategory": "Data Scraping",
306318
"title": "do web scraping and data scraping using python",
307319
"seller_level": "level_two_seller",
320+
"seller_country": null,
308321
"rating": 4.9,
309322
"review_count": 1547,
310323
"basic_price": 30.0,
@@ -330,6 +343,7 @@
330343
"subcategory": "Data Scraping",
331344
"title": "do python web scraping, data extraction and automation",
332345
"seller_level": "level_two_seller",
346+
"seller_country": null,
333347
"rating": 4.9,
334348
"review_count": 949,
335349
"basic_price": 30.0,
@@ -355,6 +369,7 @@
355369
"subcategory": "Data Scraping",
356370
"title": "do website scraping, data extraction, mining, collection, python web scraping",
357371
"seller_level": "level_two_seller",
372+
"seller_country": null,
358373
"rating": 4.8,
359374
"review_count": 82,
360375
"basic_price": 30.0,
@@ -380,6 +395,7 @@
380395
"subcategory": "Data Scraping",
381396
"title": "do web scraping, website scraping, web scraper in python",
382397
"seller_level": "level_two_seller",
398+
"seller_country": null,
383399
"rating": 4.8,
384400
"review_count": 1353,
385401
"basic_price": 30.0,
@@ -405,6 +421,7 @@
405421
"subcategory": "Data Scraping",
406422
"title": "do python web scraping, data scraping, and data mining",
407423
"seller_level": "top_rated_seller",
424+
"seller_country": null,
408425
"rating": 4.9,
409426
"review_count": 464,
410427
"basic_price": 100.0,
@@ -430,6 +447,7 @@
430447
"subcategory": "Data Scraping",
431448
"title": "provide professional web scraping services using python",
432449
"seller_level": "level_two_seller",
450+
"seller_country": null,
433451
"rating": 4.9,
434452
"review_count": 78,
435453
"basic_price": 100.0,
@@ -455,6 +473,7 @@
455473
"subcategory": "Data Scraping",
456474
"title": "do python web scraping, data scraping from any websites",
457475
"seller_level": "level_two_seller",
476+
"seller_country": null,
458477
"rating": 5.0,
459478
"review_count": 46,
460479
"basic_price": 30.0,
@@ -480,6 +499,7 @@
480499
"subcategory": "Data Processing",
481500
"title": "do web scraping data extraction automation using python",
482501
"seller_level": "level_two_seller",
502+
"seller_country": null,
483503
"rating": 4.9,
484504
"review_count": 108,
485505
"basic_price": 30.0,
@@ -505,6 +525,7 @@
505525
"subcategory": "Data Scraping",
506526
"title": "do web scraping and automation using python",
507527
"seller_level": "level_two_seller",
528+
"seller_country": null,
508529
"rating": 5.0,
509530
"review_count": 471,
510531
"basic_price": 100.0,
@@ -530,6 +551,7 @@
530551
"subcategory": "Data Scraping",
531552
"title": "do python web scraping, data scraping, and data mining",
532553
"seller_level": "level_two_seller",
554+
"seller_country": null,
533555
"rating": 4.9,
534556
"review_count": 29,
535557
"basic_price": 30.0,
@@ -555,6 +577,7 @@
555577
"subcategory": "Software Development",
556578
"title": "do web automation and web scraping using python",
557579
"seller_level": null,
580+
"seller_country": null,
558581
"rating": 5.0,
559582
"review_count": 4,
560583
"basic_price": 10.0,
@@ -580,6 +603,7 @@
580603
"subcategory": "Data Scraping",
581604
"title": "do python web scraping, data mining, and web automation",
582605
"seller_level": "top_rated_seller",
606+
"seller_country": null,
583607
"rating": 5.0,
584608
"review_count": 21,
585609
"basic_price": 30.0,
@@ -605,6 +629,7 @@
605629
"subcategory": "Data Scraping",
606630
"title": "do professional python web scraping and automation",
607631
"seller_level": "level_two_seller",
632+
"seller_country": null,
608633
"rating": 4.9,
609634
"review_count": 332,
610635
"basic_price": 30.0,
@@ -630,6 +655,7 @@
630655
"subcategory": "Data Scraping",
631656
"title": "conduct web scraping using python",
632657
"seller_level": "level_two_seller",
658+
"seller_country": null,
633659
"rating": 4.9,
634660
"review_count": 442,
635661
"basic_price": 100.0,
@@ -655,6 +681,7 @@
655681
"subcategory": "Data Scraping",
656682
"title": "do fast python web scraping, data extraction and automation",
657683
"seller_level": "level_two_seller",
684+
"seller_country": null,
658685
"rating": 5.0,
659686
"review_count": 45,
660687
"basic_price": 30.0,
@@ -680,6 +707,7 @@
680707
"subcategory": "Data Scraping",
681708
"title": "do python web scraping data scraping website scraping data mining",
682709
"seller_level": "level_one_seller",
710+
"seller_country": null,
683711
"rating": 5.0,
684712
"review_count": 38,
685713
"basic_price": 30.0,
@@ -705,6 +733,7 @@
705733
"subcategory": "Data Entry",
706734
"title": "web scraping, python, data scraping, web scraper",
707735
"seller_level": "level_two_seller",
736+
"seller_country": null,
708737
"rating": 5.0,
709738
"review_count": 11,
710739
"basic_price": 50.0,
@@ -730,6 +759,7 @@
730759
"subcategory": "Data Scraping",
731760
"title": "web scraping and crawling with python",
732761
"seller_level": "level_one_seller",
762+
"seller_country": null,
733763
"rating": 5.0,
734764
"review_count": 34,
735765
"basic_price": 30.0,
@@ -755,6 +785,7 @@
755785
"subcategory": "Data Processing",
756786
"title": "do python web scraping and web crawling for data extraction",
757787
"seller_level": "level_two_seller",
788+
"seller_country": null,
758789
"rating": 4.9,
759790
"review_count": 102,
760791
"basic_price": 10.0,
@@ -780,6 +811,7 @@
780811
"subcategory": "Data Scraping",
781812
"title": "do python web scraping and data mining",
782813
"seller_level": "top_rated_seller",
814+
"seller_country": null,
783815
"rating": 5.0,
784816
"review_count": 1162,
785817
"basic_price": 40.0,
@@ -803,6 +835,7 @@
803835
"subcategory": "Data Scraping",
804836
"title": "do data scraping, web crawling, and automation services in python",
805837
"seller_level": "level_one_seller",
838+
"seller_country": null,
806839
"rating": 4.8,
807840
"review_count": 2,
808841
"basic_price": 30.0,
@@ -827,6 +860,7 @@
827860
"subcategory": "Data Scraping",
828861
"title": "web scraping, python web scraper, data scraping from any website",
829862
"seller_level": "level_two_seller",
863+
"seller_country": null,
830864
"rating": 4.9,
831865
"review_count": 147,
832866
"basic_price": 30.0,
@@ -852,6 +886,7 @@
852886
"subcategory": "Data Scraping",
853887
"title": "do web scraping and automation python",
854888
"seller_level": "level_one_seller",
889+
"seller_country": null,
855890
"rating": 4.6,
856891
"review_count": 24,
857892
"basic_price": 30.0,
@@ -877,6 +912,7 @@
877912
"subcategory": "Software Development",
878913
"title": "do python web scraping, data scraping, data mining",
879914
"seller_level": "level_two_seller",
915+
"seller_country": null,
880916
"rating": 5.0,
881917
"review_count": 136,
882918
"basic_price": 25.0,
@@ -902,6 +938,7 @@
902938
"subcategory": "Data Scraping",
903939
"title": "do python web scraping, web automation, web crawling",
904940
"seller_level": "level_two_seller",
941+
"seller_country": null,
905942
"rating": 4.8,
906943
"review_count": 64,
907944
"basic_price": 30.0,

skills/fiverr-gig-optimizer/scripts/contribute.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,16 @@
2323
# §7.3 — the ONLY fields that may ever leave the user's machine.
2424
KEEP = [
2525
"scraped_at", "category", "subcategory", "title", "seller_level",
26-
"rating", "review_count", "basic_price", "standard_price", "premium_price",
26+
"seller_country", "rating", "review_count",
27+
"basic_price", "standard_price", "premium_price",
2728
"basic_delivery_days", "standard_delivery_days", "premium_delivery_days",
2829
"tags", "gig_count_in_search", "currency", "original_currency",
2930
]
3031
# §7.3 — must NEVER appear in output (asserted before any upload).
3132
FORBIDDEN = [
3233
"seller_username", "seller_name", "seller_display_name", "profile_url",
3334
"gig_url", "seller_url", "profile_photo_url", "freelancers_link",
34-
"seller_country", "review_text", "reviews", "image_url", "image_urls",
35+
"review_text", "reviews", "image_url", "image_urls",
3536
"id", "gig_id", "seller_id",
3637
]
3738

skills/fiverr-gig-optimizer/scripts/import_profile.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ def map_existing_gig(detail, fx):
6565
"category": detail.get("category"),
6666
"subcategory": detail.get("sub_category"),
6767
"seller_level": (detail.get("seller") or {}).get("level"),
68+
"seller_country": (detail.get("seller") or {}).get("country"),
6869
"rating": detail.get("rating"),
6970
"review_count": detail.get("reviews_count"),
7071
"tags": [t.lower() for t in (detail.get("tags") or []) if t],

skills/fiverr-gig-optimizer/scripts/scrape.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ def map_kyurish(search_item, detail, total_results, category_override, fx, today
120120
"subcategory": detail.get("sub_category"),
121121
"title": detail.get("title") or search_item.get("title"),
122122
"seller_level": seller.get("level") or search_item.get("seller_level") or None,
123+
"seller_country": seller.get("country") or None,
123124
"rating": detail.get("rating") if detail.get("rating") else search_item.get("rating"),
124125
"review_count": detail.get("reviews_count")
125126
if detail.get("reviews_count") is not None else search_item.get("reviews_count"),
@@ -163,6 +164,7 @@ def map_apify(item, total_results, category_override, fx, today):
163164
"subcategory": item.get("subCategoryId") or item.get("subcategory"),
164165
"title": item.get("title"),
165166
"seller_level": item.get("sellerLevel") or item.get("seller_level"),
167+
"seller_country": item.get("sellerCountry") or item.get("seller_country"),
166168
"rating": item.get("sellerRating") or item.get("rating"),
167169
"review_count": item.get("sellerReviewCount") or item.get("review_count"),
168170
**tiers,

skills/fiverr-gig-optimizer/scripts/seed/merge_kaggle.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727

2828
CANONICAL_FIELDS = [
2929
"scraped_at", "category", "subcategory", "title", "seller_level",
30-
"rating", "review_count", "basic_price", "standard_price", "premium_price",
30+
"seller_country", "rating", "review_count",
31+
"basic_price", "standard_price", "premium_price",
3132
"basic_delivery_days", "standard_delivery_days", "premium_delivery_days",
3233
"tags", "gig_count_in_search", "currency", "original_currency",
3334
]

0 commit comments

Comments
 (0)