├── AUTHORS.md
├── tests
├── __init__.py
└── test_valuation.py
├── requirements.txt
├── setup.cfg
├── MANIFEST.in
├── tox.ini
├── CHANGELOG.rst
├── zillow
├── error.py
├── __init__.py
├── place.py
└── api.py
├── .travis.yml
├── examples
└── get_search_results.py
├── .gitignore
├── Makefile
├── setup.py
├── testdata
├── get_zestimate.xml
├── place.xml
├── get_deep_search_results.xml
├── get_comps.xml
└── get_deep_comps.xml
├── README.md
└── LICENSE
/AUTHORS.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | requests
2 | xmltodict
3 | nose
4 | coverage
--------------------------------------------------------------------------------
/setup.cfg:
--------------------------------------------------------------------------------
1 | [metadata]
2 | description-file = README.md
3 | license-file = LICENSE
4 |
5 | [bdist_wheel]
6 | universal = 1
7 |
--------------------------------------------------------------------------------
/MANIFEST.in:
--------------------------------------------------------------------------------
1 | include LICENSE *.md *.rst
2 |
3 | # Tests
4 | include tox.ini .coveragerc conftest.py *-requirements.txt
5 | recursive-include tests *.py
6 | exclude .travis.yml
7 |
--------------------------------------------------------------------------------
/tox.ini:
--------------------------------------------------------------------------------
1 | [tox]
2 | envlist = py{36,35,34,27}
3 |
4 | [testenv]
5 | deps =
6 | coverage
7 | nose
8 |
9 | commands =
10 | nosetests --with-coverage --cover-package=zillow --cover-html
11 |
--------------------------------------------------------------------------------
/CHANGELOG.rst:
--------------------------------------------------------------------------------
1 | 0.3.0
2 | =====
3 |
4 | Released: TBD
5 |
6 | 0.2.0
7 | =====
8 |
9 | Released: 2018-03-29
10 |
11 | - Add ``GetDeepComps`` API method
12 | - Fix Python 3 compatibility
13 | - Fix ``zestimate`` typos
14 | - Use HTTPS for API requests
15 |
--------------------------------------------------------------------------------
/zillow/error.py:
--------------------------------------------------------------------------------
1 | class ZillowError(Exception):
2 | """Base class for Zillow errors"""
3 |
4 | @property
5 | def message(self):
6 | """
7 | :return: The first argument used to construct this error.
8 | """
9 | return self.args[0]
10 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: python
2 |
3 | matrix:
4 | include:
5 | - python: 3.6
6 | env: TOX_ENV=py36
7 | - python: 3.5
8 | env: TOX_ENV=py35
9 | - python: 3.4
10 | env: TOX_ENV=py34
11 | - python: 2.7
12 | env: TOX_ENV=py27
13 |
14 | install: pip install tox
15 |
16 | script: tox -e $TOX_ENV
17 |
18 | branches:
19 | only:
20 | - master
21 |
--------------------------------------------------------------------------------
/examples/get_search_results.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import zillow
4 | import pprint
5 |
6 | if __name__=="__main__":
7 | key = ""
8 | with open("./bin/config/zillow_key.conf", 'r') as f:
9 | key = f.readline().replace("\n", "")
10 |
11 | address = "3400 Pacific Ave., Marina Del Rey, CA"
12 | postal_code = "90292"
13 |
14 | api = zillow.ValuationApi()
15 | data = api.GetSearchResults(key, address, postal_code)
16 |
17 | pp = pprint.PrettyPrinter(indent=4)
18 | pp.pprint(data.get_dict())
19 |
20 | detail_data = api.GetZEstimate(key, data.zpid)
21 |
22 | comp_data = api.GetComps(key, data.zpid)
23 |
24 | pp.pprint(comp_data['comps'][1].get_dict())
25 |
26 | deep_results = api.GetDeepSearchResults(key, "1920 1st Street South Apt 407, Minneapolis, MN", "55454")
27 | pp.pprint(deep_results.get_dict())
--------------------------------------------------------------------------------
/zillow/__init__.py:
--------------------------------------------------------------------------------
1 | """A library that provides a Python interface to the Zillow API."""
2 |
3 | from __future__ import absolute_import
4 |
5 | import os as _os
6 | import pkg_resources as _pkg_resources
7 |
8 | from .error import ZillowError # noqa: F401
9 | from .place import Place # noqa: F401
10 | from .api import ValuationApi # noqa: F401
11 |
12 |
13 | __author__ = 'python-zillow@googlegroups.com'
14 |
15 |
16 | try:
17 | _dist = _pkg_resources.get_distribution('python-' + __package__)
18 | if not _os.path.abspath(__file__).startswith(
19 | _os.path.join(_dist.location, __package__)):
20 | # Manually raise the exception if there is a distribution but
21 | # it's installed from elsewhere.
22 | raise _pkg_resources.DistributionNotFound
23 | except _pkg_resources.DistributionNotFound:
24 | __version__ = 'development'
25 | else:
26 | __version__ = _dist.version
27 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 |
5 | # C extensions
6 | *.so
7 |
8 | # Distribution / packaging
9 | .Python
10 | env/
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | *.egg-info/
23 | .installed.cfg
24 | *.egg
25 |
26 | # PyInstaller
27 | # Usually these files are written by a python script from a template
28 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
29 | *.manifest
30 | *.spec
31 |
32 | # Installer logs
33 | pip-log.txt
34 | pip-delete-this-directory.txt
35 |
36 | # Unit test / coverage reports
37 | htmlcov/
38 | .tox/
39 | .coverage
40 | .coverage.*
41 | .cache
42 | nosetests.xml
43 | coverage.xml
44 | *,cover
45 |
46 | # Translations
47 | *.mo
48 | *.pot
49 |
50 | # Django stuff:
51 | *.log
52 |
53 | # Sphinx documentation
54 | docs/_build/
55 |
56 | # PyBuilder
57 | target/
58 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | help:
2 | @echo " env create a development environment using virtualenv"
3 | @echo " deps install dependencies"
4 | @echo " clean remove unwanted stuff"
5 | @echo " coverage run tests with code coverage"
6 | @echo " test run tests"
7 |
8 | env:
9 | sudo easy_install pip && \
10 | pip install virtualenv && \
11 | virtualenv env && \
12 | . env/bin/activate && \
13 | make deps
14 |
15 | deps:
16 | pip install -r requirements.txt --use-mirrors
17 |
18 | clean:
19 | rm -fr build
20 | rm -fr dist
21 | find . -name '*.pyc' -exec rm -f {} \;
22 | find . -name '*.pyo' -exec rm -f {} \;
23 | find . -name '*~' -exec rm -f {} \;
24 |
25 | coverage:
26 | nosetests --with-coverage --cover-package=zillow --cover-html
27 |
28 | test:
29 | nosetests
30 |
31 | build: clean
32 | python setup.py sdist
33 | python setup.py bdist_wheel
34 |
35 | upload: clean
36 | python setup.py sdist upload
37 | python setup.py bdist_wheel upload
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | """
2 | The setup and build script for the python-zillow library.
3 | """
4 |
5 | import os
6 |
7 | from setuptools import setup, find_packages
8 |
9 |
10 | def read(*paths):
11 | """Build a file path from *paths* and return the contents."""
12 | with open(os.path.join(*paths), 'r') as f:
13 | return f.read()
14 |
15 |
16 | setup(
17 | name='python-zillow',
18 | version='0.3.0',
19 | author='The Python-Zillow Developers',
20 | author_email='python-zillow@googlegroups.com',
21 | license='Apache License 2.0',
22 | url='https://github.com/seme0021/python-zillow',
23 | download_url='https://github.com/seme0021/python-zillow/tarball/master',
24 | keywords=['zillow', 'api', 'real estate', 'python'],
25 | description='A Python wrapper around the Zillow API',
26 | packages=find_packages(exclude=['tests*']),
27 | install_requires=[
28 | 'requests',
29 | 'xmltodict',
30 | ],
31 | classifiers=[
32 | 'Development Status :: 5 - Production/Stable',
33 | 'Intended Audience :: Developers',
34 | 'License :: OSI Approved :: Apache Software License',
35 | 'Operating System :: OS Independent',
36 | 'Topic :: Software Development :: Libraries :: Python Modules',
37 | 'Topic :: Communications :: Chat',
38 | 'Topic :: Internet',
39 | 'Programming Language :: Python',
40 | 'Programming Language :: Python :: 2',
41 | 'Programming Language :: Python :: 2.7',
42 | 'Programming Language :: Python :: 3',
43 | 'Programming Language :: Python :: 3.4',
44 | 'Programming Language :: Python :: 3.5',
45 | 'Programming Language :: Python :: 3.6',
46 | ],
47 | )
48 |
--------------------------------------------------------------------------------
/testdata/get_zestimate.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 | 2100641621
8 |
9 |
10 | Request successfully processed
11 | 0
12 |
13 |
14 | 2100641621
15 |
16 |
17 | http://www.zillow.com/homedetails/3400-Pacific-Ave-APT-201-Marina-Del-Rey-CA-90292/2100641621_zpid/
18 |
19 | http://www.zillow.com/homes/2100641621_zpid/
20 | http://www.zillow.com/homes/comps/2100641621_zpid/
21 |
22 |
23 | 3400 Pacific Ave APT 201
24 | 90292
25 | Marina Del Rey
26 | CA
27 | 33.9781
28 | -118.4643
29 |
30 |
31 | 1723665
32 | 01/03/2016
33 |
34 | 108687
35 |
36 | 1551299
37 | 1878795
38 |
39 | 0
40 |
41 |
42 |
43 | 1,189,300
44 |
45 | http://www.zillow.com/local-info/CA-Los-Angeles/Venice/r_21056/
46 | http://www.zillow.com/venice-los-angeles-ca/fsbo/
47 | http://www.zillow.com/venice-los-angeles-ca/
48 |
49 |
50 |
51 |
52 | 96128
53 | 12447
54 | 3101
55 | 9
56 |
57 |
58 |
--------------------------------------------------------------------------------
/testdata/place.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 | 3400 Pacific Ave., Marina Del Rey, CA
8 | 90292
9 |
10 |
11 | Request successfully processed
12 | 0
13 |
14 |
15 |
16 |
17 | 2100641621
18 |
19 |
20 | http://www.zillow.com/homedetails/3400-Pacific-Ave-APT-201-Marina-Del-Rey-CA-90292/2100641621_zpid/
21 |
22 | http://www.zillow.com/homes/2100641621_zpid/
23 | http://www.zillow.com/homes/comps/2100641621_zpid/
24 |
25 |
26 | 3400 Pacific Ave APT 201
27 | 90292
28 | Marina Del Rey
29 | CA
30 | 33.9781
31 | -118.4643
32 |
33 |
34 | 1723665
35 | 01/03/2016
36 |
37 | 108687
38 |
39 | 1551299
40 | 1878795
41 |
42 | 0
43 |
44 |
45 |
46 | 1,189,300
47 |
48 | http://www.zillow.com/local-info/CA-Los-Angeles/Venice/r_21056/
49 | http://www.zillow.com/venice-los-angeles-ca/fsbo/
50 | http://www.zillow.com/venice-los-angeles-ca/
51 |
52 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Python-Zillow
2 | =============
3 |
4 | A Python wrapper around the Zillow API.
5 |
6 | By the [Python-Zillow Developers](mailto:python-zillow@googlegroups.com)
7 |
8 |
9 | Introduction
10 | ------------
11 |
12 | This library provides a Python interface for the [Zillow API](http://www.zillow.com/howto/api/APIOverview.htm). It works with Python versions from 2.6+.
13 |
14 | [Zillow](www.zillow.com) provides a service that allows people to research the value of home across the United States.
15 | Zillow exposes this information via a web services API and this library is intended to make it easier for Python developers to use.
16 |
17 |
18 | Installing
19 | ----------
20 |
21 | You can install python-zillow using:
22 |
23 | ```shell
24 | pip install python-zillow
25 | ```
26 |
27 | Getting the code
28 | ----------------
29 |
30 | The code is hosted at https://github.com/seme0021/python-zillow
31 |
32 | Check out the latest development version anonymously with::
33 | ```shell
34 | $ git clone git://github.com/seme0021/python-zillow.git
35 | $ cd python-zillow
36 | ```
37 |
38 | Setup a virtual environment and install dependencies:
39 |
40 | ```shell
41 | $ virtualenv env
42 | ```
43 |
44 | Activate the virtual environment created:
45 |
46 | ```shell
47 | $ source env/bin/activate
48 | ```
49 |
50 | Running Tests
51 | -------------
52 | Note that tests require ```pip install nose``` and optionally ```pip install coverage```:
53 |
54 | To run the unit tests:
55 | ```shell
56 | make test
57 | ```
58 |
59 | to also run code coverage:
60 |
61 | ```shell
62 | make coverage
63 | ```
64 |
65 |
66 | Basic Tutorial on Searching Zillow
67 | ----------------------------------
68 |
69 | Here is some basic python code to query the zillow api using the python-zillow library.
70 |
71 | Note: I suggest keeping your key stored in a ./bin/config/zillow_key.conf file
72 |
73 | ### Initialize the API
74 |
75 | ```python
76 | import zillow
77 |
78 | with open("./bin/config/zillow_key.conf", 'r') as f:
79 | key = f.readline().replace("\n", "")
80 |
81 | api = zillow.ValuationApi()
82 | ```
83 |
84 | ### Find a place given an address
85 |
86 | ```python
87 | address = "3400 Pacific Ave., Marina Del Rey, CA"
88 | postal_code = "90292"
89 |
90 | data = api.GetSearchResults(key, address, postal_code)
91 | ```
92 |
93 | ### Find place using a zillow place id
94 |
95 | ```python
96 | zpid="2100641621"
97 | detail_data = api.GetZEstimate(key, zpid)
98 | ```
99 |
100 | ### Find comparables
101 | ```python
102 | zpid="2100641621"
103 | detail_data = api.GetComps(key, zpid)
104 | ```
105 |
106 | ### Get Deep Search Results
107 | ```python
108 | address = "3400 Pacific Ave., Marina Del Rey, CA"
109 | postal_code = "90292"
110 |
111 | data = api.GetDeepSearchResults(key, address, postal_code)
112 | ```
113 |
114 | ### Get Deep Comps
115 | ```python
116 | zws_id = ""
117 | zpid = 2100641621
118 | count=10
119 |
120 | data = data = api.GetDeepComps(zws_id, zpid, count)
121 | ```
122 |
--------------------------------------------------------------------------------
/testdata/get_deep_search_results.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 | 3400 Pacific Ave., Marina Del Rey, CA
8 | 90292
9 |
10 |
11 | Request successfully processed
12 | 0
13 |
14 |
15 |
16 |
17 | 2100641621
18 |
19 |
20 | http://www.zillow.com/homedetails/3400-Pacific-Ave-APT-201-Marina-Del-Rey-CA-90292/2100641621_zpid/
21 |
22 | http://www.zillow.com/homes/2100641621_zpid/
23 | http://www.zillow.com/homes/comps/2100641621_zpid/
24 |
25 |
26 | 3400 Pacific Ave APT 201
27 | 90292
28 | Marina Del Rey
29 | CA
30 | 33.9781
31 | -118.4643
32 |
33 |
34 | MultiFamily2To4
35 | 3.0
36 | 2
37 |
38 | 1729341
39 | 01/05/2016
40 |
41 | 107835
42 |
43 | 1608287
44 | 1902275
45 |
46 | 0
47 |
48 |
49 |
50 | 1,189,300
51 |
52 | http://www.zillow.com/local-info/CA-Los-Angeles/Venice/r_21056/
53 | http://www.zillow.com/venice-los-angeles-ca/fsbo/
54 | http://www.zillow.com/venice-los-angeles-ca/
55 |
56 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/tests/test_valuation.py:
--------------------------------------------------------------------------------
1 | import unittest
2 | import warnings
3 |
4 | import xmltodict
5 | from zillow import Place
6 |
7 |
8 | class TestGetSearchResult(unittest.TestCase):
9 |
10 | def test_search_results(self):
11 | RAW_XML = ""
12 | with open('./testdata/place.xml', 'r') as f:
13 | RAW_XML = ''.join(f.readlines())
14 |
15 | data = xmltodict.parse(RAW_XML)
16 |
17 | place = Place()
18 | place.set_data(data.get('SearchResults:searchresults', None)['response']['results']['result'])
19 |
20 | self.assertEqual("2100641621", place.zpid)
21 | self.assertEqual(1723665, place.zestimate.amount)
22 |
23 | def test_zestimate(self):
24 | RAW_XML = ""
25 | with open('./testdata/get_zestimate.xml', 'r') as f:
26 | RAW_XML = ''.join(f.readlines())
27 |
28 | data = xmltodict.parse(RAW_XML)
29 |
30 | place = Place()
31 | place.set_data(data.get('Zestimate:zestimate', None)['response'])
32 |
33 | self.assertEqual("2100641621", place.zpid)
34 | self.assertEqual(1723665, place.zestimate.amount)
35 |
36 | def test_zestiamte(self):
37 | """Test that the backward-compatible ``zestiamte`` works.
38 |
39 | This property should correctly return the ``zestimate``
40 | attribute and raise a DeprecationWarning about the changing
41 | name.
42 |
43 | """
44 | warnings.simplefilter('always', DeprecationWarning)
45 |
46 | with open('./testdata/get_zestimate.xml', 'r') as f:
47 | RAW_XML = ''.join(f.readlines())
48 |
49 | data = xmltodict.parse(RAW_XML)
50 |
51 | place = Place()
52 | place.set_data(data.get('Zestimate:zestimate', None)['response'])
53 |
54 | self.assertEqual(place.zestiamte, place.zestimate)
55 |
56 | with warnings.catch_warnings(record=True) as warning:
57 | place.zestiamte
58 | assert issubclass(warning[0].category, DeprecationWarning)
59 |
60 | def test_getcomps_principal(self):
61 | RAW_XML = ""
62 | with open('./testdata/get_comps.xml', 'r') as f:
63 | RAW_XML = ''.join(f.readlines())
64 |
65 | data = xmltodict.parse(RAW_XML)
66 |
67 | place = Place()
68 | place.set_data(data.get('Comps:comps')['response']['properties']['principal'])
69 |
70 | self.assertEqual("2100641621", place.zpid)
71 |
72 | def test_getcomps_comps(self):
73 | RAW_XML = ""
74 | with open('./testdata/get_comps.xml', 'r') as f:
75 | RAW_XML = ''.join(f.readlines())
76 |
77 | data = xmltodict.parse(RAW_XML)
78 | comps = data.get('Comps:comps')['response']['properties']['comparables']['comp']
79 |
80 | comp_places = []
81 |
82 | for datum in comps:
83 | place = Place()
84 | place.set_data(datum)
85 | comp_places.append(place)
86 |
87 | self.assertEqual(10, len(comp_places))
88 |
89 | def test_extended_data(self):
90 | RAW_XML = ""
91 | with open('./testdata/get_deep_search_results.xml', 'r') as f:
92 | RAW_XML = ''.join(f.readlines())
93 |
94 | data = xmltodict.parse(RAW_XML)
95 |
96 | place = Place(has_extended_data=True)
97 | place.set_data(data.get('SearchResults:searchresults', None)['response']['results']['result'])
98 |
99 | assert place.get_dict() is not None
100 |
101 | def test_get_deep_comps(self):
102 | RAW_XML = ""
103 | with open('./testdata/get_deep_comps.xml', 'r') as f:
104 | RAW_XML = ''.join(f.readlines())
105 |
106 | xmltodict_data = xmltodict.parse(RAW_XML)
107 |
108 | # get the principal property data
109 | principal_place = Place()
110 | principal_data = xmltodict_data.get('Comps:comps')['response']['properties']['principal']
111 |
112 | assert principal_data is not None
113 |
--------------------------------------------------------------------------------
/zillow/place.py:
--------------------------------------------------------------------------------
1 | from abc import abstractmethod
2 | import warnings
3 |
4 |
5 | class SourceData(classmethod):
6 |
7 | @abstractmethod
8 | def set_data(self, source_data):
9 | """
10 | @type source_data: dict
11 | """
12 | raise NotImplementedError()
13 |
14 | @abstractmethod
15 | def debug(self):
16 | for i in self.__dict__.keys():
17 | print("%s: %s" % (i, self.__dict__[i]))
18 |
19 | @abstractmethod
20 | def get_dict(self):
21 | res = {}
22 | for i in self.__dict__.keys():
23 | res[i] = self.__dict__[i]
24 | return res
25 |
26 | @abstractmethod
27 | def set_values_from_dict(self, data_dict):
28 | """
29 | @type data_dict: dict
30 | """
31 | for i in self.__dict__.keys():
32 | if i in data_dict.keys():
33 | self.__dict__[i] = data_dict[i]
34 |
35 |
36 | class Links(SourceData):
37 | def __init__(self, **kwargs):
38 | self.home_details = None
39 | self.graphs_and_data = None
40 | self.map_this_home = None
41 | self.comparables = None
42 |
43 | def set_data(self, source_data):
44 | """
45 | :source_data: Data from data.get('SearchResults:searchresults', None)['response']['results']['result']['links']
46 | :return:
47 | """
48 | self.home_details = source_data['homedetails']
49 | try:
50 | self.graphs_and_data = source_data['graphsanddata']
51 | except:
52 | self.graphs_and_data = None
53 | self.map_this_home = source_data['mapthishome']
54 | self.comparables = source_data['comparables']
55 |
56 | class FullAddress(SourceData):
57 | def __init__(self, **kwargs):
58 | self.street = None
59 | self.zipcode = None
60 | self.city = None
61 | self.state = None
62 | self.latitude = None
63 | self.longitude = None
64 |
65 | def set_data(self, source_data):
66 | """
67 | :source_data: Data from data.get('SearchResults:searchresults', None)['response']['results']['result']['address']
68 | :return:
69 | """
70 | self.street = source_data['street']
71 | self.zipcode = source_data['zipcode']
72 | self.city = source_data['city']
73 | self.state = source_data['state']
74 | self.latitude = source_data['latitude']
75 | self.longitude = source_data['longitude']
76 |
77 | class ZEstimateData(SourceData):
78 | def __init__(self, **kwargs):
79 | self.amount = None
80 | self.amount_currency = None
81 | self.amount_last_updated = None
82 | self.amount_change_30days = None
83 | self.valuation_range_low = None
84 | self.valuation_range_high = None
85 |
86 | def set_data(self, source_data):
87 | """
88 | :source_data: Data from data.get('SearchResults:searchresults', None)['response']['results']['result']['zestimate']
89 | :return:
90 | """
91 | try:
92 | self.amount = int(source_data['amount']['#text'])
93 | except:
94 | self.amount = None
95 | self.amount_currency = source_data['amount']['@currency']
96 | self.amount_last_updated = source_data['last-updated']
97 | try:
98 | self.amount_change_30days = int(source_data['valueChange']['#text'])
99 | except:
100 | self.amount_change_30days = None
101 | try:
102 | self.valuation_range_low = int(source_data['valuationRange']['low']['#text'])
103 | except:
104 | self.valuation_range_low = None
105 | try:
106 | self.valuation_range_high = int(source_data['valuationRange']['high']['#text'])
107 | except:
108 | self.valuation_range_high = None
109 |
110 | class LocalRealEstate(SourceData):
111 | def __init__(self):
112 | self.region_name = None
113 | self.region_id = None
114 | self.region_type = None
115 | self.overview_link = None
116 | self.fsbo_link = None
117 | self.sale_link = None
118 | self.zillow_home_value_index = None
119 |
120 | def set_data(self, source_data):
121 | """
122 | :source_data": Data from data.get('SearchResults:searchresults', None)['response']['results']['result']['localRealEstate']
123 | :return:
124 | """
125 | self.region_name = source_data['region']['@name']
126 | self.region_id = source_data['region']['@id']
127 | self.region_type = source_data['region']['@type']
128 | self.zillow_home_value_index = source_data.get('zindexValue', None)
129 | self.overview_link = source_data['region']['links']['overview']
130 | self.fsbo_link = source_data['region']['links']['forSaleByOwner']
131 | self.sale_link = source_data['region']['links']['forSale']
132 |
133 | class ExtendedData(SourceData):
134 | def __init__(self):
135 | self.fips_county = None
136 | self.usecode = None
137 | self.tax_assessment_year = None
138 | self.tax_assessment = None
139 | self.year_built = None
140 | self.lot_size_sqft = None
141 | self.finished_sqft = None
142 | self.bathrooms = None
143 | self.bedrooms = None
144 | self.last_sold_date = None
145 | self.last_sold_price = None
146 | self.complete = False
147 |
148 | def set_data(self, source_data):
149 | self.fips_county = source_data.get('FIPScounty', None)
150 | self.usecode = source_data['useCode']
151 | self.tax_assessment_year = source_data.get('taxAssessmentYear', None)
152 | self.tax_assessment = source_data.get('taxAssessment', None)
153 | self.year_built = source_data.get('yearBuilt', None)
154 | self.lot_size_sqft = source_data.get('lotSizeSqFt', None)
155 | self.finished_sqft = source_data.get('finishedSqFt', None)
156 | self.bathrooms = source_data.get('bathrooms', None)
157 | self.bedrooms = source_data.get('bedrooms', None)
158 | self.last_sold_date = source_data.get('lastSoldDate', None)
159 | price_element = source_data.get('lastSoldPrice', None)
160 | if price_element is not None:
161 | self.last_sold_price = price_element.get('#text', None)
162 | self.complete = True
163 |
164 |
165 | class Place(SourceData):
166 | """
167 | A class representing a property and it's details
168 | """
169 | def __init__(self, has_extended_data=False):
170 | self.zpid = None
171 | self.links = Links()
172 | self.full_address = FullAddress()
173 | self.zestimate = ZEstimateData()
174 | self.local_realestate = LocalRealEstate()
175 | self.similarity_score = None
176 | self.extended_data = ExtendedData()
177 | self.has_extended_data = has_extended_data
178 |
179 | @property
180 | def zestiamte(self):
181 | """Backward-compatible typo property to prevent breaking changes."""
182 | warnings.warn(
183 | 'The ``zestiamte`` attribute has been renamed to '
184 | '``zestimate`` and will be removed in a future release.',
185 | DeprecationWarning,
186 | )
187 | return self.zestimate
188 |
189 |
190 | def set_data(self, source_data):
191 | """
192 | :source_data": Data from data.get('SearchResults:searchresults', None)['response']['results']['result']
193 | :param source_data:
194 | :return:
195 | """
196 |
197 | self.zpid = source_data.get('zpid', None)
198 | self.similarity_score = source_data.get('@score', None)
199 | self.links.set_data(source_data['links'])
200 | self.full_address.set_data(source_data['address'])
201 | self.zestimate.set_data(source_data['zestimate'])
202 | self.local_realestate.set_data(source_data['localRealEstate'])
203 | if self.has_extended_data:
204 | self.extended_data.set_data(source_data)
205 |
206 | def get_dict(self):
207 | data = {
208 | 'zpid': self.zpid,
209 | 'similarity_score': self.similarity_score,
210 | 'links': self.links.get_dict(),
211 | 'full_address': self.full_address.get_dict(),
212 | 'zestimate': self.zestimate.get_dict(),
213 | 'local_realestate': self.local_realestate.get_dict(),
214 | 'extended_data': self.extended_data.get_dict()
215 | }
216 | return data
217 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
203 |
--------------------------------------------------------------------------------
/zillow/api.py:
--------------------------------------------------------------------------------
1 | import requests
2 | import xmltodict
3 |
4 | try:
5 | # python 3
6 | from urllib.parse import urlparse, urlunparse, urlencode
7 | except ImportError:
8 | from urlparse import urlparse, urlunparse
9 | from urllib import urlencode
10 |
11 | from .error import ZillowError
12 | from .place import Place
13 |
14 |
15 | class ValuationApi(object):
16 | """
17 | A python interface into the Zillow API
18 | By default, the Api caches results for 1 minute.
19 | Example usage:
20 | To create an instance of the zillow.ValuationApi class:
21 | >>> import zillow
22 | >>> api = zillow.ValuationApi()
23 |
24 |
25 | All available methods include:
26 | >>> data = api.GetSearchResults("", "", "")
27 | """
28 | def __init__(self):
29 | self.base_url = "https://www.zillow.com/webservice"
30 | self._input_encoding = None
31 | self._request_headers=None
32 | self.__auth = None
33 | self._timeout = None
34 |
35 | def GetSearchResults(self, zws_id, address, citystatezip, retnzestimate=False):
36 | """
37 | The GetSearchResults API finds a property for a specified address.
38 | The content returned contains the address for the property or properties as well as the Zillow Property ID (ZPID) and current Zestimate.
39 | It also includes the date the Zestimate was computed, a valuation range and the Zestimate ranking for the property within its ZIP code.
40 | The GetSearchResults API Web Service is located at: http://www.zillow.com/webservice/GetSearchResults.htm
41 | :param zws_id: The Zillow Web Service Identifier. Each subscriber to Zillow Web Services is uniquely identified by an ID sequence and every request to Web services requires this ID.
42 | :param address: The address of the property to search. This string should be URL encoded.
43 | :param citystatezip: The city+state combination and/or ZIP code for which to search. This string should be URL encoded. Note that giving both city and state is required. Using just one will not work.
44 | :param retnzestimat: Return Rent Zestimate information if available (boolean true/false, default: false)
45 | :return:
46 | """
47 | url = '%s/GetSearchResults.htm' % (self.base_url)
48 | parameters = {'zws-id': zws_id}
49 | if address and citystatezip:
50 | parameters['address'] = address
51 | parameters['citystatezip'] = citystatezip
52 | else:
53 | raise ZillowError({'message': "Specify address and citystatezip."})
54 | if retnzestimate:
55 | parameters['retnzestimate'] = 'true'
56 |
57 | resp = self._RequestUrl(url, 'GET', data=parameters)
58 | data = resp.content.decode('utf-8')
59 |
60 | xmltodict_data = xmltodict.parse(data)
61 |
62 | place = Place()
63 | try:
64 | place.set_data(xmltodict_data.get('SearchResults:searchresults', None)['response']['results']['result'])
65 | except:
66 | raise ZillowError({'message': "Zillow did not return a valid response: %s" % data})
67 |
68 | return place
69 |
70 | def GetZEstimate(self, zws_id, zpid, retnzestimate=False):
71 | """
72 | The GetZestimate API will only surface properties for which a Zestimate exists.
73 | If a request is made for a property that has no Zestimate, an error code is returned.
74 | Zillow doesn't have Zestimates for all the homes in its database.
75 | For such properties, we do have tax assessment data, but that is not provided through the API.
76 | For more information, see our Zestimate coverage.
77 | :zws_id: The Zillow Web Service Identifier.
78 | :param zpid: The address of the property to search. This string should be URL encoded.
79 | :param retnzestimate: Return Rent Zestimate information if available (boolean true/false, default: false)
80 | :return:
81 | """
82 | url = '%s/GetZestimate.htm' % (self.base_url)
83 | parameters = {'zws-id': zws_id,
84 | 'zpid': zpid}
85 | if retnzestimate:
86 | parameters['retnzestimate'] = 'true'
87 |
88 | resp = self._RequestUrl(url, 'GET', data=parameters)
89 | data = resp.content.decode('utf-8')
90 |
91 | xmltodict_data = xmltodict.parse(data)
92 |
93 | place = Place()
94 | try:
95 | place.set_data(xmltodict_data.get('Zestimate:zestimate', None)['response'])
96 | except:
97 | raise ZillowError({'message': "Zillow did not return a valid response: %s" % data})
98 |
99 | return place
100 |
101 | def GetDeepSearchResults(self, zws_id, address, citystatezip, retnzestimate=False):
102 | """
103 | The GetDeepSearchResults API finds a property for a specified address.
104 | The result set returned contains the full address(s), zpid and Zestimate data that is provided by the GetSearchResults API.
105 | Moreover, this API call also gives rich property data like lot size, year built, bath/beds, last sale details etc.
106 | :zws_id: The Zillow Web Service Identifier.
107 | :param address: The address of the property to search. This string should be URL encoded.
108 | :param citystatezip: The city+state combination and/or ZIP code for which to search.
109 | :param retnzestimate: Return Rent Zestimate information if available (boolean true/false, default: false)
110 | :return:
111 |
112 | Example:
113 | """
114 | url = '%s/GetDeepSearchResults.htm' % (self.base_url)
115 | parameters = {'zws-id': zws_id,
116 | 'address': address,
117 | 'citystatezip': citystatezip
118 | }
119 |
120 | if retnzestimate:
121 | parameters['retnzestimate'] = 'true'
122 |
123 | resp = self._RequestUrl(url, 'GET', data=parameters)
124 | data = resp.content.decode('utf-8')
125 |
126 | xmltodict_data = xmltodict.parse(data)
127 |
128 | place = Place(has_extended_data=True)
129 | try:
130 | place.set_data(xmltodict_data.get('SearchResults:searchresults', None)['response']['results']['result'])
131 | except:
132 | raise ZillowError({'message': "Zillow did not return a valid response: %s" % data})
133 |
134 | return place
135 |
136 | def GetDeepComps(self, zws_id, zpid, count=10, rentzestimate=False):
137 | """
138 | The GetDeepComps API returns a list of comparable recent sales for a specified property.
139 | The result set returned contains the address, Zillow property identifier, and Zestimate for the comparable
140 | properties and the principal property for which the comparables are being retrieved.
141 | This API call also returns rich property data for the comparables.
142 | :param zws_id: The Zillow Web Service Identifier.
143 | :param zpid: The address of the property to search. This string should be URL encoded.
144 | :param count: The number of comparable recent sales to obtain (integer between 1 and 25)
145 | :param rentzestimate: Return Rent Zestimate information if available (boolean true/false, default: false)
146 | :return:
147 | Example
148 | >>> data = api.GetDeepComps("", 2100641621, 10)
149 | """
150 | url = '%s/GetDeepComps.htm' % (self.base_url)
151 | parameters = {'zws-id': zws_id,
152 | 'zpid': zpid,
153 | 'count': count}
154 | if rentzestimate:
155 | parameters['rentzestimate'] = 'true'
156 |
157 | resp = self._RequestUrl(url, 'GET', data=parameters)
158 | data = resp.content.decode('utf-8')
159 |
160 | # transform the data to an dict-like object
161 | xmltodict_data = xmltodict.parse(data)
162 |
163 | # get the principal property data
164 | principal_place = Place()
165 | principal_data = xmltodict_data.get('Comps:comps')['response']['properties']['principal']
166 |
167 | try:
168 | principal_place.set_data(principal_data)
169 | except:
170 | raise ZillowError({'message': 'No principal data found: %s' % data})
171 |
172 | # get the comps property_data
173 | comps = xmltodict_data.get('Comps:comps')['response']['properties']['comparables']['comp']
174 |
175 | comp_places = []
176 | for datum in comps:
177 | place = Place()
178 | try:
179 | place.set_data(datum)
180 | comp_places.append(place)
181 | except:
182 | raise ZillowError({'message': 'No valid comp data found %s' % datum})
183 |
184 | output = {
185 | 'principal': principal_place,
186 | 'comps': comp_places
187 | }
188 |
189 | return output
190 |
191 | def GetComps(self, zws_id, zpid, count=25, rentzestimate=False):
192 | """
193 | The GetComps API returns a list of comparable recent sales for a specified property.
194 | The result set returned contains the address, Zillow property identifier,
195 | and Zestimate for the comparable properties and the principal property for which the comparables are being retrieved.
196 | :param zpid: The address of the property to search. This string should be URL encoded.
197 | :param count: The number of comparable recent sales to obtain (integer between 1 and 25)
198 | :param retnzestimate: Return Rent Zestimate information if available (boolean true/false, default: false)
199 | :return:
200 | """
201 | url = '%s/GetComps.htm' % (self.base_url)
202 | parameters = {'zws-id': zws_id,
203 | 'zpid': zpid,
204 | 'count': count}
205 | if rentzestimate:
206 | parameters['rentzestimate'] = 'true'
207 |
208 | resp = self._RequestUrl(url, 'GET', data=parameters)
209 | data = resp.content.decode('utf-8')
210 |
211 | # transform the data to an dict-like object
212 | xmltodict_data = xmltodict.parse(data)
213 |
214 | # get the principal property data
215 | principal_place = Place()
216 | principal_data = xmltodict_data.get('Comps:comps')['response']['properties']['principal']
217 |
218 | try:
219 | principal_place.set_data(principal_data)
220 | except:
221 | raise ZillowError({'message': 'No principal data found: %s' % data})
222 |
223 | # get the comps property_data
224 | comps = xmltodict_data.get('Comps:comps')['response']['properties']['comparables']['comp']
225 |
226 | comp_places = []
227 | for datum in comps:
228 | place = Place()
229 | try:
230 | place.set_data(datum)
231 | comp_places.append(place)
232 | except:
233 | raise ZillowError({'message': 'No valid comp data found %s' % datum})
234 |
235 | output = {
236 | 'principal': principal_place,
237 | 'comps': comp_places
238 | }
239 |
240 | return output
241 |
242 | def _RequestUrl(self, url, verb, data=None):
243 | """
244 | Request a url.
245 | :param url: The web location we want to retrieve.
246 | :param verb: GET only (for now).
247 | :param data: A dict of (str, unicode) key/value pairs.
248 | :return:A JSON object.
249 | """
250 | if verb == 'GET':
251 | url = self._BuildUrl(url, extra_params=data)
252 | try:
253 | return requests.get(
254 | url,
255 | auth=self.__auth,
256 | timeout=self._timeout
257 | )
258 | except requests.RequestException as e:
259 | raise ZillowError(str(e))
260 | return 0
261 |
262 | def _BuildUrl(self, url, path_elements=None, extra_params=None):
263 | """
264 | Taken from: https://github.com/bear/python-twitter/blob/master/twitter/api.py#L3814-L3836
265 | :param url:
266 | :param path_elements:
267 | :param extra_params:
268 | :return:
269 | """
270 | # Break url into constituent parts
271 | (scheme, netloc, path, params, query, fragment) = urlparse(url)
272 |
273 | # Add any additional path elements to the path
274 | if path_elements:
275 | # Filter out the path elements that have a value of None
276 | p = [i for i in path_elements if i]
277 | if not path.endswith('/'):
278 | path += '/'
279 | path += '/'.join(p)
280 |
281 | # Add any additional query parameters to the query string
282 | if extra_params and len(extra_params) > 0:
283 | extra_query = self._EncodeParameters(extra_params)
284 | # Add it to the existing query
285 | if query:
286 | query += '&' + extra_query
287 | else:
288 | query = extra_query
289 |
290 | # Return the rebuilt URL
291 | return urlunparse((scheme, netloc, path, params, query, fragment))
292 |
293 | def _EncodeParameters(self, parameters):
294 | """
295 | Return a string in key=value&key=value form.
296 | :param parameters: A dict of (key, value) tuples, where value is encoded as specified by self._encoding
297 | :return:A URL-encoded string in "key=value&key=value" form
298 | """
299 |
300 | if parameters is None:
301 | return None
302 | else:
303 | return urlencode(dict([(k, self._Encode(v)) for k, v in list(parameters.items()) if v is not None]))
304 |
305 | def _Encode(self, s):
306 | if self._input_encoding:
307 | return str(s, self._input_encoding).encode('utf-8')
308 | else:
309 | return str(s).encode('utf-8')
310 |
--------------------------------------------------------------------------------
/testdata/get_comps.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | 2100641621
7 | 10
8 |
9 |
10 | Request successfully processed
11 | 0
12 |
13 |
14 |
15 |
16 | 2100641621
17 |
18 |
19 | http://www.zillow.com/homedetails/3400-Pacific-Ave-APT-201-Marina-Del-Rey-CA-90292/2100641621_zpid/
20 |
21 | http://www.zillow.com/homes/2100641621_zpid/
22 | http://www.zillow.com/homes/comps/2100641621_zpid/
23 |
24 |
25 | 3400 Pacific Ave APT 201
26 | 90292
27 | Marina Del Rey
28 | CA
29 | 33.9781
30 | -118.4643
31 |
32 |
33 | 1723665
34 | 01/03/2016
35 |
36 | 108687
37 |
38 | 1551299
39 | 1878795
40 |
41 | 0
42 |
43 |
44 |
45 | 1,189,300
46 |
47 | http://www.zillow.com/local-info/CA-Los-Angeles/Venice/r_21056/
48 | http://www.zillow.com/venice-los-angeles-ca/fsbo/
49 | http://www.zillow.com/venice-los-angeles-ca/
50 |
51 |
52 |
53 |
54 |
55 |
56 | 20385517
57 |
58 |
59 | http://www.zillow.com/homedetails/8218-Pershing-Dr-Playa-Del-Rey-CA-90293/20385517_zpid/
60 |
61 |
62 | http://www.zillow.com/homedetails/8218-Pershing-Dr-Playa-Del-Rey-CA-90293/20385517_zpid/#charts-and-data
63 |
64 | http://www.zillow.com/homes/20385517_zpid/
65 | http://www.zillow.com/homes/comps/20385517_zpid/
66 |
67 |
68 | 8218 Pershing Dr
69 | 90293
70 | Playa Del Rey
71 | CA
72 | 33.958924
73 | -118.443805
74 |
75 |
76 | 1390989
77 | 01/03/2016
78 |
79 | -17446
80 |
81 | 1321440
82 | 1474448
83 |
84 | 89
85 |
86 |
87 |
88 | 659,600
89 |
90 | http://www.zillow.com/local-info/CA-Los-Angeles/Playa-Del-Rey/r_276514/
91 |
92 | http://www.zillow.com/playa-del-rey-los-angeles-ca/fsbo/
93 |
94 | http://www.zillow.com/playa-del-rey-los-angeles-ca/
95 |
96 |
97 |
98 |
99 |
100 | 20386027
101 |
102 |
103 | http://www.zillow.com/homedetails/6600-Vista-Del-Mar-Playa-Del-Rey-CA-90293/20386027_zpid/
104 |
105 |
106 | http://www.zillow.com/homedetails/6600-Vista-Del-Mar-Playa-Del-Rey-CA-90293/20386027_zpid/#charts-and-data
107 |
108 | http://www.zillow.com/homes/20386027_zpid/
109 | http://www.zillow.com/homes/comps/20386027_zpid/
110 |
111 |
112 | 6600 Vista Del Mar
113 | 90293
114 | Playa Del Rey
115 | CA
116 | 33.960982
117 | -118.449937
118 |
119 |
120 | 1759474
121 | 01/03/2016
122 |
123 | 3815
124 |
125 | 1601121
126 | 1953016
127 |
128 | 94
129 |
130 |
131 |
132 | 659,600
133 |
134 | http://www.zillow.com/local-info/CA-Los-Angeles/Playa-Del-Rey/r_276514/
135 |
136 | http://www.zillow.com/playa-del-rey-los-angeles-ca/fsbo/
137 |
138 | http://www.zillow.com/playa-del-rey-los-angeles-ca/
139 |
140 |
141 |
142 |
143 |
144 | 20386096
145 |
146 |
147 | http://www.zillow.com/homedetails/380-Pershing-Dr-Playa-Del-Rey-CA-90293/20386096_zpid/
148 |
149 |
150 | http://www.zillow.com/homedetails/380-Pershing-Dr-Playa-Del-Rey-CA-90293/20386096_zpid/#charts-and-data
151 |
152 | http://www.zillow.com/homes/20386096_zpid/
153 | http://www.zillow.com/homes/comps/20386096_zpid/
154 |
155 |
156 | 380 Pershing Dr
157 | 90293
158 | Playa Del Rey
159 | CA
160 | 33.96002
161 | -118.44595
162 |
163 |
164 | 1076441
165 | 01/03/2016
166 |
167 | -8721
168 |
169 | 990326
170 | 1173321
171 |
172 | 72
173 |
174 |
175 |
176 | 659,600
177 |
178 | http://www.zillow.com/local-info/CA-Los-Angeles/Playa-Del-Rey/r_276514/
179 |
180 | http://www.zillow.com/playa-del-rey-los-angeles-ca/fsbo/
181 |
182 | http://www.zillow.com/playa-del-rey-los-angeles-ca/
183 |
184 |
185 |
186 |
187 |
188 | 20386518
189 |
190 |
191 | http://www.zillow.com/homedetails/6959-Trolleyway-Playa-Del-Rey-CA-90293/20386518_zpid/
192 |
193 |
194 | http://www.zillow.com/homedetails/6959-Trolleyway-Playa-Del-Rey-CA-90293/20386518_zpid/#charts-and-data
195 |
196 | http://www.zillow.com/homes/20386518_zpid/
197 | http://www.zillow.com/homes/comps/20386518_zpid/
198 |
199 |
200 | 6959 Trolleyway
201 | 90293
202 | PLAYA DEL REY
203 | CA
204 | 33.956705
205 | -118.449885
206 |
207 |
208 | 2317353
209 | 01/03/2016
210 |
211 | 16544
212 |
213 | 2178312
214 | 2433221
215 |
216 | 97
217 |
218 |
219 |
220 | 659,600
221 |
222 | http://www.zillow.com/local-info/CA-Los-Angeles/Playa-Del-Rey/r_276514/
223 |
224 | http://www.zillow.com/playa-del-rey-los-angeles-ca/fsbo/
225 |
226 | http://www.zillow.com/playa-del-rey-los-angeles-ca/
227 |
228 |
229 |
230 |
231 |
232 | 20488022
233 |
234 |
235 | http://www.zillow.com/homedetails/4200-Via-Dolce-APT-329-Marina-Del-Rey-CA-90292/20488022_zpid/
236 |
237 |
238 | http://www.zillow.com/homedetails/4200-Via-Dolce-APT-329-Marina-Del-Rey-CA-90292/20488022_zpid/#charts-and-data
239 |
240 | http://www.zillow.com/homes/20488022_zpid/
241 | http://www.zillow.com/homes/comps/20488022_zpid/
242 |
243 |
244 | 4200 Via Dolce APT 329
245 | 90292
246 | Marina Del Rey
247 | CA
248 | 33.9749
249 | -118.458885
250 |
251 |
252 | 1134517
253 | 01/03/2016
254 |
255 | 13519
256 |
257 | 964339
258 | 1247969
259 |
260 | 71
261 |
262 |
263 |
264 | 1,189,300
265 |
266 | http://www.zillow.com/local-info/CA-Los-Angeles/Venice/r_21056/
267 | http://www.zillow.com/venice-los-angeles-ca/fsbo/
268 | http://www.zillow.com/venice-los-angeles-ca/
269 |
270 |
271 |
272 |
273 |
274 | 20449108
275 |
276 |
277 | http://www.zillow.com/homedetails/3913-Beethoven-St-Los-Angeles-CA-90066/20449108_zpid/
278 |
279 |
280 | http://www.zillow.com/homedetails/3913-Beethoven-St-Los-Angeles-CA-90066/20449108_zpid/#charts-and-data
281 |
282 | http://www.zillow.com/homes/20449108_zpid/
283 | http://www.zillow.com/homes/comps/20449108_zpid/
284 |
285 |
286 | 3913 Beethoven St
287 | 90066
288 | Los Angeles
289 | CA
290 | 33.99762
291 | -118.439924
292 |
293 |
294 |
295 | 12/31/1969
296 |
297 |
298 |
299 |
300 |
301 |
302 | 0
303 |
304 |
305 |
306 | 904,500
307 |
308 | http://www.zillow.com/local-info/CA-Los-Angeles/Mar-Vista/r_116415/
309 | http://www.zillow.com/mar-vista-los-angeles-ca/fsbo/
310 | http://www.zillow.com/mar-vista-los-angeles-ca/
311 |
312 |
313 |
314 |
315 |
316 | 20440534
317 |
318 |
319 | http://www.zillow.com/homedetails/4635-Lindblade-Dr-Culver-City-CA-90230/20440534_zpid/
320 |
321 |
322 | http://www.zillow.com/homedetails/4635-Lindblade-Dr-Culver-City-CA-90230/20440534_zpid/#charts-and-data
323 |
324 | http://www.zillow.com/homes/20440534_zpid/
325 | http://www.zillow.com/homes/comps/20440534_zpid/
326 |
327 |
328 | 4635 Lindblade Dr
329 | 90230
330 | Culver City
331 | CA
332 | 33.992424
333 | -118.417577
334 |
335 |
336 | 1567413
337 | 01/03/2016
338 |
339 | 64273
340 |
341 | 1410672
342 | 1708480
343 |
344 | 99
345 |
346 |
347 |
348 | 714,400
349 |
350 | http://www.zillow.com/local-info/CA-Los-Angeles/Del-Rey/r_403184/
351 | http://www.zillow.com/del-rey-los-angeles-ca/fsbo/
352 | http://www.zillow.com/del-rey-los-angeles-ca/
353 |
354 |
355 |
356 |
357 |
358 | 20386023
359 |
360 |
361 | http://www.zillow.com/homedetails/6665-Vista-Del-Mar-Playa-Del-Rey-CA-90293/20386023_zpid/
362 |
363 |
364 | http://www.zillow.com/homedetails/6665-Vista-Del-Mar-Playa-Del-Rey-CA-90293/20386023_zpid/#charts-and-data
365 |
366 | http://www.zillow.com/homes/20386023_zpid/
367 | http://www.zillow.com/homes/comps/20386023_zpid/
368 |
369 |
370 | 6665 Vista Del Mar
371 | 90293
372 | Playa Del Rey
373 | CA
374 | 33.959986
375 | -118.448809
376 |
377 |
378 | 2015266
379 | 01/03/2016
380 |
381 | 2306
382 |
383 | 1874197
384 | 2116029
385 |
386 | 96
387 |
388 |
389 |
390 | 659,600
391 |
392 | http://www.zillow.com/local-info/CA-Los-Angeles/Playa-Del-Rey/r_276514/
393 |
394 | http://www.zillow.com/playa-del-rey-los-angeles-ca/fsbo/
395 |
396 | http://www.zillow.com/playa-del-rey-los-angeles-ca/
397 |
398 |
399 |
400 |
401 |
402 | 20386791
403 |
404 | http://www.zillow.com/homedetails/442-Manitoba-St-Venice-CA-90293/20386791_zpid/
405 |
406 |
407 | http://www.zillow.com/homedetails/442-Manitoba-St-Venice-CA-90293/20386791_zpid/#charts-and-data
408 |
409 | http://www.zillow.com/homes/20386791_zpid/
410 | http://www.zillow.com/homes/comps/20386791_zpid/
411 |
412 |
413 | 442 Manitoba St
414 | 90293
415 | Venice
416 | CA
417 | 33.95358
418 | -118.44088
419 |
420 |
421 | 1706793
422 | 01/03/2016
423 |
424 | 3757
425 |
426 | 1536114
427 | 1826269
428 |
429 | 93
430 |
431 |
432 |
433 | 659,600
434 |
435 | http://www.zillow.com/local-info/CA-Los-Angeles/Playa-Del-Rey/r_276514/
436 |
437 | http://www.zillow.com/playa-del-rey-los-angeles-ca/fsbo/
438 |
439 | http://www.zillow.com/playa-del-rey-los-angeles-ca/
440 |
441 |
442 |
443 |
444 |
445 | 20386560
446 |
447 |
448 | http://www.zillow.com/homedetails/100-Sunridge-St-Playa-Del-Rey-CA-90293/20386560_zpid/
449 |
450 |
451 | http://www.zillow.com/homedetails/100-Sunridge-St-Playa-Del-Rey-CA-90293/20386560_zpid/#charts-and-data
452 |
453 | http://www.zillow.com/homes/20386560_zpid/
454 | http://www.zillow.com/homes/comps/20386560_zpid/
455 |
456 |
457 | 100 Sunridge St
458 | 90293
459 | Playa Del Rey
460 | CA
461 | 33.955205
462 | -118.448565
463 |
464 |
465 | 1805021
466 | 01/03/2016
467 |
468 | 74679
469 |
470 | 1606469
471 | 2039674
472 |
473 | 95
474 |
475 |
476 |
477 | 659,600
478 |
479 | http://www.zillow.com/local-info/CA-Los-Angeles/Playa-Del-Rey/r_276514/
480 |
481 | http://www.zillow.com/playa-del-rey-los-angeles-ca/fsbo/
482 |
483 | http://www.zillow.com/playa-del-rey-los-angeles-ca/
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
--------------------------------------------------------------------------------
/testdata/get_deep_comps.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | 2100641621
7 | 10
8 |
9 |
10 | Request successfully processed
11 | 0
12 |
13 |
14 |
15 |
16 | 2100641621
17 |
18 |
19 | http://www.zillow.com/homedetails/3400-Pacific-Ave-APT-201-Marina-Del-Rey-CA-90292/2100641621_zpid/
20 |
21 | http://www.zillow.com/homes/2100641621_zpid/
22 | http://www.zillow.com/homes/comps/2100641621_zpid/
23 |
24 |
25 | 3400 Pacific Ave APT 201
26 | 90292
27 | Marina Del Rey
28 | CA
29 | 33.9781
30 | -118.4643
31 |
32 | 3.0
33 | 2
34 |
35 | 1785490
36 | 01/15/2016
37 |
38 | 131345
39 |
40 | 1606941
41 | 1999749
42 |
43 | 0
44 |
45 |
46 |
47 | 1,189,300
48 |
49 | http://www.zillow.com/local-info/CA-Los-Angeles/Venice/r_21056/
50 | http://www.zillow.com/venice-los-angeles-ca/fsbo/
51 | http://www.zillow.com/venice-los-angeles-ca/
52 |
53 |
54 |
55 |
56 |
57 |
58 | 20440534
59 |
60 |
61 | http://www.zillow.com/homedetails/4635-Lindblade-Dr-Culver-City-CA-90230/20440534_zpid/
62 |
63 |
64 | http://www.zillow.com/homedetails/4635-Lindblade-Dr-Culver-City-CA-90230/20440534_zpid/#charts-and-data
65 |
66 | http://www.zillow.com/homes/20440534_zpid/
67 | http://www.zillow.com/homes/comps/20440534_zpid/
68 |
69 |
70 | 4635 Lindblade Dr
71 | 90230
72 | Culver City
73 | CA
74 | 33.992424
75 | -118.417577
76 |
77 | 2014
78 | 1014504.0
79 | 1950
80 | 13094
81 | 1696
82 | 5.0
83 | 6
84 | 11
85 | 06/25/2015
86 | 1517000
87 |
88 | 1583328
89 | 01/15/2016
90 |
91 | 56215
92 |
93 | 1409162
94 | 1741661
95 |
96 | 99
97 |
98 |
99 |
100 | 714,400
101 |
102 | http://www.zillow.com/local-info/CA-Los-Angeles/Del-Rey/r_403184/
103 | http://www.zillow.com/del-rey-los-angeles-ca/fsbo/
104 | http://www.zillow.com/del-rey-los-angeles-ca/
105 |
106 |
107 |
108 |
109 |
110 | 20385517
111 |
112 |
113 | http://www.zillow.com/homedetails/8218-Pershing-Dr-Playa-Del-Rey-CA-90293/20385517_zpid/
114 |
115 |
116 | http://www.zillow.com/homedetails/8218-Pershing-Dr-Playa-Del-Rey-CA-90293/20385517_zpid/#charts-and-data
117 |
118 | http://www.zillow.com/homes/20385517_zpid/
119 | http://www.zillow.com/homes/comps/20385517_zpid/
120 |
121 |
122 | 8218 Pershing Dr
123 | 90293
124 | Playa Del Rey
125 | CA
126 | 33.958924
127 | -118.443805
128 |
129 | 2015
130 | 360098.0
131 | 1958
132 | 5000
133 | 2223
134 | 3.0
135 | 5
136 | 12/01/2015
137 | 1150000
138 |
139 | 1369608
140 | 01/15/2016
141 |
142 | -33526
143 |
144 | 1301128
145 | 1479177
146 |
147 | 89
148 |
149 |
150 |
151 | 659,600
152 |
153 | http://www.zillow.com/local-info/CA-Los-Angeles/Playa-Del-Rey/r_276514/
154 |
155 | http://www.zillow.com/playa-del-rey-los-angeles-ca/fsbo/
156 |
157 | http://www.zillow.com/playa-del-rey-los-angeles-ca/
158 |
159 |
160 |
161 |
162 |
163 | 20386027
164 |
165 |
166 | http://www.zillow.com/homedetails/6600-Vista-Del-Mar-Playa-Del-Rey-CA-90293/20386027_zpid/
167 |
168 |
169 | http://www.zillow.com/homedetails/6600-Vista-Del-Mar-Playa-Del-Rey-CA-90293/20386027_zpid/#charts-and-data
170 |
171 | http://www.zillow.com/homes/20386027_zpid/
172 | http://www.zillow.com/homes/comps/20386027_zpid/
173 |
174 |
175 | 6600 Vista Del Mar
176 | 90293
177 | Playa Del Rey
178 | CA
179 | 33.960982
180 | -118.449937
181 |
182 | 2015
183 | 1200000.0
184 | 1969
185 | 2400
186 | 2784
187 | 4.0
188 | 4
189 | 04/21/2015
190 | 1650000
191 |
192 | 1765634
193 | 01/15/2016
194 |
195 | 9286
196 |
197 | 1642040
198 | 1906885
199 |
200 | 94
201 |
202 |
203 |
204 | 659,600
205 |
206 | http://www.zillow.com/local-info/CA-Los-Angeles/Playa-Del-Rey/r_276514/
207 |
208 | http://www.zillow.com/playa-del-rey-los-angeles-ca/fsbo/
209 |
210 | http://www.zillow.com/playa-del-rey-los-angeles-ca/
211 |
212 |
213 |
214 |
215 |
216 | 20386096
217 |
218 |
219 | http://www.zillow.com/homedetails/380-Pershing-Dr-Playa-Del-Rey-CA-90293/20386096_zpid/
220 |
221 |
222 | http://www.zillow.com/homedetails/380-Pershing-Dr-Playa-Del-Rey-CA-90293/20386096_zpid/#charts-and-data
223 |
224 | http://www.zillow.com/homes/20386096_zpid/
225 | http://www.zillow.com/homes/comps/20386096_zpid/
226 |
227 |
228 | 380 Pershing Dr
229 | 90293
230 | Playa Del Rey
231 | CA
232 | 33.96002
233 | -118.44595
234 |
235 | 2014
236 | 875000.0
237 | 1955
238 | 4829
239 | 1818
240 | 2.0
241 | 4
242 | 05/29/2015
243 | 1125000
244 |
245 | 1063110
246 | 01/15/2016
247 |
248 | -20243
249 |
250 | 978061
251 | 1148159
252 |
253 | 71
254 |
255 |
256 |
257 | 659,600
258 |
259 | http://www.zillow.com/local-info/CA-Los-Angeles/Playa-Del-Rey/r_276514/
260 |
261 | http://www.zillow.com/playa-del-rey-los-angeles-ca/fsbo/
262 |
263 | http://www.zillow.com/playa-del-rey-los-angeles-ca/
264 |
265 |
266 |
267 |
268 |
269 | 20386518
270 |
271 |
272 | http://www.zillow.com/homedetails/6959-Trolleyway-Playa-Del-Rey-CA-90293/20386518_zpid/
273 |
274 |
275 | http://www.zillow.com/homedetails/6959-Trolleyway-Playa-Del-Rey-CA-90293/20386518_zpid/#charts-and-data
276 |
277 | http://www.zillow.com/homes/20386518_zpid/
278 | http://www.zillow.com/homes/comps/20386518_zpid/
279 |
280 |
281 | 6959 Trolleyway
282 | 90293
283 | PLAYA DEL REY
284 | CA
285 | 33.956705
286 | -118.449885
287 |
288 | 2014
289 | 277419.0
290 | 1955
291 | 3268
292 | 3580
293 | 3.0
294 | 3
295 | 03/18/2015
296 | 2400000
297 |
298 | 2333585
299 | 01/15/2016
300 |
301 | 27028
302 |
303 | 2193570
304 | 2450264
305 |
306 | 97
307 |
308 |
309 |
310 | 659,600
311 |
312 | http://www.zillow.com/local-info/CA-Los-Angeles/Playa-Del-Rey/r_276514/
313 |
314 | http://www.zillow.com/playa-del-rey-los-angeles-ca/fsbo/
315 |
316 | http://www.zillow.com/playa-del-rey-los-angeles-ca/
317 |
318 |
319 |
320 |
321 |
322 | 20488022
323 |
324 |
325 | http://www.zillow.com/homedetails/4200-Via-Dolce-APT-329-Marina-Del-Rey-CA-90292/20488022_zpid/
326 |
327 |
328 | http://www.zillow.com/homedetails/4200-Via-Dolce-APT-329-Marina-Del-Rey-CA-90292/20488022_zpid/#charts-and-data
329 |
330 | http://www.zillow.com/homes/20488022_zpid/
331 | http://www.zillow.com/homes/comps/20488022_zpid/
332 |
333 |
334 | 4200 Via Dolce APT 329
335 | 90292
336 | Marina Del Rey
337 | CA
338 | 33.9749
339 | -118.458885
340 |
341 | 2015
342 | 797822.0
343 | 1974
344 | 191287
345 | 1880
346 | 3.0
347 | 3
348 | 11/20/2015
349 | 1000000
350 |
351 | 1134361
352 | 01/15/2016
353 |
354 | 8288
355 |
356 | 986894
357 | 1247797
358 |
359 | 71
360 |
361 |
362 |
363 | 1,189,300
364 |
365 | http://www.zillow.com/local-info/CA-Los-Angeles/Venice/r_21056/
366 | http://www.zillow.com/venice-los-angeles-ca/fsbo/
367 | http://www.zillow.com/venice-los-angeles-ca/
368 |
369 |
370 |
371 |
372 |
373 | 20386791
374 |
375 | http://www.zillow.com/homedetails/442-Manitoba-St-Venice-CA-90293/20386791_zpid/
376 |
377 |
378 | http://www.zillow.com/homedetails/442-Manitoba-St-Venice-CA-90293/20386791_zpid/#charts-and-data
379 |
380 | http://www.zillow.com/homes/20386791_zpid/
381 | http://www.zillow.com/homes/comps/20386791_zpid/
382 |
383 |
384 | 442 Manitoba St
385 | 90293
386 | Venice
387 | CA
388 | 33.95358
389 | -118.44088
390 |
391 | 2014
392 | 425142.0
393 | 1962
394 | 5003
395 | 3120
396 | 6.0
397 | 6
398 | 06/02/2015
399 | 1150000
400 |
401 | 1706793
402 | 01/15/2016
403 |
404 | 26301
405 |
406 | 1536114
407 | 1826269
408 |
409 | 93
410 |
411 |
412 |
413 | 659,600
414 |
415 | http://www.zillow.com/local-info/CA-Los-Angeles/Playa-Del-Rey/r_276514/
416 |
417 | http://www.zillow.com/playa-del-rey-los-angeles-ca/fsbo/
418 |
419 | http://www.zillow.com/playa-del-rey-los-angeles-ca/
420 |
421 |
422 |
423 |
424 |
425 | 20386560
426 |
427 |
428 | http://www.zillow.com/homedetails/100-Sunridge-St-Playa-Del-Rey-CA-90293/20386560_zpid/
429 |
430 |
431 | http://www.zillow.com/homedetails/100-Sunridge-St-Playa-Del-Rey-CA-90293/20386560_zpid/#charts-and-data
432 |
433 | http://www.zillow.com/homes/20386560_zpid/
434 | http://www.zillow.com/homes/comps/20386560_zpid/
435 |
436 |
437 | 100 Sunridge St
438 | 90293
439 | Playa Del Rey
440 | CA
441 | 33.955205
442 | -118.448565
443 |
444 | 2015
445 | 134384.0
446 | 1956
447 | 2552
448 | 2072
449 | 2.0
450 | 6
451 | 12/15/2015
452 | 1650000
453 |
454 | 1818930
455 | 01/15/2016
456 |
457 | 60079
458 |
459 | 1618848
460 | 2037202
461 |
462 | 95
463 |
464 |
465 |
466 | 659,600
467 |
468 | http://www.zillow.com/local-info/CA-Los-Angeles/Playa-Del-Rey/r_276514/
469 |
470 | http://www.zillow.com/playa-del-rey-los-angeles-ca/fsbo/
471 |
472 | http://www.zillow.com/playa-del-rey-los-angeles-ca/
473 |
474 |
475 |
476 |
477 |
478 | 20386023
479 |
480 |
481 | http://www.zillow.com/homedetails/6665-Vista-Del-Mar-Playa-Del-Rey-CA-90293/20386023_zpid/
482 |
483 |
484 | http://www.zillow.com/homedetails/6665-Vista-Del-Mar-Playa-Del-Rey-CA-90293/20386023_zpid/#charts-and-data
485 |
486 | http://www.zillow.com/homes/20386023_zpid/
487 | http://www.zillow.com/homes/comps/20386023_zpid/
488 |
489 |
490 | 6665 Vista Del Mar
491 | 90293
492 | Playa Del Rey
493 | CA
494 | 33.959986
495 | -118.448809
496 |
497 | 2014
498 | 1017925.0
499 | 1954
500 | 2701
501 | 3030
502 | 4.0
503 | 4
504 | 8
505 | 07/27/2015
506 | 1750000
507 |
508 | 2072781
509 | 01/15/2016
510 |
511 | 57788
512 |
513 | 1927686
514 | 2176420
515 |
516 | 96
517 |
518 |
519 |
520 | 659,600
521 |
522 | http://www.zillow.com/local-info/CA-Los-Angeles/Playa-Del-Rey/r_276514/
523 |
524 | http://www.zillow.com/playa-del-rey-los-angeles-ca/fsbo/
525 |
526 | http://www.zillow.com/playa-del-rey-los-angeles-ca/
527 |
528 |
529 |
530 |
531 |
532 | 2138006586
533 |
534 |
535 | http://www.zillow.com/homedetails/100-Sunridge-St-Playa-Del-Rey-CA-90293/2138006586_zpid/
536 |
537 | http://www.zillow.com/homes/2138006586_zpid/
538 | http://www.zillow.com/homes/comps/2138006586_zpid/
539 |
540 |
541 | 100 Sunridge St
542 | 90293
543 | Playa Del Rey
544 | CA
545 | 33.955202
546 | -118.448554
547 |
548 | 1956
549 | 111949200
550 | 1872
551 | 2.0
552 | 6
553 | 12/15/2015
554 | 1650000
555 |
556 | 1963142
557 | 01/15/2016
558 |
559 | 89534
560 |
561 | 1707934
562 | 2139825
563 |
564 | 0
565 |
566 |
567 |
568 | 659,600
569 |
570 | http://www.zillow.com/local-info/CA-Los-Angeles/Playa-Del-Rey/r_276514/
571 |
572 | http://www.zillow.com/playa-del-rey-los-angeles-ca/fsbo/
573 |
574 | http://www.zillow.com/playa-del-rey-los-angeles-ca/
575 |
576 |
577 |
578 |
579 |
580 |
581 |
582 |
--------------------------------------------------------------------------------