# Google Scholar Scraper - Papers, Citations & h-index (`scrapewise/google-scholar-scraper`) Actor

Scrape Google Scholar without login: search results, author profiles (h-index, i10, citations per year, all articles) and cited-by lists. Title, authors with profile ids, venue, year, PDF link, cited-by count, versions. Pay per result.

- **URL**: https://apify.com/scrapewise/google-scholar-scraper.md
- **Developed by:** [Scrapewise Data](https://apify.com/scrapewise) (community)
- **Categories:** Lead generation, Developer tools
- **Stats:** 3 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $7.65 / 1,000 result delivereds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
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 Scraper

Google Scholar Scraper turns **Google Scholar** into clean JSON, CSV or Excel, **without login, cookies or a paid SERP API**. Search papers by keyword (with year filters and Scholar operators), read **author profiles** with **h-index, i10-index, total citations and citations per year**, and list every paper that **cites** a given article. Each paper comes with title, authors (with their Scholar profile ids), publication, year, publisher, snippet, **PDF link**, **cited-by count**, versions and related links.

**US$ 9 per 1,000 results. No monthly fee, no start fee. Error rows are free.**

### At a glance

- **Price per 1,000 results:** US$ 9, no run start fee
- **Price per author profile:** US$ 0.009 (articles charged as results)
- **Modes:** Keyword search, author profile, cited-by list, or any Scholar link
- **Author metrics:** Citations, h-index, i10-index (all time and since 2021), citations per year, co-authors
- **Paper data:** Authors with profile ids, venue, year, PDF link, cited-by count and id, versions, related
- **Error rows:** Free, with an `errorCode`

### One real row

Search `large language models`, collected on 2026-09-30 in an Apify cloud run:

```json
{
  "type": "result",
  "source": "search:large language models",
  "position": 1,
  "title": "A survey on evaluation of large language models",
  "url": "https://dl.acm.org/doi/abs/10.1145/3641289",
  "pdfUrl": "https://dl.acm.org/doi/pdf/10.1145/3641289",
  "resultType": "article",
  "authors": [
    { "name": "Y Chang", "profileId": "Hw-lrpAAAAAJ", "profileUrl": "https://scholar.google.com/citations?user=Hw-lrpAAAAAJ&hl=en" },
    { "name": "X Wang", "profileId": "Q7Ieos8AAAAJ", "profileUrl": "https://scholar.google.com/citations?user=Q7Ieos8AAAAJ&hl=en" }
  ],
  "publication": "ACM transactions on …",
  "year": 2024,
  "publisher": "dl.acm.org",
  "snippet": "… 3.1 Natural Language Processing Tasks … the development of language models, particularly large language models, was to enhance performance on natural language processing tasks, …",
  "citedByCount": 6830,
  "citedByUrl": "https://scholar.google.com/scholar?cites=3625720365842685347&as_sdt=2005&sciodt=0,5&hl=en",
  "citesId": "3625720365842685347",
  "versionsCount": 11,
  "totalResults": 6560000
}
```

(authors list shortened here; the run returned all five linked authors.)

An author profile row collected on 2026-10-21 (`DhtAFkwAAAAJ`, run with `maxArticlesPerAuthor: 0`, citations per year shortened):

```json
{
  "type": "author",
  "name": "Kaiming He",
  "affiliation": "Associate Professor, EECS, MIT",
  "verifiedEmailDomain": "mit.edu",
  "interests": ["Computer Vision", "Machine Learning"],
  "citationsAll": 888846,
  "citationsSince": 701747,
  "hIndexAll": 78,
  "hIndexSince": 74,
  "i10IndexAll": 95,
  "i10IndexSince": 94,
  "sinceYear": 2021,
  "citationsPerYear": { "2023": 125281, "2024": 130814, "2025": 132234, "2026": 100851 },
  "articlesCount": 0
}
```

### What you can do with it

- **Literature reviews and systematic reviews:** every paper for a query and year range, with PDF links and citation counts, ready for a spreadsheet.
- **Citation analysis:** who cites a paper (`citedBy`), how citations grow year by year, which versions exist.
- **Researcher and lab profiling:** h-index, i10-index, citations, interests, affiliation and co-authors for a list of profiles, for hiring, grants, rankings or partnerships.
- **Research monitoring:** new papers on a topic (`sortBy: date`) or new citations of your own work.
- **Datasets for AI and bibliometrics:** titles, snippets, venues and author ids across thousands of papers.

### Google Scholar search scraper (papers by keyword)

`searchQueries` takes anything you would type in Scholar, including `"exact phrase"`, `author:"lecun"`, `source:nature` and `intitle:`. Filter with `yearFrom`/`yearTo`, sort by `relevance` or `date`, and skip `[CITATION]` entries with `excludeCitations`. Google Scholar shows up to 1,000 results per query; the Actor pages through them 10 at a time.

### Google Scholar author profile scraper (h-index, citations)

`authorProfiles` takes profile ids (`DhtAFkwAAAAJ`) or `scholar.google.com/citations?user=` links. You get one `author` row plus one `result` row per article (title, authors, venue, year, cited-by count and link), read 100 per page up to `maxArticlesPerAuthor`.

### Google Scholar "Cited by" scraper

`citedBy` takes the `citesId` of any result (the number after `cites=`) or the whole "Cited by" link, and returns the papers that cite it, with the same fields as a search result.

### Input

| Field | What it does |
|---|---|
| `searchQueries` | Keywords or full Scholar search links |
| `authorProfiles` | Profile ids or profile links |
| `citedBy` | `cites=` ids or "Cited by" links |
| `maxResultsPerQuery` | Default 50, per query or cited-by list (max 1,000) |
| `maxArticlesPerAuthor` | Default 100; 0 returns only the profile row |
| `yearFrom`, `yearTo` | Publication year range (search and cited-by) |
| `sortBy` | `relevance` (default) or `date` |
| `excludeCitations` | Skip `[CITATION]` entries |

```json
{
  "searchQueries": ["crispr gene editing"],
  "authorProfiles": ["DhtAFkwAAAAJ"],
  "citedBy": ["3625720365842685347"],
  "maxResultsPerQuery": 200,
  "yearFrom": 2020
}
```

### Output fields

Results (`type: "result"`): `source`, `position`, `title`, `url`, `pdfUrl`, `fullTextUrl`, `resultType` (`article`, `book`, `citation`, `pdf`, `html`), `authors` (name, `profileId`, `profileUrl`), `authorsLine`, `publication`, `year`, `publisher`, `snippet`, `citedByCount`, `citedByUrl`, `citesId`, `clusterId`, `resultId`, `versionsCount`, `versionsUrl`, `relatedUrl`, `totalResults`. Profile articles also carry `citationId`, `authorProfileId` and `authorName`.

Profiles (`type: "author"`): `profileId`, `url`, `name`, `affiliation`, `organizationId`, `verifiedEmailDomain`, `homepage`, `interests`, `photoUrl`, `citationsAll`, `citationsSince`, `hIndexAll`, `hIndexSince`, `i10IndexAll`, `i10IndexSince`, `sinceYear`, `citationsPerYear`, `coAuthors`, `articlesCount`.

Math in titles comes as LaTeX between `$` signs, as Scholar stores it (for example `$\pi_0$`).

#### Error codes (never charged)

| errorCode | Meaning |
|---|---|
| `NO_RESULTS` | Google Scholar returned nothing for this search or cited-by id |
| `NOT_FOUND` | The profile does not exist or is not public |
| `INVALID_INPUT` | A value the Actor does not understand |
| `LOGIN_REQUIRED` | The page asks for login (Scholar's author search by name does); use a profile id |
| `BLOCKED` | Google Scholar showed a captcha on several IPs in a row; run again |
| `NOT_REACHED`, `UNEXPECTED` | The run timeout arrived, or something unforeseen broke; only that input is lost |

### Pricing

| Event | Per 1,000 |
|---|---|
| Result delivered (search, cited-by or profile article) | US$ 9 |
| Author profile delivered | US$ 9 |

1,000 papers cost US$ 9. A profile with 100 articles costs US$ 0.909. Duplicates and error rows are free, and there is no Apify compute bill on top.

### FAQ

**Why not an official Google Scholar API?** There is none. Google has never offered a public Google Scholar API, so every tool reads the public pages; this one does it without login and without a paid SERP API in between.

**What about captchas?** When Scholar shows a captcha, the Actor retries by itself; only if every retry fails does the query become a free `BLOCKED` row. It never solves or bypasses captchas.

**Can I search authors by name?** Google Scholar requires login for its author search, so the Actor takes profile ids or links. Search results already include the profile id of every linked author.

### Limitations

- Google Scholar caps each query at 1,000 results; split big topics by year range.
- Sorting by date only covers roughly the last year (Scholar's own rule).
- Author names in search results are abbreviated as Scholar shows them (`Y Chang`); the profile id links to the full profile.
- Only public data. This Actor reads public pages only and respects the site's terms.

### Changelog

- **2026-09-30, 0.1:** first release. Keyword search with year filters, author profiles with metrics and all articles, cited-by lists, free error rows.

# Actor input Schema

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

Queries as you would type them in Google Scholar, one per line, for example large language models. Operators work: "exact phrase", author:"lecun", source:nature, intitle:transformer. You can also paste a full scholar.google.com/scholar?... link to keep its filters. Each result row has title, authors, venue, year, snippet, citation count, PDF link and citesId, charged as 'Result delivered'.

## `authorProfiles` (type: `array`):

Google Scholar author profiles, one per line: the profile id (DhtAFkwAAAAJ) or a link like https://scholar.google.com/citations?user=DhtAFkwAAAAJ. Returns one profile row (affiliation, interests, citations, h-index, i10-index, citations per year, co-authors), charged as 'Author profile delivered', plus one row per article.

## `citedBy` (type: `array`):

Papers whose citing papers you want, one per line: the number after cites= in a "Cited by" link (every search result has it in 'citesId'), or the whole link. Returns the papers that cite it, one row each, charged as results.

## `maxResultsPerQuery` (type: `integer`):

Maximum results for each query and each cited-by list, from 1 to 1,000 (default 50). Google Scholar shows up to 1,000 results (100 pages of 10) per query. You pay per result delivered, so this caps the cost of each query.

## `maxArticlesPerAuthor` (type: `integer`):

Maximum articles for each author profile, default 100. Articles are read 100 per page. Set 0 to get only the profile row, without articles.

## `yearFrom` (type: `integer`):

Only results published in or after this year, for example 2020. Applies to searches and cited-by lists. Empty = any year.

## `yearTo` (type: `integer`):

Only results published in or before this year, for example 2024. Applies to searches and cited-by lists. Empty = any year.

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

Relevance (default) or Date, newest first. Google Scholar only sorts by date within the last year, so Date returns recent papers only.

## `excludeCitations` (type: `boolean`):

Off (default). On: skip \[CITATION] entries, which Google Scholar only knows from other papers' references (no full text or link). Skipped entries are not charged.

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

Apify Proxy is the default and recommended. When Google Scholar shows a captcha, the Actor retries on its own, with no extra charge; it never solves captchas. Change it only to use your own proxies.

## Actor input object example

```json
{
  "searchQueries": [
    "large language models"
  ],
  "maxResultsPerQuery": 50,
  "maxArticlesPerAuthor": 100,
  "sortBy": "relevance",
  "excludeCitations": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

No description

## `resultsCsv` (type: `string`):

No description

# 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": [
        "large language models"
    ],
    "maxResultsPerQuery": 50,
    "maxArticlesPerAuthor": 100,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapewise/google-scholar-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": ["large language models"],
    "maxResultsPerQuery": 50,
    "maxArticlesPerAuthor": 100,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("scrapewise/google-scholar-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 '{
  "searchQueries": [
    "large language models"
  ],
  "maxResultsPerQuery": 50,
  "maxArticlesPerAuthor": 100,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call scrapewise/google-scholar-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapewise/google-scholar-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/gJ9GS1uYFwVzre1I2/builds/8ENTxNdS8mBdIiTzp/openapi.json
