Lubar, I saw your post at Stack Overflow but am going to post a similar answer here for consistency. It's a good question. I work in the address verification industry and have tackled your kind of problem before.
I linked to this Stack Overflow question in a comment; and it's important to know that there's really no guarantee about the format of complete freeform street addresses. As mentioned in the linked post, complete addresses can look like any of these:
1) 102 main street
Anytown, state
2) 400n 600e #2, 52173
3) p.o. #104 60203
4) 1234 LKSDFJlkjsdflkjsdljf #asdf 12345
5) 205 1105 14 90210
(The reasons are explained in the linked post.) I realize that GeoPy returns addresses in a certain format -- depending on the geocoder used (which resulting format is out of GeoPy's control), but addresses can look all sorts of ways within a certain component (like having commas), and it's important to know that standardized addresses don't have commas (according to USPS Publication 28).
I helped work on an API just recently called US Street Address API from SmartyStreets; it was just upgraded to support geocoding and single-line address parsing.
GeoPy is designed to geocode, not parse into components (that task is actually really difficult for reasons I won't get into here). The US Street Address API will, however, componentize the address and return coordinates and other information about the address, and only if the addresses are real; no "guessed" results.
To parse a single-line address into components using Python, simply put the entire address into the "street" field:
import json
import pprint
import urllib
LOCATION = 'https://api.smartystreets.com/street-address/'
QUERY_STRING = urllib.urlencode({ # entire query sting must be URL-Encoded
'auth-token': r'YOUR_API_KEY_HERE',
'street': '1 infinite loop cupertino ca 95014'
})
URL = LOCATION + '?' + QUERY_STRING
response = urllib.urlopen(URL).read()
structure = json.loads(response)
pprint.pprint(structure)
The resulting JSON object will contain a components
object which will look something like this:
"components": {
"primary_number": "1",
"street_name": "Infinite",
"street_suffix": "Loop",
"city_name": "Cupertino",
"state_abbreviation": "CA",
"zipcode": "95014",
"plus4_code": "2083",
"delivery_point": "01",
"delivery_point_check_digit": "7"
}
The response will also include the combined first_line and delivery_line_2 so you don't have to manually concatenate those if you need them.
Check out this answer also for some info What ArcGIS geoprocessing tools support exporting tabular data to CSV?
Once you have a locator service, locator.addressesToLocations(options) is the API call to the locator http://help.arcgis.com/en/webapi/javascript/arcgis/jsapi/locator.html . However, none of the Esri sample servers let you batch geocode. You would need to set this up on your own ArcGIS Server. If you have a paid ArcGIS Online account you could do it there also.
As far as returning a csv file, one solution is to create your own geoprocessing service that wraps geocoding and places the finished file in the public output directory for download. You can then send the app the url of the file for a user to download.
Alternately, you could use flex or silverlight to receive the locator response, parse the json and save a csv file locally.
//this locator address is what it would look like, but you can't batch geocode (see above)
//var locator = new esri.tasks.Locator("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Locators/ESRI_Geocode_USA/GeocodeServer");
var addresses = [{
"OBJECTID": 0,
"STREET": "440 Arguello Blvd",
"ZONE": "94118"
}, {
"OBJECTID": 1,
"STREET": "100 Arguello Blvd",
"ZONE": "94118"
}];
locator.outSpatialReference = map.spatialReference;
var options = {
addresses: addresses
}
locator.addressesToLocations(options);
The addressesToLocations(options) will return an array of AddressCandidates. You can do whatever you like with them. You don't have to place on map.
http://help.arcgis.com/en/webapi/javascript/arcgis/jsapi/addresscandidate.html
Best Answer
Looks like someone asked this on SO and didn't get an answer. The Google Maps API blog says:
and suggests you might want to look at the Places API as the Geocoding API is more for complete postal address strings.