Using the Office for National Statistics website I can get a census summary for a UK postcode.
https://neighbourhood.statistics.gov.uk/dissemination/
I expected that I should be able to do the same thing using the API.
https://neighbourhood.statistics.gov.uk/HTMLDocs/downloads/QuickStart-Guide-V2.1.pdf
But it isn't clear to me how to get from the postcode to the neighbourhood (or Lower Layer Super Output Area as the Office for National Statistics calls them). It seems that I need to use the Delivery endpoint like this.
But how do I find out which parameters to use for a specific postcode?
It looks like three calls are required to get a dataset.
import xml.etree.ElementTree as ElementTree
import json
import requests
API_KEY = "YOUR_API_KEY"
def get_area_id(level_type, postcode):
""" Get the area id for the pos
:param level_type: The resolution you are interested in. 14 = ward level data.
:param postcode: A UK postcode
:return: string area identifier
"""
base_url = "http://neighbourhood.statistics.gov.uk/NDE2/Disco/FindAreas"
payload = {'HierarchyId': '27', 'Postcode': postcode}
response = requests.get(base_url, params=payload)
xml = ElementTree.fromstring(response.content)
namespaces = {'ns1': 'http://neighbourhood.statistics.gov.uk/nde/v1-0/discoverystructs'}
xpath_for_area = './/ns1:Area'
areas = xml.findall(xpath_for_area, namespaces)
ward_area_id = ''
for area in areas:
level_type_id = area.find('ns1:LevelTypeId', namespaces).text
if level_type_id == str(level_type): # find the Ward (=14)
ward_area_id = area.find('ns1:AreaId', namespaces).text
return ward_area_id
def get_ext_code(area_id):
""" Get the ext code (whatever that is) from an area id
:param area_id: the area id for a postcode
:return: the ext code for an area (I think is the GSS code)
"""
base_url = "http://neighbourhood.statistics.gov.uk/NDE2/Disco/GetAreaDetail"
payload = {'AreaId': area_id}
response = requests.get(base_url, params=payload)
xml = ElementTree.fromstring(response.content)
namespaces = {'ns1': 'http://neighbourhood.statistics.gov.uk/nde/v1-0/discoverystructs',
'structure': 'http://www.SDMX.org/resources/SDMXML/schemas/v2_0/structure'}
xpath_for_ext_code = './/ns1:ExtCode'
ext_code = xml.find(xpath_for_ext_code, namespaces).text
return ext_code
def get_data(data_set, geog_code):
""" Get the data for a geographical code
:param data_set: string identifier from http://www.nomisweb.co.uk/census/2011 /quick_statistics
:param geog_code: the ext code for the geographical area
:return: a json object with the data
"""
base_url = "http://data.ons.gov.uk/ons/api/data/dataset/"
payload = {'apikey': API_KEY, 'context': 'Census', 'geog': '2011WARDH', 'dm/2011WARDH': geog_code,
'totals': 'false', 'jsontype': 'json-stat'}
r = requests.get(base_url + "/" + data_set + ".json", params=payload)
obj = json.loads(r.text)
return obj
def process(json_object, data_set):
data = {}
values = json_object[data_set]['value']
index = json_object[data_set]['dimension'][json_object[data_set]['dimension']['id'][1]]['category']['index']
labels = json_object[data_set]['dimension'][json_object[data_set]['dimension']['id'][1]]['category']['label']
for l in labels:
num = index[l]
count = values[str(num)]
data[labels[l]] = count
return data
area_id = get_area_id(14, "SW1A 0AA")
gss_code = get_ext_code(area_id)
data_returned = get_data("QS208EW", gss_code) # QS208EW = religion
print(process(data_returned, "QS208EW"))
Have you tried looking at the code in the VBA example?
Function RunAreas()
Dim txtResponse
Dim postcode As String
Dim extCode
Set rootSheet = GetSheet("Query")
Set areaSheet = GetSheet("Areas")
endPoint = "http://neighbourhood.statistics.gov.uk/NDE2/Disco/FindAreas?HierarchyId=27&Postcode="
postcode = rootSheet.Range("A2").Value
Application.StatusBar = "Getting areas for " + postcode
txtResponse = GetAreas(postcode)
delim = "<delim>"
data = GetElements(txtResponse, "Area")
If UBound(data) < 0 Then
Application.StatusBar = False
MsgBox "Postcode " + postcode + " not found", vbExclamation
Exit Function
End If
For i = 0 To UBound(data)
curLevelType = GetValue(data(i), "LevelTypeId")
curHierarchy = GetValue(data(i), "HierarchyId")
curId = GetValue(data(i), "AreaId")
curName = GetValue(data(i), "Name")
Select Case curLevelType
Case 15
extCode = UpdateArea("Output Area", 2, curId, curName, curHierarchy)
Case 14
extCode = UpdateArea("Ward", 3, curId, curName, curHierarchy)
Case 13
extCode = UpdateArea("LA", 4, curId, curName, curHierarchy)
Case 11
extCode = UpdateArea("Region", 5, curId, curName, curHierarchy)
Case 10
extCode = UpdateArea("Country", 6, curId, curName, curHierarchy)
End Select
Next
MsgBox ("Areas Found")
Application.StatusBar = "Get Areas completed"
End Function
来源:https://stackoverflow.com/questions/29622849/uk-postcode-to-census-data-using-the-api