# Google Scholar Paper & Citation Search Scraper (`dataspryva/google-scholar-paper-and-citation-search-scraper`) Actor

Search Google Scholar by keyword and get structured records for papers and citations, with author, venue, year, citation counts, and links to PDFs and related work. Filter by year range, document format, and article type.

- **URL**: https://apify.com/dataspryva/google-scholar-paper-and-citation-search-scraper.md
- **Developed by:** [Dataspryva](https://apify.com/dataspryva) (community)
- **Categories:** AI, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.49 / 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.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Google Scholar Paper & Citation Search Scraper

Search **Google Scholar** for papers, follow their citations, and export public researcher profiles as clean structured data. One actor covers keyword search with year and review filters, citing-paper lists, author metrics such as h-index and i10-index, PDF links, citation styles, and cluster identifiers for follow-up queries. No Google account, API key, or proxy setup is needed.

### What this actor does

- **Three modes:** `search` finds papers by keyword, `citations` lists papers that cite a known article, and `authorProfile` exports a public researcher profile with its publication list.
- **Paper search filters:** year range, newest-first sorting, review articles only, and client-side PDF/HTML filtering. Optional advanced filters narrow results by author, venue, or title-only matching.
- **Citing papers:** pass a Scholar cluster ID or a `cites=` URL and receive the citing works with the same paper fields.
- **Author profiles:** name, affiliation, verified email domain, homepage, research interests, citations, h-index, i10-index (all-time and recent), plus the paginated publication table.
- **Citation styles:** optionally add MLA, APA, Chicago, Harvard, and Vancouver text for returned results, with a bounded time budget so search rows are still saved if formats are slow.
- **Honest data:** PDF links point at the file Scholar lists, book and citation-only rows are typed correctly, duplicate rows within each query or citation list are removed, and empty fields are omitted.

### Output per record

Every record has a `recordType`: `paper`, `citation`, or `author`.

#### Paper and citation records

- `title` — paper or article title
- `link` — publisher or landing-page URL
- `documentLink` — direct PDF or HTML file URL, when Scholar lists one
- `documentType` — `PDF`, `HTML`, `PS`, or omitted
- `authors` — author names as shown by Scholar
- `publication` — journal, conference, or venue text from Scholar (some rows include the publisher or source domain)
- `year` — publication year
- `source` — hosting domain, such as `arxiv.org`, when Scholar separates it from the venue
- `fullAttribution` — the complete attribution line from Scholar
- `searchMatch` — snippet showing where the query matched
- `citations` — cited-by count (`0` when Scholar shows none)
- `citationsLink` — link to the citing-paper list
- `relatedArticlesLink` — link to related articles
- `versions` / `versionsLink` — version count and link, when Scholar shows them
- `type` — `ARTICLE`, `BOOK`, or `CITATION`
- `resultIndex` — position in the result list (0-based)
- `clusterId` — Scholar cluster ID, useful for citation lookups
- `resultId` — Scholar's internal result ID
- `scholarUrl` — Scholar page for the article cluster
- `authorIds` / `authorProfileUrls` — linked author profiles
- `doi` — clean DOI parsed from the result URL when present; Scholar does not expose a DOI field directly
- `citationFormats` — `mla`, `apa`, `chicago`, `harvard`, `vancouver` when requested
- `searchQuery` — the query that found the paper (search mode)
- `citedByOf` — the cluster ID being cited (citations mode)
- `scrapeTimestamp` — ISO 8601 scrape time

#### Author records

- `authorId`, `profileUrl`, `name`, `affiliation`
- `verifiedEmailDomain`, `homepageUrl`, `interests`, `thumbnailUrl`
- `citations`, `citationsSince`, `hIndex`, `hIndexSince`, `i10Index`, `i10IndexSince`, `metricsSinceYear`
- `publications` — title, authors, venue, year, citations, Scholar URL, citation ID, and optional journal/volume/issue/pages/publisher/abstract/publication date/total citations
- `publicationCount`
- `scrapeTimestamp`

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | string | `search` | `search`, `citations`, or `authorProfile` |
| `queries` | array | `["attention is all you need"]` | Search terms for `mode=search` |
| `clusterIds` | array | – | Cluster IDs or `cites=` URLs for `mode=citations` |
| `authorIds` | array | – | Author IDs or profile URLs for `mode=authorProfile` |
| `maxItems` | integer | `100` | Maximum papers per query/cluster, or papers per author (1–1000) |
| `sortBy` | string | `relevance` | `relevance` or `date` |
| `filter` | string | `all` | `all`, `pdfOnly`, or `htmlOnly` |
| `articleType` | string | `any` | `any` or `review` |
| `newerThan` | integer | – | Earliest publication year |
| `olderThan` | integer | – | Latest publication year |
| `author` | string | – | Return papers by this author |
| `publication` | string | – | Return papers from this venue |
| `titleOnly` | boolean | `false` | Match the query against titles |
| `includeCitationFormats` | boolean | `false` | Add five citation styles for returned rows within a bounded budget; a slow format lookup never drops the search rows |
| `includePaperDetails` | boolean | `false` | Add journal, volume, issue, pages, publisher, publication date, abstract, and total citations to author publications |

### Examples

#### Search recent review papers on a medical topic

```json
{
    "mode": "search",
    "queries": ["cancer immunotherapy"],
    "maxItems": 30,
    "articleType": "review",
    "newerThan": 2022
}
```

#### Find papers by a specific author in a specific venue

```json
{
    "mode": "search",
    "queries": ["quantum computing"],
    "author": "Andrew Steane",
    "publication": "Physical Review",
    "maxItems": 20
}
```

#### List papers that cite a known article

```json
{
    "mode": "citations",
    "clusterIds": ["184251978817409129"],
    "maxItems": 50,
    "includeCitationFormats": true
}
```

#### Export an author profile with paper details

```json
{
    "mode": "authorProfile",
    "authorIds": ["https://scholar.google.com/citations?user=-AXbSiwAAAAJ&hl=en"],
    "maxItems": 100,
    "includePaperDetails": true
}
```

### Use cases

- **Literature reviews** — collect a structured reading list and follow citation chains without copying rows from Scholar.
- **Bibliometrics** — track citation counts, h-index, and i10-index for researchers or fields.
- **Research monitoring** — rerun saved queries to catch new papers in a topic.
- **Citation analysis** — export citing papers for one or more key articles.
- **Academic recruiting and grants** — compare public publication records and recent citation metrics.
- **Data pipelines** — feed clean JSON into a database, spreadsheet, or research assistant.

### FAQ

#### Do I need a Google Scholar account, API key, or proxy?

No. The actor reads public Scholar pages and selects a working connection automatically. Just provide the input and run it.

#### Why do I get fewer results than `maxItems`?

Google Scholar serves about 10 search results per page and may return an empty or partial page for deep pagination. The actor retries on a fresh connection and stops with an honest status instead of inventing rows. For broad topics, split the query by year, venue, or author to reach more results.

#### What is a cluster ID and where do I find it?

A cluster ID identifies one article and all of its known versions on Scholar. It is the number in a `cites=` or `cluster=` URL, and it is also returned as `clusterId` on every search result. Use it as input to `mode=citations` to list citing papers.

#### Why is a DOI missing from some records?

Google Scholar does not show a DOI field on search results. The actor adds a DOI only when the result's URL contains one, so many records correctly omit it. It never guesses a DOI. Query strings, fragments, and common suffix paths such as `/meta` or `.html` are removed.

#### Which citation styles are supported?

MLA, APA, Chicago, Harvard, and Vancouver are returned as text when `includeCitationFormats` is enabled. The actor looks up each returned result ID, including deeper pages, within a bounded time budget. If Google Scholar is slow or blocks some format lookups, the already-collected paper rows are still saved and the run status reports how many rows received formats. The option adds one request per row, so it is slower than a plain search.

#### Why are some PDF links missing?

Scholar only shows a file link when it has indexed a PDF or HTML copy. The actor returns the real file URL and omits `documentLink` when no file is available. `link` still points to the publisher or landing page.

#### Why do author profiles not include coauthors?

Coauthor cards are not part of the public profile view; Scholar only exposes them through a signed-in editing dialog. The actor returns the public fields it can verify: affiliation, interests, metrics, and the publication list.

#### Can I search for an author by name and get their profile automatically?

Author-name profile search requires a Google sign-in, so the actor does not offer it. If you know the profile URL or user ID, paste it into `authorIds`; author names linked from search results are also returned in `authorIds` and `authorProfileUrls`.

#### How are year filters handled with newest-first sorting?

When a year range is set, the actor sends Scholar's server-side `as_ylo`/`as_yhi` bounds (even with `sortBy: "date"`) and verifies the years on the returned rows. Newest-first order is then applied within each page, because Scholar ignores a global date sort when a year range is active. A 2020–2022 range therefore returns matching papers instead of a false empty result.

#### Is this affiliated with Google or Google Scholar?

No. This is an independent third-party actor that reads publicly available Google Scholar pages. It is not operated by or endorsed by Google.

# Actor input Schema

## `mode` (type: `string`):

What to fetch: paper search, citing papers, or public author profiles.

## `queries` (type: `array`):

Keywords or paper titles to search on Google Scholar (mode=search). Each query runs separately.

## `clusterIds` (type: `array`):

Paper cluster IDs or Google Scholar 'cites=' URLs to list citing papers for (mode=citations).

## `authorIds` (type: `array`):

Google Scholar author IDs or profile URLs to export (mode=authorProfile).

## `maxItems` (type: `integer`):

Maximum papers per query or cluster, or papers per author. Google Scholar serves about 10 search results per page.

## `sortBy` (type: `string`):

Sort search results by relevance or date (mode=search).

## `filter` (type: `string`):

Keep only PDF or HTML results; applied to returned rows (mode=search).

## `articleType` (type: `string`):

Return all articles or review articles only (mode=search).

## `newerThan` (type: `integer`):

Only include papers published in this year or later (mode=search).

## `olderThan` (type: `integer`):

Only include papers published in this year or earlier (mode=search).

## `author` (type: `string`):

Return papers written by this author, e.g. 'Geoffrey Hinton' (mode=search).

## `publication` (type: `string`):

Return papers from this journal or venue, e.g. 'Nature' (mode=search).

## `titleOnly` (type: `boolean`):

Match the query against paper titles instead of the full text (mode=search).

## `includeCitationFormats` (type: `boolean`):

Also return MLA, APA, Chicago, Harvard, and Vancouver citations for returned rows, within a bounded budget (mode=search or citations).

## `includePaperDetails` (type: `boolean`):

Fetch journal, volume, pages, publisher, and abstract for each author publication (mode=authorProfile).

## Actor input object example

```json
{
  "mode": "search",
  "queries": [
    "attention is all you need"
  ],
  "maxItems": 3,
  "sortBy": "relevance",
  "filter": "all",
  "articleType": "any",
  "titleOnly": false,
  "includeCitationFormats": false,
  "includePaperDetails": false
}
```

# Actor output Schema

## `results` (type: `string`):

Dataset containing scraped papers, citing papers, or author profiles.

# 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 = {
    "mode": "search",
    "queries": [
        "attention is all you need"
    ],
    "maxItems": 3,
    "sortBy": "relevance",
    "filter": "all",
    "articleType": "any",
    "titleOnly": false,
    "includeCitationFormats": false,
    "includePaperDetails": false
};

// Run the Actor and wait for it to finish
const run = await client.actor("dataspryva/google-scholar-paper-and-citation-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 = {
    "mode": "search",
    "queries": ["attention is all you need"],
    "maxItems": 3,
    "sortBy": "relevance",
    "filter": "all",
    "articleType": "any",
    "titleOnly": False,
    "includeCitationFormats": False,
    "includePaperDetails": False,
}

# Run the Actor and wait for it to finish
run = client.actor("dataspryva/google-scholar-paper-and-citation-search-scraper").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "mode": "search",
  "queries": [
    "attention is all you need"
  ],
  "maxItems": 3,
  "sortBy": "relevance",
  "filter": "all",
  "articleType": "any",
  "titleOnly": false,
  "includeCitationFormats": false,
  "includePaperDetails": false
}' |
apify call dataspryva/google-scholar-paper-and-citation-search-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,dataspryva/google-scholar-paper-and-citation-search-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

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