# Quora Search Scraper (`scraper-engine/quora-search-scraper`) Actor

🔍 Quora Search Scraper extracts targeted search results & post data from Quora for faster insights. 📈 Perfect for market research, lead gen, and content analysis—save time with automated crawling and clean outputs. 🚀

- **URL**: https://apify.com/scraper-engine/quora-search-scraper.md
- **Developed by:** [Scraper Engine](https://apify.com/scraper-engine) (community)
- **Categories:** Lead generation, SEO tools, Automation
- **Stats:** 2 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.99 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

### Quora Search Scraper — Questions, Answers, Upvotes and Authors

Quora Search Scraper turns a keyword or a Quora URL into structured JSON rows: question title, full answer text, author name and credentials, upvotes, comment and share counts, follower counts and absolute answer dates. It covers five content types — questions, answers, profiles, topics and spaces — and needs no Quora account, login or cookie. Rows stream into the dataset live as each page is parsed. Paste a keyword, set a row limit, press Start.

⚠️ **No input is marked required, and that cuts both ways.** `searchQueries` ships prefilled with `["python programming"]`, so pressing **Start** in the Console without editing anything runs that keyword and charges you for the rows it collects. An input that carries neither `searchQueries` nor `directUrls` does **not** fall back to a hidden query — the run logs `No searchQueries and no directUrls/urls provided — nothing to do.` and exits immediately with zero rows and no charge.

### What is Quora Search Scraper?

Quora Search Scraper is an Apify Actor that reads public Quora pages with a stealth Chromium browser, pulls the GraphQL payloads Quora embeds in them, and flattens each result into a typed dataset row tagged with a `content_type` of `question`, `answer`, `profile`, `topic` or `space`.

No Quora account, login or cookie is required. The Actor never authenticates — it reads exactly what a logged-out visitor's page contains.

It is built for content and SEO researchers mining question intent, market researchers reading how real people describe a problem, and developers piping Q\&A text into dashboards or AI pipelines.

### What Quora question and answer data is publicly available to scrape?

A logged-out Quora question page carries the question title, its topic tags, its answer and follower counts, and the full text of its answers along with each author's display name, profile link, credential line and engagement metrics. Profile, topic and space pages are thinner when read anonymously, and this Actor deliberately does not emit the columns Quora leaves empty there.

| Data Category | Returned by this Actor | Gated or not extracted |
| ----- | ----- | ----- |
| Question title, URL, topic tags, answer and follower counts | ✅ Public | — |
| Full answer text, author name, profile link, credential line | ✅ Public | — |
| Answer upvotes, comment count, share count, creation time | ✅ Public | — |
| Profile name, bio, credentials, followers, following, answers, questions, total views | ✅ Public | — |
| Topic name, topic URL, topic followers | ✅ Public | Topic description and question count are not in the logged-out payload — not emitted |
| Space name, description, followers, contributors | ✅ Public | Space post count is not in the logged-out payload — not emitted |
| Comment text under an answer | ❌ | Only the count (`comments_count`) is returned, never the comment bodies |
| Upvoter identities, topic follower lists, answer view counts | ❌ | Not returned |
| Quora's own on-site search results page | ❌ | Not used — question URLs are discovered through DuckDuckGo and Bing instead |
| Anything behind a Quora login or a paid Quora subscription | ❌ | Never returned — the Actor holds no session |

Quora Search Scraper only returns publicly visible data — what any visitor sees. Nothing behind a login wall.

### What data can I extract with Quora Search Scraper?

Every row carries `content_type`, `title`, `url`, `source_url` and `scrape_timestamp`. Everything else depends on which of the five content types the row is, so the dataset is intentionally sparse — branch on `content_type` before you read anything else. Across all five row builders the Actor writes 33 distinct keys.

| Field Name | Description |
| ----- | ----- |
| `content_type` | Row type: `question`, `answer`, `profile`, `topic` or `space`. On every row |
| `title` | Question title on `question` and `answer` rows; person, topic or space name on the other three. On every row |
| `url` | Canonical Quora link for the row — answer permalink, question, profile, topic or space page. On every row |
| `source_url` | The URL the Actor actually opened to produce this row. On every row |
| `scrape_timestamp` | UTC ISO-8601 stamp of when the Actor wrote the row — the Actor's clock, not Quora's. On every row |
| `source_query` | The keyword that discovered this row, `""` for direct URLs. On `question` and `answer` rows only |
| `answer_text` | Full answer body flattened to plain text, not truncated. List items are prefixed `- ` |
| `answer_url` | Direct permalink to the answer itself, `""` when Quora's node carries no permalink |
| `author_name` | Answer author's display name, assembled from Quora's `givenName` + `familyName` |
| `author_url` | Answer author's Quora profile URL |
| `author_credentials` | The author's credential line as Quora displays it, `""` when absent |
| `upvotes` | Upvote count on the answer, `0` when Quora omits it |
| `comments_count` | Displayed comment count on the answer, `0` when Quora omits it |
| `shares_count` | Share count on the answer, `0` when Quora omits it |
| `answer_timestamp` | Relative age string computed from Quora's `creationTime` — `4y`, `7mo`, `3d`, `just now` |
| `created_at` | Absolute answer date as ISO-8601 UTC, or `null` when `creationTime` is missing or unparseable |
| `age_days` | Whole days since the answer was posted, or `null` when `created_at` is `null` |
| `is_ai_answer` | `true` when Quora flags the answer as machine-generated |
| `question_title` | Title of the question the answer sits under — identical to `title` on `answer` rows |
| `question_url` | URL of the question the answer sits under |
| `answer_count` | Answers on the question (`question` rows) or public answers by the person (`profile` rows) |
| `follow_count` | Followers of the question. On `question` rows only — note the name differs from `follower_count` |
| `topics` | Array of Quora topic names attached to the question, `[]` when none are exposed |
| `name` | Person, topic or space name. On `profile`, `topic` and `space` rows — duplicates `title` |
| `bio` | Profile biography, flattened from Quora's rich-text document to plain text |
| `credentials` | Profile credential line, flattened to plain text |
| `profile_image_url` | Avatar image URL, `""` when absent |
| `follower_count` | Followers of the profile, topic or space |
| `following_count` | Accounts the profile follows |
| `question_count` | Questions asked by the profile |
| `total_views` | All-time public content views for the profile |
| `description` | Space description, flattened to plain text. On `space` rows only |
| `contributor_count` | Contributors to the space. On `space` rows only |

> `follow_count` on question rows and `follower_count` on profile, topic and space rows are two different keys for the same idea. The default **All Results** view maps its Followers column to `follower_count`, so question rows show blank there — read `follow_count` for question followers, or switch to the **Questions** view.

#### Question and answer text fields

`question` rows are the header for a page: `title`, `url`, `answer_count`, `follow_count` and `topics`. `answer` rows carry the substance — `answer_text` is the complete flattened answer body, never a snippet, and `question_title` / `question_url` repeat the parent question so an answer row stands on its own with no join.

`title` and `question_title` are set from the same value on answer rows, so they are always equal. `url` on an answer row is the answer permalink when Quora exposes one and falls back to the question link when it does not; `answer_url` is `""` in that case rather than duplicating the question link.

#### Engagement, timestamp and flag fields

`upvotes`, `comments_count` and `shares_count` come straight from Quora's own counters and are coerced to integers — they default to `0` when the field is missing from the payload, so a `0` means "not published" as often as it means "no engagement". Answer view counts are not part of the logged-out payload and are not returned.

Dates come in three forms from one source. Quora publishes a microsecond `creationTime`; from it the Actor derives `answer_timestamp` (the relative `4y` / `7mo` string Quora itself shows), `created_at` (absolute ISO-8601 UTC) and `age_days` (an integer). When `creationTime` is absent, `answer_timestamp` is `""` while `created_at` and `age_days` are `null`. `is_ai_answer` reflects Quora's own machine-answer flag.

#### Profile, topic and space fields

`profile` rows carry `name`, `bio`, `credentials`, `profile_image_url`, `follower_count`, `following_count`, `answer_count`, `question_count` and `total_views`. When a page has no usable User node at all, the row is rebuilt from the page's `og:title`, `og:image` and meta description, so you still get a named row rather than nothing.

`topic` rows are deliberately short — `name`, `url` and `follower_count`. `space` rows add `description` and `contributor_count`. Topic description, topic question count and space post count are omitted rather than shipped as permanently-empty columns, because Quora does not put them in the logged-out payload.

These three row types only ever come from `directUrls`. Keyword discovery filters its results down to question URLs, so a keyword-only run produces `question` and `answer` rows exclusively.

#### 🤖 Add-on: Need additional Quora data?

**Quora Scraper — Webhook Delivery & Demo Mode** covers the same platform with a webhook-first delivery model and a demo mode, which is handy when you want results POSTed to an endpoint instead of pulled from a dataset. For question-intent research beyond Quora, **Reddit Posts Scraper By Keyword & Score Filter** and **YouTube Search Scraper** surface the same audience questions on two other platforms.

### Why not build this yourself?

Quora publishes no public content API, so there is no supported endpoint to point at — which means a DIY build inherits every one of the problems this Actor already solves.

**Cloudflare, not HTML.** Quora sits behind Cloudflare, so a plain HTTP client gets an interstitial instead of a page. This Actor drives a real stealth Chromium (Playwright plus `playwright-stealth`, automation flags disabled, a fixed desktop user agent and viewport) and waits out the `Just a moment` / `Attention Required` challenge before parsing. Images, media and fonts are blocked at the route level so pages render on less bandwidth.

**Discovery is a separate problem from extraction.** Quora's own search box is not used at all. For each keyword the Actor queries DuckDuckGo's SPA, then DuckDuckGo's no-JS HTML endpoint, then Bing as a fallback — always as `<your keyword> site:quora.com` — unwraps DuckDuckGo's `uddg=` redirect links, filters candidates down to real question URLs, and when the engines mostly rank topic hubs it opens up to three of those hubs on Quora and harvests question URLs from their embedded feeds.

**The answers are not in the markup.** Quora ships its data as GraphQL payloads inside `window.ansFrontendGlobals.data.inlineQueryResults` plus `multipart/mixed` `gql_para_POST` streams fetched while scrolling. Both have to be captured and parsed, and answer bodies arrive as a rich-text `{"sections":[...]}` document that needs flattening before it is readable text.

**Deep answer pulls need tokens you have to go and find.** To page through answers deterministically the Actor scrapes the `formkey` and the question's GraphQL node id out of the rendered page, then fetches the referenced JS bundle to recover the 64-character persisted-query hash, then drives `QuestionPagedListPaginationQuery` over the same browser session so the Cloudflare clearance cookie is reused. If any of those tokens cannot be extracted it falls back to scroll-captured nodes automatically.

**Proxies and retries.** Every run climbs an automatic ladder — direct, then Apify datacenter, then Apify residential, sticky once escalated — with retries and backoff on top. You never create a proxy account or rotate an IP.

### How to use Quora Search Scraper

Quora Search Scraper runs on Apify. Start it from the Apify Console or call it through the Apify API. No Quora credentials are involved at any point.

1. Open Quora Search Scraper on Apify and click **Try for free**
2. Give it something to work on — **Search Keywords** (`searchQueries`), **Direct Quora URLs** (`directUrls`), or both. Neither is flagged required, but a run with neither exits immediately
3. Set **Maximum Results** (`maxResults`) — this is the total row count for the whole run, questions and answers and everything else combined
4. Leave **Proxy** on Apify Proxy so the automatic residential fallback can work, optionally picking a country
5. Click **Start** and watch rows land live in the Output tab
6. Export as JSON, CSV or Excel, or read the dataset through the Apify API

The Output tab has a view dropdown with six tables — **All Results**, **Answers**, **Questions**, **Profiles**, **Topics** and **Spaces** — so each content type is readable without filtering by hand. The Actor also mirrors each row into a per-type dataset alias (`section-answer`, `section-question`, and so on) when storage permissions allow it.

#### How to scale to bulk Quora extraction

Both input fields are lists, so bulk is the normal mode. `searchQueries` takes any number of keywords and `directUrls` takes any number of Quora URLs, one per line, and a single run processes keywords first and then direct URLs. A newline- or comma-separated string works too, and `{ "url": "..." }` objects are accepted as well as plain strings, so output from another tool can usually be fed in unchanged.

`maxResults` is a **global** budget, not a per-keyword one: ten keywords with `maxResults: 100` is a 100-row run in total, and the run stops the moment the budget is spent — the last keywords may never be reached. For a fixed quota per keyword, run one keyword per run and loop over the runs.

### What can you do with Quora question and answer data?

- 🔍 A **content strategist** planning a topic cluster runs five seed keywords, then ranks rows by `follow_count` and `answer_count` to find the questions an audience actually follows rather than the ones that merely exist.
- ✍️ An **SEO writer** drafting a FAQ page reads `title` and the top `answer_text` bodies sorted by `upvotes`, and uses `age_days` to drop advice that is five years stale.
- 📊 A **market researcher** studying how buyers describe a problem collects `answer_text` across a product category and filters `is_ai_answer` to `false` so machine-written filler never enters the sample.
- 👤 A **partnerships lead** vetting subject-matter experts pastes profile URLs into `directUrls` and screens `credentials`, `total_views` and `answer_count` to find people with real depth before reaching out.
- 🤖 An **AI engineer** building a question-answering agent indexes `answer_text` with `title`, `topics` and `upvotes` as metadata into a vector store, so the agent can answer "what do experienced practitioners actually say about this" from live Q\&A rather than a stale export.

Every one of these is callable from an agent framework over the Apify API, since the Actor is a standard HTTP-triggered run.

### How does Quora Search Scraper handle rate limits and blocking?

Egress runs on a **proxy escalation ladder that starts at the cheapest rung**. Every run begins on a **direct connection with no proxy at all**. Only when Quora pushes back does the Actor climb: direct → Apify datacenter → Apify residential, logging each switch, and it sticks on the higher rung once it has escalated. Once on residential it grants up to three extra attempts before giving up on a target.

Requests go out from a stealth Chromium instance with `AutomationControlled` disabled, a fixed desktop user agent, an `en-US` locale and a real viewport. Cloudflare's interstitial is detected by page title (`Just a moment`, `Attention Required`) and waited out — up to six checks at 2.5-second intervals per navigation attempt — with up to three navigation attempts and a reload between them.

There is **no CAPTCHA solving** in this Actor, and none is claimed. If a page is still challenged after every attempt, the Actor parses what it has, which simply yields fewer or zero rows for that URL.

When a target returns nothing, the Actor escalates the ladder and retries it — up to three attempts, plus three more once it reaches the residential rung, with a backoff that grows by three seconds per attempt. If it still comes back empty it logs `Gave up on <url>` with the reason and moves to the next target; rows already collected are kept. Keyword discovery gets the same treatment: an empty round triggers a ladder climb and a retry before the keyword is abandoned.

### ⬇️ Input

Four parameters, none of them flagged required by the schema. Supply at least one of `searchQueries` or `directUrls` or the run exits with nothing.

| Parameter | Required | Type | Description | Example Value |
| ----- | ----- | ----- | ----- | ----- |
| `searchQueries` | No | array | Keywords to search on Quora. Each keyword discovers relevant Quora question URLs (via DuckDuckGo) and scrapes them. No Quora login needed. Prefilled with `["python programming"]`. | `["what is python used for", "best python web framework"]` |
| `directUrls` | No | array | Paste any Quora URLs directly — questions, profiles, topics or spaces. Supports bulk input (one per line). Prefilled empty. | `["https://www.quora.com/What-is-Python-used-for", "https://www.quora.com/profile/Guido-van-Rossum-1"]` |
| `maxResults` | No | integer | Total number of result rows to collect — across all keywords and URLs combined. Minimum 1, maximum 50000. Default `10`. | `100` |
| `proxyConfiguration` | No | object | Optional Apify Proxy configuration used as the mid-tier (datacenter) network. Residential is applied automatically as the final fallback. Default `{"useApifyProxy": true}`. | `{"useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"]}` |

Five honest notes on how these actually behave:

- **`maxResults` has two different defaults.** The schema default and prefill are `10`, which is what the Console shows you. The code's own fallback is `50`, so an API call that omits `maxResults` entirely — or sends `0` or `null` — targets 50 rows, not 10. Send the number explicitly if it matters. The 1–50000 range is this Actor's cap, not Quora's.
- **`maxResults` counts every row, not just answers.** A question contributes one `question` row before its answers do, so `maxResults: 10` on a single question is one question row plus nine answers.
- **`proxyConfiguration` is read far more narrowly than it looks.** The only key taken from your object is `apifyProxyCountry`, and it is applied to the **residential** rung only. The datacenter rung is always built as `{"useApifyProxy": true}` and the residential rung always uses the `RESIDENTIAL` group, whatever you selected. Setting `useApifyProxy: false` does not produce a direct-only run — it only removes your ability to pick a country.
- **`urls` is accepted but undocumented.** The code merges a `urls` field into `directUrls` if you send one. It is not in the schema, so the Console will not show it; it exists so bulk output from other tools drops in unchanged.
- ⚠️ **Non-Quora URLs are not rejected.** `directUrls` entries are only checked for a valid `http`/`https` scheme and host. Anything that is not a `/profile/`, `/topic/`, `/q/` or `/space/` path is treated as a question page — including a non-Quora URL, which will be opened, parsed for Quora payloads, found empty, and retried before being abandoned. Space URLs must be in `/q/` or `/space/` form; a `subdomain.quora.com` space link is classified as a question.

#### Example input

```json
{
  "searchQueries": [
    "what is python used for",
    "best python web framework"
  ],
  "directUrls": [
    "https://www.quora.com/What-is-Python-used-for",
    "https://www.quora.com/profile/Guido-van-Rossum-1",
    "https://www.quora.com/topic/Python-programming-language-1",
    "https://www.quora.com/q/datascience"
  ],
  "maxResults": 120,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"],
    "apifyProxyCountry": "US"
  }
}
```

### ⬆️ Output

Typed, normalized JSON with a stable shape per `content_type` across runs. Rows are pushed live as each page is parsed, so the dataset fills while the run is still going. Export as JSON, CSV or Excel, or read the dataset through the Apify API.

Because five row types share one dataset, the shape is sparse by design: an `answer` row carries 20 keys, a `profile` row 14, `question` and `space` rows 9 each, and a `topic` row 7. Keys that do not apply to a row type are **omitted, not set to `null`**, so use a presence check (`row.get("upvotes")`) rather than assuming a key exists. The two keys that genuinely carry `null` are `created_at` and `age_days`, when Quora publishes no `creationTime` for an answer.

**Every row in the dataset is charged.** Each pushed row bills one `row_result` event, and there are no free metadata rows to filter out — this Actor writes no header rows, no diagnostic rows and no accounting rows, so there is no `errorReason`, `status` or `isDiagnostic` marker field to look for. A run that collects nothing pushes nothing and therefore charges nothing; failures show up in the run log, not in the dataset. The only filter you are likely to need is a split by type:

```python
answers = [r for r in items if r["content_type"] == "answer"]
```

The per-type mirror datasets (`section-answer`, `section-question`, `section-profile`, `section-topic`, `section-space`) are copies of rows already charged in the default dataset — reading them costs no extra events. If storage permissions block the mirror, the run continues with the default dataset only.

#### Example output

An `answer` row — the type most runs are mostly made of:

```json
{
  "content_type": "answer",
  "title": "What is Python primarily used for?",
  "url": "https://www.quora.com/What-is-Python-primarily-used-for/answer/Ravi-Chandran-88",
  "answer_text": "Python earns its keep in four places, and they barely overlap:\n- Data work: pandas, NumPy and scikit-learn are the default toolkit in most analytics teams.\n- Backend services: Django and FastAPI run a large share of the APIs you use daily.\n- Automation and glue: anything that has to talk to three systems at once.\n- Teaching: the syntax gets out of the way while people learn to think.\n\nWhere it struggles is anything latency-critical or memory-bound. I have never regretted reaching for Go there.",
  "answer_url": "https://www.quora.com/What-is-Python-primarily-used-for/answer/Ravi-Chandran-88",
  "author_name": "Ravi Chandran",
  "author_url": "https://www.quora.com/profile/Ravi-Chandran-88",
  "author_credentials": "Backend engineer, 12 years writing Python in production",
  "upvotes": 1847,
  "comments_count": 63,
  "shares_count": 21,
  "answer_timestamp": "2y",
  "created_at": "2024-04-18T11:32:07+00:00",
  "age_days": 828,
  "is_ai_answer": false,
  "question_title": "What is Python primarily used for?",
  "question_url": "https://www.quora.com/What-is-Python-primarily-used-for",
  "source_url": "https://www.quora.com/What-is-Python-primarily-used-for",
  "source_query": "what is python used for",
  "scrape_timestamp": "2026-07-25T09:14:02.481230+00:00"
}
```

The `question` row that preceded it:

```json
{
  "content_type": "question",
  "title": "What is Python primarily used for?",
  "url": "https://www.quora.com/What-is-Python-primarily-used-for",
  "answer_count": 214,
  "follow_count": 1396,
  "topics": ["Python (programming language)", "Software Development", "Computer Programming"],
  "source_url": "https://www.quora.com/What-is-Python-primarily-used-for",
  "source_query": "what is python used for",
  "scrape_timestamp": "2026-07-25T09:13:58.902847+00:00"
}
```

A `profile` row from a direct URL — note that `source_query` is absent, not empty:

```json
{
  "content_type": "profile",
  "title": "Guido van Rossum",
  "name": "Guido van Rossum",
  "url": "https://www.quora.com/profile/Guido-van-Rossum-1",
  "bio": "Creator of Python. Distinguished Engineer at Microsoft.",
  "credentials": "Created the Python programming language",
  "profile_image_url": "https://qph.cf2.quoracdn.net/main-thumb-1042118-200-oqkfmzwjxvbpqhtnrwdlkzcgeuysinat.jpeg",
  "follower_count": 148203,
  "following_count": 37,
  "answer_count": 412,
  "question_count": 19,
  "total_views": 41738522,
  "source_url": "https://www.quora.com/profile/Guido-van-Rossum-1",
  "scrape_timestamp": "2026-07-25T09:16:44.113905+00:00"
}
```

A `space` row, showing the two keys unique to that type:

```json
{
  "content_type": "space",
  "title": "Data Science",
  "name": "Data Science",
  "url": "https://www.quora.com/q/datascience",
  "description": "A space for practitioners to share applied machine learning and analytics work.",
  "follower_count": 104318,
  "contributor_count": 2740,
  "source_url": "https://www.quora.com/q/datascience",
  "scrape_timestamp": "2026-07-25T09:17:12.660428+00:00"
}
```

And a `topic` row, the shortest shape in the dataset:

```json
{
  "content_type": "topic",
  "title": "Python (programming language)",
  "name": "Python (programming language)",
  "url": "https://www.quora.com/topic/Python-programming-language-1",
  "follower_count": 1604882,
  "source_url": "https://www.quora.com/topic/Python-programming-language-1",
  "scrape_timestamp": "2026-07-25T09:17:39.204815+00:00"
}
```

### How does it work?

Quora renders in the browser and ships its data as GraphQL payloads rather than as markup, so the Actor drives a stealth Chromium instance instead of an HTTP client. Each page is opened, scrolled, and read two ways at once: the payloads Quora inlines into the HTML, and the `multipart/mixed` `gql_para_POST` responses it fetches while scrolling. Images, media and fonts are blocked to keep the page light.

For a keyword, question URLs are discovered through DuckDuckGo and Bing with a `site:quora.com` filter, topping up from Quora's own topic hubs when the engines rank those higher. For a question page, answers are then paged deterministically through Quora's `QuestionPagedListPaginationQuery` cursor query — reusing the same browser session that already cleared Cloudflare — with scroll-captured nodes as an automatic fallback when the required tokens cannot be extracted.

Requests start on a direct connection and escalate to an Apify datacenter proxy and then residential only when Quora pushes back. Answer bodies and bios arrive as rich-text documents and are flattened to plain text; string numbers are coerced to integers. Because the data comes from those structured payloads rather than from CSS selectors, a Quora front-end redesign does not change your field names. Only publicly visible data is collected — no account, cookie or session is used.

### Integrations

Quora Search Scraper is an Apify Actor, so it works with anything that can call the Apify API or consume a dataset.

#### Calling Quora Search Scraper from Python

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")

run = client.actor("<YOUR_USERNAME>/quora-search-scraper").call(run_input={
    "searchQueries": ["what is python used for"],
    "directUrls": ["https://www.quora.com/profile/Guido-van-Rossum-1"],
    "maxResults": 100,
    "proxyConfiguration": {"useApifyProxy": True},
})

for row in client.dataset(run["defaultDatasetId"]).iterate_items():
    if row["content_type"] == "answer":
        print(row["upvotes"], row["author_name"], row["created_at"], row["answer_url"])
```

Works in Go, Ruby, Node.js, cURL — any language that can make an HTTP request. Branch on `content_type` to route each row type to the right handler.

#### No-code tools (n8n, Make, LangChain)

In n8n, use the Apify node — or an HTTP Request node pointed at the Apify run endpoint with your token — and pass the same JSON input shown above; a Switch node on `content_type` then splits answers, questions and profiles into separate branches. In Make, the Apify module supports run-and-wait, so a weekly keyword sweep can feed a Google Sheets or Airtable step directly. In LangChain, wrap the run endpoint as a tool and hand `answer_text` straight to the model, since it arrives as flat plain text. Apify schedules and webhooks handle recurrence and completion triggers, so a recurring question monitor needs no code of your own.

### Is it legal to scrape Quora questions and answers?

Scraping publicly accessible pages is broadly treated as permissible where no authentication is bypassed, and Quora Search Scraper reads only what a logged-out visitor sees — no account, no cookie, no session.

The regime that applies most directly here is **contractual and copyright-based**. Quora's terms of service govern automated access to and reuse of its site, and the substance of what you collect — `answer_text`, `title` / `question_title`, `bio` and `description` — is user-generated writing that its authors own. Reading it for research is a different proposition from republishing it, and republishing collected answer text as your own content or as a competing corpus is where the real exposure sits.

A narrower personal-data question attaches to the author-identity fields, because some of what this Actor returns identifies real people. On `answer` rows that is `author_name`, `author_url` and `author_credentials`. On `profile` rows it is `title`, `name`, `url`, `bio`, `credentials`, `profile_image_url`, `follower_count`, `following_count`, `answer_count`, `question_count` and `total_views`. Under GDPR and CCPA you need a lawful basis before you store or reuse those specific fields, and data minimisation applies — if your use case is content research, drop the author columns at ingestion and keep the text. `question`, `topic` and `space` rows carry no author identity at all.

Consult legal counsel if your use case involves bulk storage of personal data, or republication of collected answer text.

### ❓ Frequently asked questions

#### What Quora fields does Quora Search Scraper return?

The five most used are `answer_text`, `upvotes`, `author_name`, `title` and `created_at`. Every row also carries `content_type`, `url`, `source_url` and `scrape_timestamp`. Across the five row types the Actor writes 33 distinct keys — see the data fields table above for all of them.

#### Does Quora Search Scraper require a Quora account, login or cookies?

No. The Actor holds no session at any point — no username, no password, no cookie export. It reads the same logged-out pages any visitor sees. The only credential involved is your Apify token, and only if you call it through the API rather than the Console.

#### How many results can I extract in one run?

`maxResults` accepts 1 to 50000 and is the **total** row count for the run, across every keyword and URL combined. That range is this Actor's own cap. Whether you reach the number depends on the targets: per question, answers are paged in batches of 20 with a ceiling of 60 pagination requests, and discovery stops early when the search engines and topic hubs stop yielding new question URLs. Question rows count toward the budget alongside answers.

#### Does it return full answers or truncated snippets?

Full answers. `answer_text` is Quora's complete answer body, flattened from its rich-text document into plain text with list items prefixed `- `. There is no character cap and no truncation step anywhere in the code.

#### Are the upvote counts and timestamps real, or estimated?

Real, straight from Quora's own payload. `upvotes`, `comments_count` and `shares_count` are Quora's counters coerced to integers, and they default to `0` when the field is missing — so a `0` can mean "not published" rather than "no engagement". Dates all derive from Quora's `creationTime`: `answer_timestamp` is the relative string Quora itself shows, `created_at` is absolute ISO-8601, `age_days` is an integer. Answer view counts are not in the logged-out payload and are not returned. `scrape_timestamp` is the Actor's own clock, not Quora data.

#### What happens if a query returns zero results?

The run finishes normally and pushes nothing for that keyword. Discovery tries DuckDuckGo's SPA, DuckDuckGo's HTML endpoint and Bing, then expands up to three topic hubs; if the whole round comes up empty the Actor climbs the proxy ladder and retries, with three extra attempts once it is on residential. Only then does it return an empty list and move to the next keyword. If a run ends with zero rows overall, the log says so and suggests enabling the Apify residential proxy. Because no diagnostic row is written and only real rows are charged, a zero-result run leaves you an empty dataset and no charge — check the run log rather than looking for an error row.

#### Can I scrape multiple Quora questions, keywords and URLs at once?

Yes. `searchQueries` and `directUrls` are both lists and can be used together in one run; keywords are processed first, then direct URLs. Duplicate URLs are removed **within** a single keyword's discovery, not across keywords and not against `directUrls` — if two keywords surface the same question, that question is scraped twice and appears twice. Deduplicate on `url` if that matters. Answers are deduplicated by Quora's own answer id within each question.

#### Does Quora Search Scraper work with Claude, ChatGPT and other AI agent tools?

Yes. It is callable as a standard HTTP-triggered run through the Apify API, so LangChain, CrewAI, n8n or a hand-written tool definition can invoke it and receive typed JSON with no parsing step. Have the agent branch on `content_type` and everything it sees is already flat.

#### How does Quora Search Scraper compare to other Quora scrapers?

Checked on the Apify Store on 25 July 2026: `crawlerbros/quora-search-scraper` documents the closest feature set — keyword search plus direct URLs, the same five content types and a near-identical field list — and its listing states no Quora account or cookies are needed, a 1–5,000 result range described as per query or per question, a minimum 1024 MB memory requirement, and that keyword search returns 1–5 question URLs per query; its documented topic and space rows include `description`, `question_count` and `post_count`, and its answer rows do not document absolute dates. `memo23/Quora-Scraper-with-optional-login` takes `startUrls` including Quora `search?q=` URLs and states plainly that you must supply cookies from a logged-in Quora account to reach search data; its documented output keeps Quora's raw key names (`qid`, `numUpvotes`, `numViews`, `creationTime`). `alizarin_refrigerator-owner/quora-research` is a bring-your-own-key Actor — its listing requires a cookie export from the Cookie-Editor extension, offers a free demo mode with sample data, and documents filters this Actor does not have, such as `minAnswerUpvotes`, `answersPerQuestion` and `sortBy`.

What this Actor documents explicitly against that field: no login or cookie of any kind, absolute answer dates (`created_at` and `age_days`) alongside the relative string, a global rather than per-query result budget, the direct-first proxy ladder, and columns Quora does not expose anonymously left out rather than shipped permanently empty.

#### Does Quora Search Scraper return data in a format LLMs can use directly?

Yes. Typed, normalized JSON with consistent field names across runs, rich-text documents already flattened to plain text and string numbers already coerced to integers. No HTML parsing, no selectors. Pass a row directly into an LLM, index it into a vector store, or hand it to an agent tool.

#### What happens when Quora changes its layout or anti-bot system?

The scraper is maintained, and because it reads Quora's embedded GraphQL payloads rather than CSS selectors, a front-end redesign generally does not affect the field names you consume. Nodes are located by a recursive walk over the payloads instead of fixed paths, so a moved key degrades one field rather than breaking the row, and the deterministic answer pagination falls back to scroll capture on its own when Quora's tokens move. Your field names and types stay the same on your end.

#### Can I use Quora Search Scraper without managing proxies or browser infrastructure?

Yes. The browser, the stealth configuration and the proxy ladder are all handled for you — direct, then Apify datacenter, then Apify residential with three extra retries, sticky once escalated. You never create a proxy account, rotate an IP or run a Chromium instance yourself. The Actor does not solve CAPTCHAs, and it makes no claim to.

#### Which Quora fields work best for AI training data and RAG indexing?

For RAG indexing: `answer_text` carries by far the most information per record and chunks cleanly, with `title` and `topics` as ready-made metadata filters and `url` as the citation. For training data: `upvotes`, `comments_count`, `answer_count`, `follow_count`, `age_days` and `is_ai_answer` are the most structurally consistent fields across records. All values return as typed primitives or plain arrays, so no normalization pass is needed — just remember that `created_at` and `age_days` can be `null`, that keys not belonging to a row type are absent rather than `null`, and that filtering `is_ai_answer` to `false` keeps machine-written text out of a human-language corpus.

### 🔗 Related scrapers

| Scraper Name | What it extracts |
| ----- | ----- |
| Quora Scraper — Webhook Delivery & Demo Mode | The same Quora content with webhook delivery and a demo mode |
| Reddit Posts Scraper By Keyword & Score Filter | Reddit posts for a keyword, filtered by score |
| Reddit User Profile Posts And Comments Scraper With Account Age | A Reddit user's posts and comments with account age and karma stats |
| YouTube Search Scraper | Videos, channels and playlists for a search term |
| X (Twitter) Posts Search | Public posts matching a search query |
| Google News Scraper By Publisher & Site Filter | News articles filtered by publisher and site |

### 💬 Your feedback

Found a bug, or need a field that is in Quora's payload but not in the output? Open an issue on the Actor's Issues tab. Reports that include the exact input JSON and the keyword or Quora URL you ran are the fastest to reproduce and fix.

# Actor input Schema

## `searchQueries` (type: `array`):

Keywords to search on Quora. Each keyword discovers relevant Quora question URLs (via DuckDuckGo) and scrapes them. No Quora login needed. ✨ Example: "what is python used for".

## `directUrls` (type: `array`):

Paste any Quora URLs directly — questions ❓, profiles 👤, topics 🏷️ or spaces 🪐. Supports bulk input (one per line).

## `maxResults` (type: `integer`):

Total number of result rows to collect — across all keywords and URLs combined. Want 60, 200 or 500 rows? Set exactly that. ✅

## `proxyConfiguration` (type: `object`):

Optional Apify Proxy configuration used as the mid-tier (datacenter) network. Residential is applied automatically as the final fallback.

## Actor input object example

```json
{
  "searchQueries": [
    "python programming"
  ],
  "directUrls": [],
  "maxResults": 10,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "searchQueries": [
        "python programming"
    ],
    "directUrls": [],
    "maxResults": 10,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("scraper-engine/quora-search-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "searchQueries": ["python programming"],
    "directUrls": [],
    "maxResults": 10,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("scraper-engine/quora-search-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchQueries": [
    "python programming"
  ],
  "directUrls": [],
  "maxResults": 10,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call scraper-engine/quora-search-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=scraper-engine/quora-search-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/vA9p9rhmaEa30a0mH/builds/H3OTxJWV1HPUqLtQ2/openapi.json
