How to scrape software and SaaS data from GitHub using the Minexa API
- Minexa.ai
- Jul 7
- 4 min read
GitHub Explore surfaces what the developer community is actually building right now. Trending repositories, active topics, star counts, programming languages, and full card-level metadata are all sitting on a single public page. The challenge is getting that data into a structured format you can query, filter, and feed into a pipeline.
This guide walks through how to extract that data programmatically using the Minexa API. The workflow has two phases: train a scraper once using the Minexa Chrome extension, then call the API to pull structured data at scale across any number of GitHub Explore URLs.
Why GitHub Explore data matters for SaaS and software research
If you are tracking which open-source tools are gaining traction, monitoring competitor repositories, or building a dataset of trending SaaS-adjacent projects, GitHub Explore gives you a real-time signal. Star velocity, topic tags, and language distribution across trending repos tell you where developer attention is moving before it shows up anywhere else.
Collecting this manually is slow. The Minexa API makes it repeatable and structured.
Phase 1: train the scraper using the Chrome extension
Start by installing the Minexa Chrome extension and navigating to github.com/explore.
Open the extension. It will detect the page automatically. Click 'I'm on the right page' to confirm you are ready to proceed with the setup.
The extension will show you the pagination options it detected for the page. Review the result and click 'Continue'. Note that when using the API, pagination is not handled automatically. You will need to write a JS code scenario that defines what needs to be clicked to move between pages.
Next, choose whether to scrape just the list or the list plus linked detail pages. For GitHub Explore, the list itself contains rich card-level data, so scraping the list alone is a reasonable starting point.
Select your scraping mode. Simple mode works well for GitHub Explore since the card structure is consistent across all trending repository entries.
The extension highlights the full data container on the page automatically. Confirm the selection and create the scraper.
Once the scraper is created, you will see all extracted data points with navigation to review each column. This is where you confirm the fields look correct before moving to the API phase.
Click 'API request' to view the generated code samples in JSON and Python. This screen also shows the scraper ID you will use in every subsequent API call.
Phase 2: call the Minexa API to extract at scale
Once your scraper is trained, the scraper ID becomes the stable key for all API calls. Here is a ready-to-run Python example using a realistic scraper ID:
import requests
url = "https://api.minexa.ai/data"
headers = {
"Content-Type": "application/json",
"x-api-key": "YOUR_API_KEY"
}
payload = {
"scraper_id": 6284,
"urls": ["https://github.com/explore"],
"columns": "top_40"
}
response = requests.post(url, json=payload, headers=headers)
print(response.json())
Pass multiple URLs in a single request to extract data across several GitHub Explore variants or topic-filtered pages at once. The columns parameter accepts either a top-N value or a list of named fields if you want to target specific outputs.
What the extracted data looks like
Here is a sample of what the API returns for two repository cards from GitHub Explore:
[
{
"repository_details": [
{ "value": "Trending repository", "tag": "span", "type": "text" },
{ "value": "simplex-chat", "tag": "a", "type": "text" },
{ "value": "/simplex-chat/simplex-chat", "tag": "a", "attribute": "href", "type": "attribute" },
{ "value": "Star", "tag": "span", "type": "text" },
{ "value": "16.8k", "tag": "span", "type": "text" },
{ "value": "Haskell", "tag": "span", "type": "text" },
{ "value": "Jun 29, 2026", "tag": "relative-time", "type": "text" }
],
"event_payload": [
{ "value": "{\"event_type\":\"explore.click\",\"payload\":{\"click_context\":\"REPOSITORY_CARD\",\"record_id\":59927747}}", "tag": "a", "attribute": "data-hydro-click" }
]
},
{
"repository_details": [
{ "value": "Trending repository", "tag": "span", "type": "text" },
{ "value": "agency-agents", "tag": "a", "type": "text" },
{ "value": "/msitarzewski/agency-agents", "tag": "a", "attribute": "href", "type": "attribute" },
{ "value": "Star", "tag": "span", "type": "text" },
{ "value": "119k", "tag": "span", "type": "text" },
{ "value": "Shell", "tag": "span", "type": "text" },
{ "value": "Jun 29, 2026", "tag": "relative-time", "type": "text" }
]
}
]
The repository_details field is a traversable array that encodes all card-level metadata in a single nested object per repository. From one field you can pull the repo name, owner path, href, star count, primary language, last update timestamp, and description text.
The event_payload field contains a JSON string per card encoding the click context, click target, visual representation type, internal record ID, and originating URL. The record ID is GitHub's internal identifier for each repository, which is stable across sessions and useful for deduplication when running the scraper on multiple dates.
The hash_value fields surface per-link HMAC signatures that GitHub attaches to each anchor element for internal click validation. These are not useful for most downstream applications but are captured automatically as part of the full card structure.
The authentication_data field captures the login redirect path that GitHub injects into star button links for unauthenticated users. This path encodes the repository slug and can be parsed to confirm which repository each star interaction belongs to.
Export options include Excel and JSON. If you are building a recurring pipeline, set up your own cron job and pass updated URLs to the API on whatever schedule fits your monitoring cadence.
To get started, visit the Minexa API documentation or install the Minexa Chrome extension to train your first scraper.
For more on how the API handles extraction requests internally, see: What actually happens inside a Minexa API extraction request.
