Newsletter
TechAnV Blog
Get updates on security engineering, Rust, eBPF, and DevSecOps. No spam, unsubscribe anytime.
Check your inbox and click the confirmation link to complete your subscription.
Scraping Reddit via their JSON API#
Reddit have long had an unofficial (I think) API where you can add .json to the end of any URL to get back the data for that page as JSON.
I wanted to track new posts on Reddit that mention my domain simonwillison.net.
https://www.reddit.com/domain/simonwillison.net/new/ shows recent posts from a specific domain.
https://www.reddit.com/domain/simonwillison.net/new.json is that data as JSON, which looks like this:
1{2 "kind": "Listing",3 "data": {4 "modhash": "la6xmexs8u301d6d105d24f94cdaa4457a00a1ea042c95f6e2",5 "dist": 25,6 "children": [7 {8 "kind": "t3",9 "data": {10 "approved_at_utc": null,11 "subreddit": "programming",12 "selftext": "",13 "author_fullname": "t2_2ks9",14 "saved": false,15 "mod_reason_title": null,16 "gilded": 0,17 "clicked": false,18 "title": "Joining CSV and JSON data with an in-memory SQLite database",19 "link_flair_richtext": [],20 "subreddit_name_prefixed": "r/programming"Attempting to fetch this data with curl shows an error:
1$ curl 'https://www.reddit.com/domain/simonwillison.net/new.json'2{"message": "Too Many Requests", "error": 429}Turns out this rate limiting is based on user-agent - so to avoid it, set a custom user-agent:
1$ curl --user-agent 'simonw/fetch-reddit' 'https://www.reddit.com/domain/simonwillison.net/new.json'2{"kind": "Listing", "data": ...I used jq to tidy this up like so:
1[.data.children[] | .data | {2 id: .id,3 subreddit: .subreddit,4 url: .url,5 created_utc: .created_utc | todate,6 permalink: .permalink,7 num_comments: .num_comments8}]Combined:
1$ curl \2 --user-agent 'simonw/fetch-reddit' \3 'https://www.reddit.com/domain/simonwillison.net/new.json' \4 | jq '[.data.children[] | .data | {5 id: .id,6 subreddit: .subreddit,7 url: .url,8 created_utc: .created_utc | todate,9 permalink: .permalink,10 num_comments: .num_comments11 }]' > simonwillison-net.jsonOutput looks like this:
1[2 {3 "id": "o3tjsx",4 "subreddit": "programming",5 "url": "https://simonwillison.net/2021/Jun/19/sqlite-utils-memory/",6 "created_utc": "2021-06-20T00:25:51Z",7 "permalink": "/r/programming/comments/o3tjsx/joining_csv_and_json_data_with_an_inmemory_sqlite/",8 "num_comments": 109 },10 {11 "id": "nnsww6",12 "subreddit": "patient_hackernews",13 "url": "https://til.simonwillison.net/bash/finding-bom-csv-files-with-ripgrep",14 "created_utc": "2021-05-29T18:04:38Z",15 "permalink": "/r/patient_hackernews/comments/nnsww6/finding_csv_files_that_start_with_a_bom_using/",16 "num_comments": 117 }18]