Repository navigation
Expand file tree
/
Copy pathexample.py
More file actions
67 lines (54 loc) · 2.75 KB
/
Copy pathexample.py
File metadata and controls
67 lines (54 loc) · 2.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
"""Amazon keyword research with the Amazon Search Scraper on Apify.
For each keyword: how many sponsored slots sit above the first organic result,
the median price / rating of the organic top 20, and the products with real
demand ("bought in past month") but weak review counts, i.e. open niches.
Usage:
pip install -r requirements.txt
set APIFY_TOKEN=<YOUR_APIFY_TOKEN> (export on macOS/Linux)
python example.py "standing desk" "desk lamp"
"""
import csv
import os
import statistics
import sys
from apify_client import ApifyClient
ACTOR_ID = "rel8ble/amazon-search-scraper"
DOMAIN = "amazon.com"
TOP_N = 20
token = os.environ.get("APIFY_TOKEN", "<YOUR_APIFY_TOKEN>")
keywords = sys.argv[1:] or ["standing desk", "desk lamp"]
client = ApifyClient(token)
run = client.actor(ACTOR_ID).call(run_input={
"keywords": keywords,
"domain": DOMAIN,
"maxItemsPerSearch": 60,
"includeSponsored": True,
})
items = list(client.dataset(run["defaultDatasetId"]).iterate_items())
print(f"{len(items)} products for {len(keywords)} keyword(s)")
fields = ["keyword", "position", "organicPosition", "isSponsored", "asin", "title",
"price", "listPrice", "currency", "rating", "ratingsCount",
"boughtLastMonth", "isBestSeller", "isAmazonChoice", "url"]
with open("amazon_search.csv", "w", newline="", encoding="utf-8") as f:
w = csv.DictWriter(f, fieldnames=fields, extrasaction="ignore")
w.writeheader()
w.writerows(items)
print("Wrote amazon_search.csv")
def median(values):
values = [v for v in values if isinstance(v, (int, float))]
return round(statistics.median(values), 2) if values else None
for kw in keywords:
rows = sorted((i for i in items if i.get("keyword") == kw), key=lambda i: i["position"])
organic = [i for i in rows if not i.get("isSponsored")][:TOP_N]
first_organic = next((i["position"] for i in rows if not i.get("isSponsored")), None)
ads_above = sum(1 for i in rows if i.get("isSponsored") and first_organic and i["position"] < first_organic)
print(f"\n== {kw} ==")
print(f"sponsored slots above first organic result: {ads_above}")
print(f"organic top {len(organic)}: median price {median(i.get('price') for i in organic)}, "
f"median rating {median(i.get('rating') for i in organic)}, "
f"median ratings count {median(i.get('ratingsCount') for i in organic)}")
# Selling well, few reviews yet: room for a newcomer.
gaps = [i for i in rows if (i.get("boughtLastMonth") or 0) >= 1000 and (i.get("ratingsCount") or 0) < 500]
for i in sorted(gaps, key=lambda i: -(i.get("boughtLastMonth") or 0))[:5]:
print(f" open niche: {i.get('boughtLastMonthText')} | {i.get('ratingsCount')} ratings | "
f"{i.get('price')} {i.get('currency')} | {i['title'][:70]}")