This guide shows you how to automate the export of research metadata (titles, authors, abstracts, DOI, publication dates) using a scholarly search API like Crossref, OpenAlex, or Semantic Scholar. You’ll learn to write a script that queries the API, parses the JSON response, and saves clean metadata to a CSV or Excel file—saving hours of manual copy-paste. No prior coding experience is needed beyond basic Python and a willingness to follow steps.
What You’ll Need
- Python 3.7+ installed on your computer
- A code editor (VS Code, PyCharm, or even Notepad)
- An internet connection
- Optional: A free API key from Crossref (not required but increases rate limits)
- Basic familiarity with the command line/terminal
Step-by-Step
- Choose your scholarly API. For general metadata, Crossref (api.crossref.org) is free and doesn’t require a key. OpenAlex (api.openalex.org) is also free and provides more detailed metadata. Semantic Scholar requires a key for higher limits. This guide uses Crossref as the example, but the pattern works for others.
- Install the required Python libraries. Open your terminal and run:
pip install requests pandas. Therequestslibrary handles API calls, andpandashelps with data export. - Set up your script file. Create a new Python file, e.g.,
export_metadata.py. Start with imports:import requests, pandas as pd, time. - Define your search query. Decide what you’re searching for. For example, if you want all articles with “machine learning” in the title published in 2023, you’d use a query string like
query.title=machine+learning&filter=from-pub-date:2023-01-01,until-pub-date:2023-12-31. The Crossref API uses URL parameters, not JSON bodies. - Make the API request. Use
requests.get()with the base URL and your query. For Crossref:url = "https://api.crossref.org/works?" + query. Add a mailto parameter to be polite:&mailto=your@email.com. - Parse the JSON response. The API returns a JSON object. Access the items with
data["message"]["items"]. Each item contains fields liketitle(a list),author(a list of dicts),DOI,published-printorpublished-online. - Extract the metadata you need. Write a loop that goes through each item and pulls out the fields you want. For example:
records = [] for item in items: title = item.get("title", [""])[0] authors = "; ".join([f"{a.get('given','')} {a.get('family','')}" for a in item.get("author", [])]) doi = item.get("DOI", "") year = item.get("published-print", {}).get("date-parts", [[""]])[0][0] records.append({"Title": title, "Authors": authors, "DOI": doi, "Year": year}) - Convert to a DataFrame. After the loop, create a pandas DataFrame:
df = pd.DataFrame(records). - Export to CSV or Excel. Use
df.to_csv("metadata.csv", index=False)ordf.to_excel("metadata.xlsx", index=False). Theindex=Falseprevents an extra row number column. - Handle pagination. The API returns a limited number of results per request (default 20). To get all results, loop through pages by incrementing the
offsetparameter (orcursorfor Crossref) until you have all records. Add atime.sleep(1)between requests to respect rate limits. - Run the script. Execute it with
python export_metadata.py. Check the output file to ensure it contains the expected metadata. - Automate the script. To run it on a schedule, use your operating system’s task scheduler (Task Scheduler on Windows, cron on macOS/Linux). For example, a cron job:
0 9 * * 1 python /path/to/export_metadata.pyruns it every Monday at 9 AM.
Common Mistakes
- Not URL-encoding the query. Spaces and special characters must be encoded (e.g., use
%20or+for spaces). Userequests.utils.quote()or theparamsargument inrequests.get()to handle this automatically. - Assuming field names are consistent. Crossref returns some fields as lists (e.g.,
titleis a list even for one title). Always check the structure. - Ignoring rate limits. Sending too many requests quickly can get your IP temporarily blocked. Always add a small delay between requests.
- Forgetting to handle missing data. Not all records have all fields. Use
.get()with default values to avoid KeyErrors. - Not checking the HTTP status code. A 404 or 403 means your request failed. Always check
response.status_codebefore parsing.
Tips
- Use the API’s filter parameters. They reduce the amount of data you need to process. For example, filter by type:
filter=type:journal-article. - Test with a small query first. Start with a narrow query and print the first few records to verify the parsing logic.
- Save the raw JSON. If you need to re-run without hitting the API, save the response to a file and read from it.
- Use a virtual environment. This keeps your dependencies isolated and avoids version conflicts.
- Consider using the
habanerolibrary. It’s a Python wrapper for Crossref that simplifies some steps, but the raw approach gives you more control.
Troubleshooting
- I get a 401 Unauthorized error. If you’re using an API key, check that it’s correctly set in the headers. For Crossref, you don’t need a key, but if you’re using Semantic Scholar, make sure the key is included as
Authorization: Bearer YOUR_KEY. - The script runs but the CSV is empty. Check the JSON response. Print
data["message"]["total-results"]to see if there are results. If total is 0, your query may be too restrictive. - I get a KeyError for ‘author’. Some records don’t have an author field. Use
item.get("author", [])to return an empty list instead. - The script times out. Increase the timeout in
requests.get()(e.g.,timeout=30). Also check your internet connection. - I need more than 1000 results. Crossref has a maximum of 1000 results per query. You’ll need to split your query by date range or use the
cursorparameter for deep pagination. - My output file has weird characters. Ensure you specify the correct encoding when writing:
df.to_csv("metadata.csv", index=False, encoding="utf-8").
Frequently Asked Questions
Do I need an API key for Crossref?
No, Crossref is free and open. Adding a mailto parameter is polite and helps them contact you if needed.
Can I use this with other APIs like Scopus or Web of Science?
Yes, but those require institutional access and API keys. The pattern is the same: construct a query, get JSON, parse, export.
How do I get the full abstract?
Crossref often includes abstracts, but they may be in JATS XML format. You’ll need to strip HTML tags. OpenAlex provides plain-text abstracts more easily.
What if I want to export metadata for a specific journal?
Use the container-title filter in Crossref. For example: filter=container-title:Nature.
Can I schedule this to run automatically?
Yes, use cron (macOS/Linux) or Task Scheduler (Windows). You can also run it as a GitHub Action if you prefer cloud-based automation.
How do I handle large numbers of results without hitting rate limits?
Use the cursor parameter in Crossref for deep pagination, and add a delay of 1-2 seconds between requests. Also, consider using the rows parameter to increase results per request (max 1000).
Related
Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.
More cards in this drawer
- Campus Tech Innovation Hubs: What They Are
- Poco C51 Airtel Prepaid Locked Variant India?
- Jenkins vs GitHub Actions: Which CI/CD Fits Your Team?
- Turn Off Backup Encryption in iTunes?
- Shared VPS Hosting: Is It Better?
- Disk Defrag Pro: What It Does and Whether You Need It