How to get real estate data with Idealista API?
Asked Answered
D

5

5

I've been trying to use the API of the website Idealista (https://www.idealista.com/) to retrieve information of real estate data.

Since I'm not familiarized with OAuth2 I haven't been able to obtain the token so far. I have just been provided with the api key, the secret and some basic info of how to mount the http request.

I would appreciate an example (preferably in Python) of the functioning of this API, or else some more generic info about dealing with OAuth2 and Python.

Dyslalia answered 13/10, 2016 at 14:32 Comment(0)
D
7

After some days of research I came up with a basic python code to retrieve real estate data from the Idealista API.

def get_oauth_token():
http_obj = Http()
url = "https://api.idealista.com/oauth/token"
apikey= urllib.parse.quote_plus('Provided_API_key')
secret= urllib.parse.quote_plus('Provided_API_secret')
auth = base64.encode(apikey + ':' + secret)
body = {'grant_type':'client_credentials'}
headers = {'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8','Authorization' : 'Basic ' + auth}
resp, content = http_obj.request(url,method='POST',headers=headers, body=urllib.parse.urlencode(body))
return content

This function would return a JSON with the OAuth2 token and the session time in seconds. Afterwards, to query the API, it would be as simple as:

def search_api(token):
http_obj = Http()
url = "http://api.idealista.com/3.5/es/search?center=40.42938099999995,-3.7097526269835726&country=es&maxItems=50&numPage=1&distance=452&propertyType=bedrooms&operation=rent"
headers = {'Authorization' : 'Bearer ' + token}
resp, content = http_obj.request(url,method='POST',headers=headers)
return content

This time the we would find in the content var the data we were looking for, again as a JSON.

Dyslalia answered 18/10, 2016 at 11:5 Comment(4)
cool, http_obj is an instance of what? what libraries need to be imported? thanks!Knudson
Hey @Nabla, It has been a while but I think I was using httplib2. However you can do the same with other frameworks, like requests in python 3.Dyslalia
Hi good point. Where did you find the docs for this?Sibeal
Back then I got some docs sent from [email protected] after requesting access.Dyslalia
R
2

This is my code, improving #3... this run ok! for me!!!! only put your apikey and your password (secret)...

import pandas as pd
import json
import urllib
import requests as rq
import base64

def get_oauth_token():
    url = "https://api.idealista.com/oauth/token"    
    apikey= 'your_api_key' #sent by idealista
    secret= 'your_password'  #sent by idealista
    auth = base64.b64encode(apikey + ':' + secret)
    headers = {'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8' ,'Authorization' : 'Basic ' + auth}
    params = urllib.urlencode({'grant_type':'client_credentials'})
    content = rq.post(url,headers = headers, params=params)
    bearer_token = json.loads(content.text)['access_token']
    return bearer_token

def search_api(token, url):  
    headers = {'Content-Type': 'Content-Type: multipart/form-data;', 'Authorization' : 'Bearer ' + token}
    content = rq.post(url, headers = headers)
    result = json.loads(content.text)['access_token']
    return result

country = 'es' #values: es, it, pt
locale = 'es' #values: es, it, pt, en, ca
language = 'es' #
max_items = '50'
operation = 'sale' 
property_type = 'homes'
order = 'priceDown' 
center = '40.4167,-3.70325' 
distance = '60000'
sort = 'desc'
bankOffer = 'false'

df_tot = pd.DataFrame()
limit = 10

for i in range(1,limit):
    url = ('https://api.idealista.com/3.5/'+country+'/search?operation='+operation+#"&locale="+locale+
           '&maxItems='+max_items+
           '&order='+order+
           '&center='+center+
           '&distance='+distance+
           '&propertyType='+property_type+
           '&sort='+sort+ 
           '&numPage=%s'+
           '&language='+language) %(i)  
    a = search_api(get_oauth_token(), url)
    df = pd.DataFrame.from_dict(a['elementList'])
    df_tot = pd.concat([df_tot,df])

df_tot = df_tot.reset_index()
Replete answered 9/4, 2018 at 13:38 Comment(2)
there's a lot of unnecessary code, commented out code. clean it up and post only the essentialNeuter
Hello @Ivan. Can you filter results for a single real state agent with this API?Doublehung
A
2

That can't be marked as correct answer since

auth = base64.encode(apikey + ':' + secret)
body = {'grant_type':'client_credentials'}
headers = {'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8','Authorization' : 'Basic ' + auth}

Will give you TypeError:

can only concatenate str (not "bytes") to str 

Since base64encode returns a byte type object...

It's true Idealista API is very limited about documentation, but I think this is a better approach since I don't use unnecesary libs (Only native):

#first request
message = API_KEY + ":" + SECRET
auth = "Basic " + base64.b64encode(message.encode("ascii")).decode("ascii")

headers_dic = {"Authorization" : auth, 
               "Content-Type" : "application/x-www-form-urlencoded;charset=UTF-8"}

params_dic = {"grant_type" : "client_credentials",
              "scope" : "read"}



r = requests.post("https://api.idealista.com/oauth/token", 
                  headers = headers_dic, 
                  params = params_dic)

This works flawless with only python requests and base64 module...

regards

Amaurosis answered 4/8, 2020 at 17:33 Comment(0)
W
0

I found some mistakes. At least, I cannot run it. I believe, I improved with this:

import pandas as pd
import json
import urllib
import requests as rq
import base64

def get_oauth_token(): 

    url = "https://api.idealista.com/oauth/token"    

    apikey= 'your_api_key' #sent by idealist
    secret= 'your_password' #sent by idealista
    apikey_secret = apikey + ':' + secret
    auth = str(base64.b64encode(bytes(apikey_secret, 'utf-8')))[2:][:-1]

    headers = {'Authorization' : 'Basic ' + auth,'Content-Type': 'application/x-www-form- 
    urlencoded;charset=UTF-8'}
    params = urllib.parse.urlencode({'grant_type':'client_credentials'}) #,'scope':'read'
    content = rq.post(url,headers = headers, params=params)
    bearer_token = json.loads(content.text)['access_token']

    return bearer_token


def search_api(token, URL):  
    headers = {'Content-Type': 'Content-Type: multipart/form-data;', 'Authorization' : 'Bearer ' + token}
    content = rq.post(url, headers = headers)
    result = json.loads(content.text)

    return result
Whisenhunt answered 17/5, 2020 at 11:4 Comment(0)
H
0

This works:

import requests
import base64
import urllib.parse

def get_oauth_token():
    url = "https://api.idealista.com/oauth/token"

    # Your API key and secret (replace with your actual key and secret)
    api_key = 'your_string'
    api_secret = 'your_string'

    # URL encode your key and secret, concatenate them, and encode to Base64
    apikey_encoded = urllib.parse.quote_plus(api_key)
    secret_encoded = urllib.parse.quote_plus(api_secret)
    credentials = f"{apikey_encoded}:{secret_encoded}"
    encoded_credentials = base64.b64encode(credentials.encode()).decode()

    headers = {
        'Authorization': 'Basic ' + encoded_credentials,
        'Content-Type': 'application/x-www-form-urlencoded'
    }

    body = {
        'grant_type': 'client_credentials'
    }

    # Make the POST request
    response = requests.post(url, headers=headers, data=body)

    # Handle the response
    if response.status_code == 200:
        return response.json()  # Returns the JSON response with the token
    else:
        raise Exception(f"Failed to obtain token: {response.status_code}, {response.text}")

# Use the function to get the token
# try:
#     token_info = get_oauth_token()
#     print("Access Token:", token_info.get("access_token"))
# except Exception as e:
#     print("Error:", e)

def search_api(token):
    url = "https://api.idealista.com/3.5/es/search"
    headers = {'Authorization': 'Bearer ' + token}

    # Parameters for the API request
    params = {
        'center': '40.42938099999995,-3.7097526269835726',
        'country': 'es',
        'maxItems': '50',
        'numPage': '1',
        'distance': '452',
        'propertyType': 'bedrooms',
        'operation': 'rent'
    }

    # Make the GET or POST request
    # If your API requires a GET request, change it to requests.get
    response = requests.post(url, headers=headers, params=params)

    # Handle the response
    if response.status_code == 200:
        return response.json()  # Returns the JSON response
    else:
        raise Exception(f"API request failed: {response.status_code}, {response.text}")

# Usage example
# token = "your_access_token"
# try:
#     result = search_api(token)
#     print(result)
# except Exception as e:
#     print("Error:", e)

TOKEN = 'returned_string'

try:
    result = search_api(TOKEN)
    print(result)
except Exception as e:
    print("Error:", e)
Hemotherapy answered 30/12, 2023 at 23:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.