#!/usr/bin/env python3 """Daily Wikipedia pageviews for a list of articles, as CSV. Uses the public Wikimedia Pageviews REST API (no API key). Standard library only. python3 wikipageviews.py --start 20260901 --end 20260930 "Python_(programming_language)" "Rust_(programming_language)" """ import argparse, csv, json, sys, time, urllib.error, urllib.parse, urllib.request UA = "wikipageviews-script/0.1 (static download; contact via the page it came from)" ROOT = "https://wikimedia.org/api/rest_v1/metrics/pageviews/per-article" def views(article, project="en.wikipedia", granularity="daily", start="20260901", end="20260930", access="all-access", agent="user"): enc = urllib.parse.quote(article.replace(" ", "_"), safe="") url = f"{ROOT}/{project}/{access}/{agent}/{enc}/{granularity}/{start}/{end}" req = urllib.request.Request(url, headers={"User-Agent": UA}) try: with urllib.request.urlopen(req, timeout=30) as r: data = json.load(r) except urllib.error.HTTPError as e: if e.code == 404: return [] raise return [(i["timestamp"][:8], i["views"]) for i in data["items"]] def main(): p = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) p.add_argument("articles", nargs="*", default=["Python_(programming_language)"]) p.add_argument("--project", default="en.wikipedia") p.add_argument("--start", default="20260901") p.add_argument("--end", default="20260930") p.add_argument("--granularity", default="daily", choices=["daily", "monthly"]) a = p.parse_args() w = csv.writer(sys.stdout) w.writerow(["article", "date", "views"]) for art in a.articles: for date, n in views(art, a.project, a.granularity, a.start, a.end): w.writerow([art, date, n]) time.sleep(0.2) if __name__ == "__main__": main()