DOI to BibTeX

Posted on 03 April 2017

The Digital Object Identifier (DOI) resolution service at doi.org exposes an API for retrieving the BibTeX markup for a reference given its DOI. The following Python 3 script takes a DOI on the command line and returns the BibTeX. For example,

$ python doi2bib.py 10.1177/1470593113512323

@article{Avis_2013,
    doi = {10.1177/1470593113512323},
    url = {https://doi.org/10.1177%2F1470593113512323},
    year = 2013,
    month = {dec},
    publisher = {{SAGE} Publications},
    volume = {14},
    number = {4},
    pages = {451--475},
    author = {M. Avis and S. Forbes and S. Ferguson},
    title = {The brand personality of rocks: A critical evaluation of a brand personality scale},
    journal = {Marketing Theory}
}

The code is below. Update 23/1/2024: to add line-endings after each BibTeX field you can pass the string returned from doi.org through the bibtexparser package (this must be installed)

import sys
import urllib.request
import bibtexparser
from urllib.error import HTTPError

BASE_URL = 'http://dx.doi.org/'

try:
    doi = sys.argv[1]
except IndexError:
    print('Usage:\n{} <doi>'.format(sys.argv[0]))
    sys.exit(1)

url = BASE_URL + doi
req = urllib.request.Request(url)
req.add_header('Accept', 'application/x-bibtex')
try:
    with urllib.request.urlopen(req) as f:
        bibtex = f.read().decode()
        # The round-trip through bibtexparser adds line endings.
        bibtex = bibtexparser.loads(bibtex)
        bibtex = bibtexparser.dumps(bibtex)
    print(bibtex)
except HTTPError as e:
    if e.code == 404:
        print('DOI not found.')
    else:
        print('Service unavailable.')
    sys.exit(1)