Stack Overflow Scraper - Questions, Tags & Scores avatar

Stack Overflow Scraper - Questions, Tags & Scores

Pricing

from $1.94 / 1,000 questions

Go to Apify Store
Stack Overflow Scraper - Questions, Tags & Scores

Stack Overflow Scraper - Questions, Tags & Scores

Search Stack Overflow and five more Stack Exchange sites by keyword or tag. Each question has the score, answers, views, tags, asker and reputation, and the body as plain text, with the accepted answer on request. Two tags means both. $2.00 per 1,000 questions.

Pricing

from $1.94 / 1,000 questions

Rating

0.0

(0)

Developer

Dami's Studio

Dami's Studio

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

1

Monthly active users

3 days ago

Last modified

Share

Scrape Stack Overflow questions by keyword or tag: search Stack Overflow and five sibling Stack Exchange sites, and each row is one question with the title, the score, the answer count, the view count, its tag list, who asked it and their reputation, and the whole question body as plain text.

Questions first. Turn on includeAcceptedAnswer and each row also carries the accepted answer as plain text. The other answers and the comments are not in the output, so if you need whole threads, this is the wrong purchase however cheap it is.

InputKeywords, tags, or both
OutputOne row per question: title, score, answers, views, tags, asker and reputation, the body as plain text. The accepted answer on request
Ceiling1,000 questions per run
Account neededNone, and no Stack Exchange key
Price$2.00 per 1,000 questions on the Free plan, a little less on paid plans. The free plan's $5 a month covers about 2,500

🔍 What Stack Overflow Scraper does

It runs one search and pages through it until it has as many questions as you asked for.

query matches words in titles and bodies. tags filters, and it is an AND: put javascript,promise and you get only questions carrying both, not either. You can use tags on their own with no keywords, which is the cleanest way to pull the top questions in a tag.

sortBy decides the order, and it changes what a small run gives you. votes returns the long-standing classics. creation returns what was asked most recently. activity returns what people are still arguing about. relevance leans on the keyword match. On votes you can also set minScore to keep only questions at or above a score.

Six sites are available: Stack Overflow, Server Fault, Super User, Ask Ubuntu, MathOverflow and Software Engineering. One site per run.

With includeAcceptedAnswer on, each question also carries the answer its asker accepted: score, author and the body as plain text. Many questions never get one, and those say so with null.

📋 What data you get from each Stack Overflow question

What you getField
The question's id, title and linkquestionId, title, url
Score, answer count and viewsscore, answerCount, viewCount
Whether Stack Exchange counts it as answeredisAnswered
Every tag on the questiontags
Who asked it, and their reputationownerName, ownerReputation
When it was askedcreatedAt
The question body as plain textbody
The accepted answer, when you ask for itacceptedAnswerId, acceptedAnswer

▶️ How to scrape Stack Overflow questions

  1. Open Stack Overflow Scraper and click Try for free.
  2. Type into Search query, or fill Tags instead, or both.
  3. Pick a Stack Exchange site if you want one of the other five.
  4. Choose a Sort by order and set Max questions, then click Start.
  5. Download the dataset as JSON, CSV, Excel or XML.

💰 How much does it cost to scrape Stack Overflow questions?

$2.00 per 1,000 questions on the Free plan. Paid plans pay a little less: $1.98 on Starter, $1.96 on Scale and $1.94 on Business. On the free plan, the $5 Apify gives you each month covers about 2,500 questions.

You pay per question row. Duplicates removed inside a run and every diagnostic row are not charged, and a search that matches nothing does not bill for results. Questions below minScore are never fetched, so they cost nothing either. The accepted answer adds nothing to the price.

📥 What you give it

{
"query": "async await",
"tags": "javascript,promise",
"site": "stackoverflow",
"sortBy": "votes",
"maxItems": 50
}
FieldDefaultWhat it is
querynoneKeywords matched against titles and bodies. The Console shows async await as an example, but that is a prefill, so an API call has to send its own.
tagsnoneComma separated, and every tag must be present on the question. The Console prefills javascript, which again does not travel to an API call.
sitestackoverflowOne of stackoverflow, serverfault, superuser, askubuntu, mathoverflow, softwareengineering.
sortByvotesvotes, relevance, creation or activity. Always highest or newest first.
minScorenoneOnly questions with at least this score. Stack Exchange applies it, so lower-scored questions are never fetched or billed. Works with sortBy set to votes only; with another order the run refuses it, because the site would read the number as a date.
includeAcceptedAnswerfalseAdds each question's accepted answer to its row, at the same price per question. Works with every site and sort.
maxItems501 to 1,000. Paging is automatic, a hundred at a time.
notionConnectornoneOptional. Writes every delivered question into your Notion. Authorise a connector once under Settings, API and Integrations, MCP connectors, then pick it here.
notionParentIdnoneOptional. The Notion data source id to write into. Leave it empty and the pages are created privately in your workspace.
proxyConfigurationoffOptional network setting. Off is right for a normal run.

Send a query, tags, or both. Leaving both empty is not refused, and what comes back then is whatever the site decides to hand over, charged like any other rows. It is the one input mistake here that costs money.

📤 What you get back

A real row from a recent run, with the body cut short here for length:

{
"ok": true,
"questionId": 37576685,
"title": "Using async/await with a forEach loop",
"url": "https://stackoverflow.com/questions/37576685/using-async-await-with-a-foreach-loop",
"score": 3353,
"answerCount": 35,
"viewCount": 2481345,
"isAnswered": true,
"tags": ["javascript", "node.js", "promise", "async-await", "ecmascript-2017"],
"ownerName": "Saad",
"ownerReputation": 55029,
"createdAt": "2016-06-01T18:55:58.000Z",
"body": "Are there any issues with using async/await in a forEach loop? I'm trying to loop through an array of files and await on the contents of each file. ..."
}
FieldHow to read it
bodyThe question, converted from HTML to plain text. Code blocks survive as text, indentation mostly does not.
isAnsweredStack Exchange's own flag: true when an answer was accepted or has a positive score, so it can be true with no accepted answer. Not the same as answerCount being above zero.
acceptedAnswerIdOnly with includeAcceptedAnswer. The accepted answer's id, or null when the question has none.
acceptedAnswerOnly with includeAcceptedAnswer. {answerId, score, ownerName, ownerReputation, createdAt, body}, with body as plain text. null when there is no accepted answer, or when it could not be read in this run (then acceptedAnswerId is still set).
ownerName, ownerReputationBoth null when the account was deleted or the post is anonymous.
scoreNet votes, which can be negative.
titlePassed through as Stack Exchange sends it, so an HTML entity like " can survive into this field. Only body is decoded.
tagsThe question's full tag list, which is usually wider than the tags you filtered on.

🧾 Reading the output

Questions carry ok: true. Anything with ok: false carries an errorCode and is not charged.

CodeWhat it means
NO_RESULTSThe search ran and matched nothing. Usually a tag that does not exist, or two tags no single question carries.
BAD_INPUTminScore was set with a sortBy other than votes. Nothing was searched; the row's note says what to change.
RATE_LIMITEDStack Exchange asked the run to stop for the day. Whatever was already collected is in the dataset and complete as far as it goes.
NOT_SERVEDStack Exchange did not serve the search on this run. Re-run it later. Until 12 October 2026 this code was called BLOCKED.
NETWORKStack Exchange was unreachable or answered with something unusable. Re-run it.
TIME_LIMITThe run got close to its time limit and stopped on its own. The questions delivered before that are complete and charged. Give the run more time, or ask for fewer questions, to get the rest.

A run that ends on one of these rows still finishes as succeeded, except one: when the time limit stopped the run before any question came back, it ends as failed, with a TIME_LIMIT row saying so.

A RATE_LIMITED row after some questions is not a failed run. It means the run delivered what it could and stopped rather than spinning. The same goes for an acceptedAnswerId with an empty acceptedAnswer: that answer could not be read in this run, usually because the day's allowance ran out. The run log says how many were read.

The Console's Overview table hides tags, isAnswered and body. Download the dataset as JSON, CSV or Excel, or switch the table to all fields.

💡 What people use it for

  • Finding the questions a product's documentation should have answered, by searching its name and reading what people are stuck on.
  • Comparing tag volume between two libraries before committing to one.
  • Watching a tag weekly with sortBy on creation to see what problems are new.

🚧 What it does not do

  • The accepted answer only, and only when you ask for it. Other answers and comments are not read. answerCount tells you how many answers there are.
  • One site per run. Searching Stack Overflow and Ask Ubuntu together means two runs.
  • No date range input. Sort by creation and filter on createdAt afterwards.
  • Only six of the network's sites, the ones in the list above.
  • Tags are AND, never OR. Three tags usually returns far less than you expect.
  • There is a daily ceiling on how much anyone can pull without a key. When it is reached the run stops and says so instead of failing. Accepted answers count against it too, about one extra read per hundred questions.
  • Rows are a snapshot. Scores, views and answer counts move.
  • It is not an official Stack Overflow or Stack Exchange tool. Dami's Studio is independent and is not affiliated with or endorsed by Stack Overflow or Stack Exchange, or by any other company named on this page.

🧭 Which developer scraper do you need?

If you wantUse
Articles from DEV.to by tag or author, with the full text on requestDEV.to Scraper
Hacker News stories, Ask and Show HN posts, and commentsHacker News Scraper
Stack Overflow questions with the body and the accepted answerThis one
Repositories and developer profiles from a GitHub searchGitHub Scraper
npm and PyPI package details and download countsnpm + PyPI Package Scraper
Product launches and their upvotesProduct Hunt Scraper

❓ Questions people ask

Do I need a Stack Exchange API key?

No. Nothing to register for.

Can I search Stack Overflow tags without keywords?

Yes, and it is the better way to pull a tag's top questions. Leave the query empty and fill tags.

Why did two tags return almost nothing?

Because both have to be on the same question. Drop one.

Can I get the answers to each question?

The accepted one, yes: turn on includeAcceptedAnswer. The others are not read, so take url from the row and open the question.

Why does a title contain "?

The title is passed through as Stack Exchange sends it. Decode it on your side, or use body, which is already plain text.

Can I call it from code or connect it to an AI assistant?

Yes. The API tab has ready-made code for Python, JavaScript and the command line. For Claude, ChatGPT or another MCP client, connect https://mcp.apify.com/?tools=fetch-actor-details,dami_studio/stackexchange-scraper. Either way the run happens on your Apify account at the same price.

Check Stack Exchange's licence terms before you republish anything. Asker names are personal data under GDPR and similar laws, so have a reason for keeping them. Apify's write-up on the legality of web scraping is a good starting point, and we are not lawyers.

🆘 If something breaks

Open the Issues tab on the actor page. Send the query, the tags and the run id. The errorCode on the diagnostic row usually names the problem by itself.