Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I'm searching for a full list of countries with their country codes.

Like on this page (need full and valid):



share|improve this question

7 Answers 7

up vote 13 down vote accepted

The ISO 3166-1 official site is probably the most updated source for the two-letter codes. Unfortunately, they don't have the alpha-3 online, quoting their site:

Where can I find the ISO 3166-1 alpha-3 country code for free download on the ISO 3166/MA Website?

Nowhere. The alpha-3 code is not made available free of charge. You can buy the International Standard ISO 3166-1 from our ISO Store. It contains the three-letter code.

A bit strange in the internet era, but luckily, there is a Wikipedia article with the full list and a UN official document that covers the subject, with country codes.


There's a list at the CIA site with FIPS 10, ISO 3166 Alpha2, ISO 3166 Alpha3, STANAG and Internet TLD (e.g, .il or .uk).

Link summary:

Note that these list contain non-country entities like Antartica.

share|improve this answer

If you want to periodically update your list, you could scrape one of the sources and parse its results into a useful format. I've done so here for converting the Wikipedia country code list into a CSV:

import csv
import urllib2
from BeautifulSoup import BeautifulSoup

opener = urllib2.build_opener()
opener.addheaders = [('User-agent', 'Mozilla/5.0')]

url = 'http://en.wikipedia.org/wiki/ISO_3166-1'

page = opener.open(url)
soup = BeautifulSoup(page.read())

t = soup.find('table', {'class' : 'wikitable sortable'})

# create a new CSV for the output
iso_csv = csv.writer(open('wikipedia-iso-country-codes.csv', 'w'))

# get the header rows, write to the CSV
iso_csv.writerow([th.findAll(text=True)[0] for th in t.findAll('th')])

# Iterate over the table pulling out the country table results. Skip the first 
# row as it contains the already-parsed header information.
for row in t.findAll("tr")[1:]:
    tds = row.findAll('td')
    raw_cols = [td.findAll(text=True) for td in tds]
    cols = []
    # country field contains differing numbers of elements, due to the flag -- 
    # only take the name
    # for all other columns, use the first result text
    cols.extend([col[0] for col in raw_cols[1:]])
share|improve this answer

You can find all (most?) of the two and three letter codes in http://download.geonames.org/export/dump/countryInfo.txt - it also has ISO numeric and fips codes and other country info.

share|improve this answer
This is a good format, but it's now outdated. It doesn't contain the codes for South Sudan and Kosovo. –  Matt Feb 22 '13 at 18:01

You may use this code https://classic.scraperwiki.com/scrapers/iso_3166-1/edit/ -- lxml is always faster than BeautifulSoup.

Copied it here:

import scraperwiki
import lxml.html
import urllib
import datetime
import json

from unidecode import unidecode

def get_html(title):
    raw_json = scraperwiki.scrape("http://en.wikipedia.org/w/api.php?action=parse&format=json&page=" + title)
    html = json.loads(raw_json)['parse']['text']['*']
    return html

page_title = "ISO_3166-1"

html = get_html(page_title)
doc = lxml.html.fromstring(html)

for count, tr in enumerate(doc.cssselect('tr')):
    row = [(td.text_content()) for td in tr.cssselect('td')]
    if len(row)==5:
        for ahref in tr.cssselect('a'):
            detailink = ahref.attrib['href']
            if detailink.find(':',0,len(detailink)) != -1:
                detailink = detailink[6:]
                print detailink
        now = datetime.datetime.now()
        data ={"tmsp_scraped":str(now), "eng_short_name":row[0], "alpha_2_code":row[1], "alpha_3_code":row[2], "numeric_code":row[3], "iso_31662_code":detailink}
        scraperwiki.sqlite.save(unique_keys=["eng_short_name"], data=data, table_name="s_iso31661")

        html = get_html(detailink)
        doc = lxml.html.fromstring(html)

        for count, tr in enumerate(doc.cssselect('tr')):
            row = [td.text_content() for td in tr.cssselect('td')]
            row2 = [td.text_content() for td in tr.cssselect('td')]
            if len(row)>0:
                if row[0][:2] == detailink[11:]:
                    now = datetime.datetime.now()
                    data = {"tmsp_scraped":str(now), "iso_31662_code":detailink, "region_code":row[0], "region_desc":row[1], "region_desc_utf8":row2[1]}
                    scraperwiki.sqlite.save(unique_keys=["iso_31662_code","region_code"], data=data, table_name="s_iso31662_region")

One more nice library: https://github.com/neuront/python-iso3166

share|improve this answer

I know, it is an old question but it came up pretty high on google.

I would like to add pycountry because you have a python tag and it seems to be what you wanted. From the docs:

ISO country, subdivision, language, currency and script definitions and their translations

pycountry provides the ISO databases for the standards:

639 Languages

3166 Countries

3166-3 Deleted countries

3166-2 Subdivisions of countries

4217 Currencies

15924 Scripts

The package includes a copy from Debian's pkg-isocodes and makes the data accessible through a Python API.

share|improve this answer
This answer needs to be higher up! Great suggestion. –  Gregory Goltsov Sep 30 at 11:35

Try this list:


It has ISO 2-letter, 3-letter and numeric codes with country short form names.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.