PDF Text & Table Extractor (pdfplumber, batch URLs) avatar

PDF Text & Table Extractor (pdfplumber, batch URLs)

Pricing

from $20.00 / 1,000 pdf extracteds

Go to Apify Store
PDF Text & Table Extractor (pdfplumber, batch URLs)

PDF Text & Table Extractor (pdfplumber, batch URLs)

Download any PDF by URL and extract clean per-page text + detected tables (as 2D arrays) + document metadata (title/author/created/modified). Powered by pdfplumber. Batch up to 50 PDFs. $0.01 per PDF + $0.0005 per page.

Pricing

from $20.00 / 1,000 pdf extracteds

Rating

0.0

(0)

Developer

Hojun Lee

Hojun Lee

Maintained by Community

Actor stats

0

Bookmarked

212

Total users

43

Monthly active users

3 days ago

Last modified

Share

PDF Text Extractor — PDF to Text, PDF Scraper, RAG Chunks, OCR, Tables

Extract text from PDF files via API in seconds. Returns structured Markdown, RAG chunks, tables, and metadata — batch mode, Google Drive / Dropbox / SharePoint auto-resolved, OCR for scanned PDFs. PDF text extractor and PDF parser built for LangChain, LlamaIndex, Pinecone, Weaviate, Chroma. No API key. $0.025/PDF + $0.002/page.

⭐ If this saves you time, a quick review on the Store page helps others find it.


⚡ Run in 30 seconds

Paste any PDF URL — direct links, Google Drive, or Dropbox — and click Start:

# Direct PDF URL
https://www.irs.gov/pub/irs-pdf/f1040.pdf
# Google Drive share link (auto-resolved)
https://drive.google.com/file/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms/view
# Dropbox share link (auto-resolved)
https://www.dropbox.com/s/abc123/report.pdf?dl=0
# SharePoint / OneDrive share link (auto-resolved)
https://company.sharepoint.com/:b:/s/team/EaBcD...view.aspx

Default output is rich Markdown — headings, lists, tables, code blocks auto-detected. Switch to rag_chunks mode to get overlapping text windows ready to embed into Pinecone, Weaviate, Chroma, Qdrant, or any vector DB.


Price comparison vs other Apify PDF actors

ActorStart feePer pageOCR pageRAG chunksTables
This actor$0.001$0.001included✅✅
memo23/pdf-text-extractor$0.005$0.005$0.015❌❌
yabanana99/pdf-word-excel-to-markdown$0.005$0.004$0.012❌❌

Up to 15× cheaper per page, with more features.


Why this PDF scraper?

Free PDF extractors give you raw text dumps. This actor goes further:

FeatureFree alternativesThis actor
RAG chunks (configurable overlap)❌✅
SharePoint / OneDrive URL resolution❌✅
Table extraction (2D arrays)❌✅
PDF type classification (text vs scanned)❌✅
Password-protected PDFs❌✅
Auto-OCR for scanned pagesPartial✅ Full
Skip empty pages option❌✅
Batch 50 PDFs in one runPartial✅
Page range selection❌✅
Webhook / Telegram alerts❌✅

Quick start (Python API)

from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
# Extract text from a single PDF
run = client.actor("gochujang/pdf-text-extractor").call(run_input={
"url": "https://www.sec.gov/Archives/edgar/data/320193/aapl-10k.pdf",
"outputFormat": "markdown",
})
items = list(client.dataset(run["defaultDatasetId"]).iterate_items())
markdown_doc = next(i for i in items if i["_type"] == "markdown")
print(markdown_doc["markdown"][:500])
# Batch: extract tables from 10 SEC filings at once
run = client.actor("gochujang/pdf-text-extractor").call(run_input={
"urls": [
"https://www.sec.gov/Archives/edgar/data/320193/aapl-10k.pdf",
"https://www.sec.gov/Archives/edgar/data/789019/msft-10k.pdf",
],
"extractTables": True,
"outputFormat": "per_page",
"maxPages": 200,
})
pages = list(client.dataset(run["defaultDatasetId"]).iterate_items())
# RAG pipeline: extract + chunk + embed
run = client.actor("gochujang/pdf-text-extractor").call(run_input={
"url": "https://example.com/whitepaper.pdf",
"outputFormat": "rag_chunks",
"chunkSize": 1000,
"chunkOverlap": 200,
})
chunks = [i for i in client.dataset(run["defaultDatasetId"]).iterate_items()
if i["_type"] == "chunk"]
# chunks are ready to embed into Pinecone/Weaviate/Chroma

Use cases

  1. AI / LLM pipelines — Convert PDF to text for ChatGPT, Claude, Gemini, or RAG vector search. One call returns clean chunks ready for embedding.
  2. SEC filings — Pull text + tables from 10-K, 10-Q, 8-K in batch. Combine with our SEC EDGAR Tracker.
  3. Research aggregation — Build a searchable database of academic papers + abstracts from arXiv or PubMed PDFs.
  4. Financial reports — Auto-extract earnings tables from quarterly releases; pipe into spreadsheets or databases.
  5. Legal documents — Contracts, court filings, regulatory submissions — extract and index at scale.
  6. Invoice & receipt parsing — Extract line items and totals from PDF invoices without manual data entry.
  7. Government records — FOIA responses, regulatory filings, public data PDFs — download and parse in bulk.
  8. Scanned document digitization — Bank statements, old reports, image PDFs via OCR. Enable enableOcr and get text even from image-only PDFs.
  9. Compliance audit — Index every PDF in your corporate document store; feed into your search or compliance tools.

What you get

Summary row (one per PDF)

{
"_type": "summary",
"url": "https://www.sec.gov/Archives/.../aapl-10k.pdf",
"ok": true,
"page_count": 80,
"pages_extracted": 80,
"title": "Apple Inc. — Annual Report 2024",
"author": "Apple Inc.",
"created": "D:20240928081300Z",
"text_preview": "UNITED STATES SECURITIES AND EXCHANGE COMMISSION...",
"file_size_kb": 4820
}

Per-page row

{
"_type": "page",
"url": "https://...",
"page": 12,
"page_count": 80,
"char_count": 3210,
"word_count": 524,
"text": "Item 1A. Risk Factors\n\nOur business...",
"tables": [
[
["Revenue", "Q1 2024", "Q4 2023"],
["iPhone", "$45.96B", "$43.81B"],
["Mac", "$9.66B", "$7.61B"]
]
],
"table_count": 1,
"ocr_applied": false
}

Input Parameters

ParameterTypeDefaultDescription
urlsarray—List of PDF URLs to extract (batch mode)
urlsTextstring—Paste multiple PDF URLs, one per line — merged with urls
urlstring—Single PDF URL (used when urls is empty)
changeDetectionbooleanfalseHash each PDF's text and compare to the previous run — adds changed + content_hash to every record. Ideal for scheduled monitoring
webhookUrlstring—POST a JSON alert to this URL when a PDF changes (requires changeDetection=true). Works with Slack, Discord, Make, Zapier, n8n
changedOnlybooleanfalseOnly output records for PDFs that changed (requires changeDetection=true). Scheduled runs produce zero records when nothing changed
outputFormatstringmarkdownmarkdown (LLM-ready), per_page, combined, both, or rag_chunks
extractTablesbooleanfalseDetect and extract tables as 2D arrays
extractImagesbooleanfalseAdd image_count field to each page
skipEmptyPagesbooleanfalseSkip pages with no extractable text (useful for scanned PDFs with mixed pages)
enableOcrbooleanfalseEnable OCR for scanned pages (pages with < 50 chars auto-detected)
ocrLanguagestringengTesseract language: eng, deu, fra, jpn, or combined eng+deu
startPageinteger1First page to extract (1-indexed)
endPageinteger—Last page to extract (inclusive)
maxPagesinteger100Max pages per PDF from startPage
passwordstring—Password for password-protected / encrypted PDFs
userAgentstring—Custom User-Agent for the HTTP request

Input examples

Single PDF

{
"url": "https://www.example.com/whitepaper.pdf"
}

Batch of 10-K filings from SEC

{
"urls": [
"https://www.sec.gov/Archives/edgar/data/320193/aapl-10k.pdf",
"https://www.sec.gov/Archives/edgar/data/789019/msft-10k.pdf"
],
"extractTables": true,
"maxPages": 200
}

Text-only (skip tables for speed)

{
"url": "https://...",
"extractTables": false
}

Skip blank/empty pages

{
"url": "https://example.com/mixed-scanned.pdf",
"skipEmptyPages": true,
"enableOcr": true
}

Monitor PDF Changes Automatically

Turn this actor into a zero-maintenance document monitor in three steps:

  1. Enable changeDetection: true
  2. Set webhookUrl to your Slack / Make / Zapier / n8n webhook
  3. Schedule to run daily at 8am

You get notified the moment your document updates — and zero records when nothing changed.

{
"urls": ["https://example.com/policy.pdf"],
"changeDetection": true,
"changedOnly": true,
"webhookUrl": "https://hooks.slack.com/services/T.../B.../..."
}

Scheduling & change detection (monitor a PDF for updates)

Set changeDetection: true to turn this actor into a document monitor. On every run it hashes the extracted text of each PDF, stores the hash in the Actor's Key-Value Store, and compares it against the previous run. Every output record gains two fields:

  • changed — true if the PDF's text differs from the last run, false if identical, null if detection is disabled or the fetch failed. The first run is always changed: true (no prior hash to compare).
  • content_hash — the MD5 of the extracted text, so you can diff or dedupe downstream.

This lets you schedule the actor (e.g. weekly) and only act when something actually changes — trigger a webhook, re-index a vector store, or send an alert.

Example: monitor a regulatory PDF weekly

{
"urls": [
"https://www.sec.gov/files/rules/final/2024/33-11275.pdf"
],
"changeDetection": true,
"outputFormat": "markdown"
}

Then schedule it with a weekly cron (0 9 * * 1). Downstream, only react to records where changed is true:

from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("gochujang/pdf-text-extractor").call(run_input={
"urls": ["https://www.sec.gov/files/rules/final/2024/33-11275.pdf"],
"changeDetection": True,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
if item.get("_type") == "summary" and item.get("changed"):
print(f"PDF changed! {item['url']} (hash {item['content_hash'][:8]})")
# → fire your webhook / re-embed / notify here

Change detection persists hashes in the Actor's named Key-Value Store, keyed per URL. Runs of the same actor share that store, so scheduled runs compare against each other automatically — no extra setup.


Webhook alerts (Slack / Discord / Make / Zapier / n8n)

Add webhookUrl to get an instant HTTP notification whenever a PDF changes. Works with any service that accepts POST JSON.

{
"urls": ["https://www.sec.gov/files/rules/final/2024/33-11275.pdf"],
"changeDetection": true,
"webhookUrl": "https://hooks.slack.com/services/T.../B.../...",
"changedOnly": true
}

Webhook payload (POST, application/json):

{
"event": "pdf_changed",
"url": "https://www.sec.gov/files/rules/final/2024/33-11275.pdf",
"content_hash": "a3f8c2...",
"page_count": 42,
"word_count": 18340,
"title": "Final Rule Release No. 33-11275",
"detected_at": "2024-10-15T09:00:12Z"
}

changedOnly mode

Set changedOnly: true (requires changeDetection: true) to suppress all output for unchanged PDFs. Your scheduled dataset is empty when nothing changed — no downstream filtering needed.

{
"urls": [
"https://example.com/report-q3.pdf",
"https://example.com/policy-v2.pdf"
],
"changeDetection": true,
"changedOnly": true,
"outputFormat": "markdown"
}

If neither PDF changed since the last run, the dataset is empty. Only the changed one produces records.


RAG-Ready Chunking (LangChain / LlamaIndex / Vector DB)

Use outputFormat: "rag_chunks" to get overlapping text chunks ready to embed into Pinecone, Weaviate, Chroma, Qdrant, or any vector database:

{
"url": "https://example.com/whitepaper.pdf",
"outputFormat": "rag_chunks",
"chunkSize": 1000,
"chunkOverlap": 200
}

Each chunk row includes context metadata for retrieval:

{
"_type": "chunk",
"chunk_index": 3,
"total_chunks": 47,
"text": "...overlapping window of text...",
"doc_title": "Whitepaper Title",
"doc_author": "Author Name",
"doc_page_count": 24,
"pdf_type": "text_based"
}

LangChain integration

from apify_client import ApifyClient
from langchain.schema import Document
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import Chroma
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("gochujang/pdf-text-extractor").call(run_input={
"urls": ["https://example.com/report.pdf"],
"outputFormat": "rag_chunks",
"chunkSize": 1000,
"chunkOverlap": 200,
})
chunks = list(client.dataset(run["defaultDatasetId"]).iterate_items())
docs = [Document(page_content=c["text"], metadata={"title": c["doc_title"], "chunk": c["chunk_index"]})
for c in chunks if c.get("_type") == "chunk"]
vectorstore = Chroma.from_documents(docs, OpenAIEmbeddings())

LlamaIndex integration

from apify_client import ApifyClient
from llama_index.core import VectorStoreIndex
from llama_index.core.schema import TextNode
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("gochujang/pdf-text-extractor").call(run_input={
"urls": ["https://example.com/report.pdf"],
"outputFormat": "rag_chunks",
})
chunks = list(client.dataset(run["defaultDatasetId"]).iterate_items())
nodes = [TextNode(text=c["text"], metadata={"title": c.get("doc_title",""), "chunk_index": c.get("chunk_index",0)})
for c in chunks if c.get("_type") == "chunk"]
index = VectorStoreIndex(nodes)
query_engine = index.as_query_engine()

No post-processing needed — chunks are word-boundary aligned, non-empty, and sized for typical embedding models (512–2048 tokens).


OCR for Scanned PDFs

Enable enableOcr: true to handle scanned or image-based PDFs (bank statements, legal filings, old reports). The actor automatically detects pages with little extractable text and falls back to Tesseract OCR.

{
"url": "https://example.com/scanned-report.pdf",
"enableOcr": true,
"ocrLanguage": "eng"
}

Each page row includes "ocr_applied": true when OCR was used, so you can distinguish native-text pages from OCR-processed ones.

Supported languages: eng (English), deu (German), fra (French), spa (Spanish), jpn (Japanese), and all Tesseract languages. Multi-language: "eng+deu".


Pricing

Pay-Per-Event — only pay for what you extract:

  • $0.025 — per PDF (download + parse + metadata)
  • $0.002 — per page extracted (native text)
  • $0.006 — per OCR page (scanned PDFs)
  • $0.003 — per RAG chunk generated (rag_chunks mode)
RunCost
One 80-page 10-K (native text)$0.185
Batch of 10 research papers (20 pages avg)$0.65
20-page scanned PDF with OCR$0.145
50-page doc → RAG chunks (1000 chars, ~62 chunks)$0.211
Quarterly: 50 earnings releases (15 pages avg)$2.75

Vs Adobe Acrobat Pro DC ($23/mo), Unstructured.io ($99/mo API), or DocParser ($199/mo) — significantly cheaper for dev/batch workloads.


FAQ

Does it support password-protected PDFs? Yes. Set the password input field to unlock them. Wrong password returns a clear error.

What is the maximum PDF file size? 50 MB by default. You can raise this up to 500 MB via the maxPdfMb input parameter.

Can it handle scanned PDFs (image-only)? Yes — enable enableOcr: true. Tesseract OCR is built in, supporting 100+ languages. OCR pages are charged at $0.006/page.

Does it extract tables? Yes. Set extractTables: true to get tables as 2D arrays (rows × columns) per page. Tables are also rendered as Markdown tables in markdown output mode.

Can I extract only specific pages? Yes — use startPage / endPage for a fixed range, or maxPages to cap the total. All are 1-indexed.

What PDF sources are supported? Direct PDF URLs, Google Drive share links, Dropbox links, SharePoint / OneDrive links — all auto-resolved. Any publicly accessible PDF URL works.

How do I skip pages with no text? Set skipEmptyPages: true. Useful for mixed PDFs where some pages are blank or image-only.

Is it safe to use for confidential PDFs? Apify runs in isolated containers. PDFs are downloaded to memory, processed, and discarded after the run — they are not stored persistently.


Data engine

  • pdf-inspector (Rust) — blazing fast (~150ms), smart layout detection, Markdown output
  • pdfplumber v0.11+ — Pure-Python fallback for complex layouts, table extraction
  • Tesseract OCR — built-in fallback for scanned/image PDFs, 100+ languages supported

Works great with

Building a document pipeline? These actors work alongside this one:



Feedback

A short review helps researchers / analysts find it: Leave a review on Apify Store

Keywords: PDF extractor, PDF parser, PDF to text, PDF to markdown, RAG, table extraction, PDF scraper, document processing, OCR