Tutorials13 min read

Google Scholar API for Python — Complete Tutorial (2026)

Step-by-step Google Scholar API Python tutorial. Install, authenticate, search papers, handle pagination and errors, and build a reusable client class with BitLore.

B
BitLore Team
7/21/2026

What You'll Build

By the end of this tutorial you'll have a reusable Python client for the Google Scholar API, with search, pagination, error handling, and typed result parsing — ready to drop into a research app, dashboard, or AI pipeline.

We use BitLore because there is no official Google Scholar API from Google. BitLore returns structured JSON in under 100ms.

Prerequisites

Python 3.9+
pip install requests python-dotenv
A BitLore API key from the dashboard

Step 1: Store Your API Key Securely

Create a .env file (never commit this to git):

.env
BITLORE_API_KEY=your_api_key_here

Step 2: Build a Scholar Client Class

scholar_client.py
import os
import requests
from dataclasses import dataclass
from typing import Optional
from dotenv import load_dotenv

load_dotenv()

@dataclass
class ScholarPaper:
    title: str
    link: str
    snippet: str
    authors: Optional[str] = None
    cited_by: Optional[int] = None

class BitLoreScholarClient:
    BASE_URL = "https://api.bitlore.in/search"

    def __init__(self, api_key: Optional[str] = None):
        self.api_key = api_key or os.environ["BITLORE_API_KEY"]

    def search(
        self,
        query: str,
        page: int = 1,
        timeout: int = 30,
    ) -> list[ScholarPaper]:
        resp = requests.get(
            self.BASE_URL,
            params={
                "search_engine": "google_scholar",
                "q": query,
                "page": page,
                "api_key": self.api_key,
            },
            timeout=timeout,
        )
        resp.raise_for_status()
        payload = resp.json()

        papers = []
        for item in payload.get("data", {}).get("results", []):
            papers.append(ScholarPaper(
                title=item.get("title", ""),
                link=item.get("link", ""),
                snippet=item.get("snippet", ""),
                authors=item.get("authors"),
                cited_by=item.get("cited_by"),
            ))
        return papers

Step 3: Run Your First Search

main.py
from scholar_client import BitLoreScholarClient

client = BitLoreScholarClient()
papers = client.search("large language models")

for i, paper in enumerate(papers, 1):
    print(f"{i}. {paper.title}")
    print(f"   {paper.link}\n")

Step 4: Handle Errors Gracefully

Python
import requests

def safe_search(client, query: str, retries: int = 3):
    for attempt in range(retries):
        try:
            return client.search(query)
        except requests.HTTPError as e:
            if e.response.status_code == 429:
                wait = 2 ** attempt
                print(f"Rate limited. Retrying in {wait}s...")
                time.sleep(wait)
            elif e.response.status_code == 401:
                raise ValueError("Invalid API key") from e
            else:
                raise
    return []

Step 5: Paginate Through Results

Python
def search_all_pages(client, query: str, max_pages: int = 10):
    all_papers = []
    for page in range(1, max_pages + 1):
        batch = client.search(query, page=page)
        if not batch:
            break
        all_papers.extend(batch)
    return all_papers

Response Fields Reference

Each result typically includes:

title — paper or article title
link — URL to the Scholar result
snippet — abstract excerpt or description
authors — author list when available
cited_by — citation count when available

See the full field reference in our API docs.

Async Version (FastAPI / asyncio)

Python (httpx)
import httpx

async def search_scholar_async(query: str, api_key: str) -> dict:
    async with httpx.AsyncClient() as client:
        r = await client.get(
            "https://api.bitlore.in/search",
            params={
                "search_engine": "google_scholar",
                "q": query,
                "api_key": api_key,
            },
        )
        r.raise_for_status()
        return r.json()

What's Next?

Combine this client with:

Tags

Google Scholar APIPythonAPI TutorialAcademic SearchREST API

About the Author

B

BitLore Team

API Expert

Share this article