Europe PMC Scraper: Life-Science Literature & Full Text avatar

Europe PMC Scraper: Life-Science Literature & Full Text

Pricing

from $0.37 / 1,000 article scrapeds

Go to Apify Store
Europe PMC Scraper: Life-Science Literature & Full Text

Europe PMC Scraper: Life-Science Literature & Full Text

Scrape Europe PMC: citations, abstracts and full text where open access, plus MeSH terms, grants and cited-by counts. Broader coverage than PubMed for European research.

Pricing

from $0.37 / 1,000 article scrapeds

Rating

0.0

(0)

Developer

Arman Hossain

Arman Hossain

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

0

Monthly active users

21 days ago

Last modified

Share

Europe PMC Scraper: Citations, abstracts, MeSH terms, funder grants and open-access full text, Europe PMC's own query syntax passed through untouched

Europe PMC Scraper pulls biomedical literature out of Europe PMC, titles, authors, journals, abstracts, DOIs, PMIDs and PMCIDs, MeSH terms, funder grants, cited-by counts, and the complete open-access full text as clean plain text.

Europe PMC indexes everything PubMed does and more: preprints, patents, theses, agency reports, and the European funder record that PubMed does not carry. For anyone building a RAG corpus or running a systematic review. It is the better starting point, and unlike PubMed's E-utilities. It has no key, no email-in-the-URL requirement and no 3-requests-per-second ceiling.

Agent skill: SKILL.md

https://api.apify.com/v2/key-value-stores/t7YoTxpZEJOWvw4Ug/records/europe-pmc-scraper.md

What you get

Output fieldMeaning
id, sourceEurope PMC record ID and which index it came from (MED, PMC, PPR for preprints, PAT for patents…)
pmid, pmcid, doiThe three identifiers you join on. Any may be null, see the FAQ
title, authorStringArticle title (markup stripped) and the full author list as one string
journalTitle, journalIssnPublishing journal
pubYear, firstPublicationDatePublication year and exact first-publication date
abstractTextFull abstract as plain text, markup stripped (core only)
isOpenAccess, inEPMC, hasPdfReal booleans, converted from Europe PMC's "Y"/"N" strings
citedByCountCitations recorded by Europe PMC
grantsListFunder records: grantId, agency, acronym, the field PubMed does not give you
meshTermsMeSH descriptor names, e.g. ["Humans","Cardiovascular Diseases"]
fullTextUrlBest available link, open access preferred, DOI as fallback
fullTextUrlsEvery link Europe PMC knows, with its availability
europePmcUrlCanonical article page
fullText, fullTextCharsOnly when includeFullText is on, the article body as clean plain text
query, scrapedAtWhich query produced the row, and the run timestamp

A RUN_SUMMARY record in the key-value store holds per-run counts, the filters used, any query that failed, and how many articles actually yielded full text.

Common use cases

1. Build an open-access biomedical corpus for RAG. Open access on, full text on, core for the metadata that makes chunks citable.

{
"searchQueries": ["CRISPR gene editing"],
"resultType": "core",
"openAccessOnly": true,
"includeFullText": true,
"maxResults": 500
}

2. Grant and funding analysis. grantsList is the differentiator here, search by agency and get every funded paper with its grant IDs.

{
"searchQueries": [
"GRANT_AGENCY:\"Wellcome Trust\" AND PUB_YEAR:2025",
"GRANT_AGENCY:\"Gates Foundation\" AND PUB_YEAR:2025"
],
"resultType": "core",
"maxResults": 2000
}

3. Systematic reviews with full-text access. MeSH-scoped searching plus full text means screening on the body, not just the abstract.

{
"searchQueries": ["MESH:\"Neoplasms\" AND MESH:\"Immunotherapy\" AND PUB_YEAR:[2023 TO 2026]"],
"resultType": "core",
"openAccessOnly": true,
"includeFullText": true,
"maxResults": 1000
}

Quick start

Simplest possible run:

{
"searchQueries": ["long covid"]
}

Fast, lightweight sweep for change detection:

{
"searchQueries": ["long covid"],
"resultType": "lite",
"maxResults": 5000
}

Input

FieldTypeDefaultNotes
searchQueriesarray-Required. One search per entry. Plain words or Europe PMC field syntax. Each is paginated independently.
resultTypestringcorecore for abstracts, MeSH and grants; lite for identifiers and citation basics only. Both carry the PMCID.
openAccessOnlybooleanfalseAppends AND (OPEN_ACCESS:y) to every query.
includeFullTextbooleanfalseDownloads the JATS full text for every OA record with a PMCID and adds it as plain text.
maxResultsinteger200Total cap across all queries. 0 = no cap.

Which combinations make sense. includeFullText works with either resultType, lite returns the PMCID too, and pages 1,000 records at a time instead of 100, so it is the cheaper way to build a full-text corpus when you do not need the abstract and MeSH terms. includeFullText really wants openAccessOnly: true though: full text exists only for the OA subset, so without the filter most articles come back with fullText: null while you still pay for the row. Use lite when you are only diffing identifiers on a schedule. It is several times smaller on the wire.

Europe PMC query syntax

QueryFinds
long covidFree text across everything
TITLE:"gene therapy"Title match
AUTH:"Smith J"Author
JOURNAL:"Nature"Journal
PUB_YEAR:2025 or PUB_YEAR:[2023 TO 2026]Year, exact or range
MESH:"Neoplasms"MeSH term
GRANT_AGENCY:"Wellcome Trust"Funder
DOI:"10.1038/s41586-024-00001-0"Exact DOI lookup
SRC:PPRPreprints only
OPEN_ACCESS:yOpen-access subset (or just set openAccessOnly)
HAS_FT:yRecords with full text in Europe PMC

Combine with AND, OR, NOT and parentheses.

Output example

{
"query": "long covid",
"id": "42328279",
"source": "MED",
"pmid": "42328279",
"pmcid": "PMC13279208",
"doi": "10.1016/j.jhlto.2026.100600",
"title": "Long COVID sequelae in heart transplant recipients.",
"authorString": "Lees CR, Morad T, Webb M, Sim MS, Hsu JJ.",
"journalTitle": "JHLT open",
"journalIssn": "2950-1334",
"pubYear": "2026",
"firstPublicationDate": "2026-05-26",
"abstractText": "Post acute sequelae of SARS-CoV-2 infection (also known as Long COVID) have been defined as symptoms that persist after 3 months …",
"isOpenAccess": true,
"inEPMC": true,
"hasPdf": false,
"citedByCount": 0,
"grantsList": [
{ "grantId": "226350/Z/22/Z", "agency": "Wellcome Trust", "acronym": "WT" }
],
"meshTerms": ["Humans", "Post-Acute COVID-19 Syndrome", "Heart Transplantation"],
"fullTextUrl": "https://europepmc.org/articles/PMC13279208",
"fullTextUrls": [
{ "site": "DOI", "url": "https://doi.org/10.1016/j.jhlto.2026.100600", "availability": "Subscription required", "documentStyle": "doi" },
{ "site": "Europe_PMC", "url": "https://europepmc.org/articles/PMC13279208", "availability": "Open access", "documentStyle": "html" }
],
"europePmcUrl": "https://europepmc.org/article/MED/42328279",
"fullText": "The COVID-19 pandemic has resulted in nearly 800 million confirmed cases and over 7 million deaths globally since its emergence in late 2019. …",
"fullTextChars": 20665,
"scrapedAt": "2026-08-06T11:48:44.221Z"
}

RUN_SUMMARY:

{
"resultType": "core",
"queriesRequested": 1,
"queriesFailed": 0,
"failures": [],
"articlesSaved": 500,
"fullTextFetched": 431,
"filters": {
"searchQueries": ["CRISPR gene editing"],
"resultType": "core",
"openAccessOnly": true,
"includeFullText": true,
"maxResults": 500
},
"finishedAt": "2026-08-06T12:04:11.903Z"
}

Limits and behaviour

  • Pagination is cursor-based, and that matters. Europe PMC's page-number pagination breaks past 1,000 results; cursorMark does not. This Actor uses the cursor exclusively, carrying nextCursorMark forward and stopping when the API hands back the cursor it was given. Verified live walking six pages deep past the 1,000-record mark with no gap or repeat. There is no depth ceiling, so maxResults: 0 on a broad query really will try to fetch all 1,063,524 hits, set a cap you mean.
  • Full text is the OA subset only. Roughly a fifth of Europe PMC has open-access full text. Records without it get fullText: null and fullTextChars: 0; a missing full text is not counted as a failure, because it is the normal case. RUN_SUMMARY.fullTextFetched tells you how many actually came back with text.
  • Full text is cleaned, not raw. Europe PMC serves JATS XML. This Actor extracts <body>, drops references, figures, tables and formulae, they become unreadable once markup is stripped, then decodes entities and normalises whitespace. Text is capped at 500,000 characters per article, which no real article reaches.
  • Titles and abstracts are stripped of markup. Europe PMC returns structured abstracts headed with <h4>Background</h4> and chemistry titles containing <sub>/<sup>. Block tags become a space so sections do not fuse together, inline tags are removed outright so LaMn<sub>1</sub>O<sub>3</sub> stays LaMn1O3, and what you get is plain text a RAG chunker can ingest.
  • Entities are decoded twice. Europe PMC double-encodes some free-text fields, one grant agency arrives as US President&amp;apos;s Malaria Initiative, so decoding runs twice and you get US President's Malaria Initiative.
  • isOpenAccess is a real boolean. Europe PMC returns the string "Y". This Actor converts isOpenAccess, inEPMC and hasPdf to true/false so you can filter without string comparison.
  • A rejected query doesn't kill the run. Europe PMC reports bad queries as HTTP 200 with an errCode body rather than an error status; the Actor detects that, records the query in RUN_SUMMARY.failures, and continues. It only errors out if every query fails.
  • Partial results are kept. If a query fails on its fourth page, the 300 articles from pages 1-3 stay in the dataset and the failure is still reported.
  • Transient errors are retried. 429 and 5xx get three attempts with linear backoff.
  • Public data only. No authentication, no personal data, no access-control bypass.

API example

curl -X POST "https://api.apify.com/v2/acts/arman-bd~europe-pmc-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"searchQueries": ["GRANT_AGENCY:\"Wellcome Trust\" AND PUB_YEAR:2025"],
"resultType": "core",
"maxResults": 100
}'

JavaScript example

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('arman-bd/europe-pmc-scraper').call({
searchQueries: ['MESH:"Neoplasms" AND MESH:"Immunotherapy"'],
resultType: 'core',
openAccessOnly: true,
includeFullText: true,
maxResults: 200,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
const withText = items.filter((a) => a.fullTextChars > 0);
console.log(`${withText.length}/${items.length} articles have full text`);
for (const a of withText.slice(0, 5)) {
console.log(`${a.pmcid}, ${a.title} (${a.fullTextChars} chars)`);
}

FAQ

Do I need a proxy? No. Proxy configuration is not required to run this Actor.

Do I need an account or API key? No, unlike PubMed's E-utilities, Europe PMC asks for neither.

What happens if Europe PMC is unavailable? 429s and 5xx errors are retried with backoff. If a query still fails. It is recorded in RUN_SUMMARY.failures and the run continues with the remaining queries.

Can I schedule it? Yes. firstPublicationDate plus a diff on id gives a clean feed of what is new since the last run. resultType: "lite" makes those sweeps much cheaper to transfer.

Why is pmcid null on some records? Only articles deposited in PubMed Central have one. Subscription-only articles are indexed with a PMID and DOI but no PMCID, and therefore no full text.

Why is abstractText null? Either you used resultType: "lite", which omits it, or the record has no abstract (common for preprints, patents and correspondence).

Why did includeFullText give me mostly nulls? You almost certainly left openAccessOnly off. Full text exists only for the OA subset, turn the filter on and the hit rate jumps.

How does this differ from PubMed? Europe PMC is a superset: it mirrors all of MEDLINE and adds preprints, patents, agency reports, theses and the European funder record. grantsList and open-access full text are the two things you cannot get this cleanly from PubMed.

Can I get more than 1,000 results? Yes, that is exactly what the cursor pagination is for. Raise maxResults and it keeps going.

Can I integrate it with something else? Yes, Apify API, client libraries, webhooks, scheduled runs, dataset exports (JSON/CSV/Excel) or MCP. Output is structured JSON.