How to Create an App that Gets the Latest Sold Prices from eBay
Creating an app that retrieves the latest sold prices from eBay involves leveraging eBay’s APIs to fetch real-time data. This guide will walk you through the process, from setting up your development environment to handling API responses.
Step-by-Step Guide
1. Register for an eBay Developer Account
- Visit the eBay Developer Program and sign up for an account.
- Create an application to obtain your API keys (App ID, Cert ID, and Dev ID).
2. Choose the Appropriate API
- eBay Finding API: Use this for searching and retrieving data about items listed on eBay, including sold items.
- eBay Shopping API: Use this for retrieving detailed information about specific items, including price and availability.
- eBay Buy API: This API includes the
search
endpoint, which provides sales data for the past 90 days.
3. Set Up Your Development Environment
- Choose a programming language and framework (e.g., Python, Node.js).
- Install necessary libraries (e.g.,
requests
for Python,axios
for Node.js).
4. Make API Calls
- Use the API keys obtained during registration to authenticate your requests.
- For example, using the eBay Finding API to search for sold items:
Example: Using the eBay Finding API with Python
import requests
def get_sold_items(keywords):
url = 'https://svcs.ebay.com/services/search/FindingService/v1'
params = {
'OPERATION-NAME': 'findCompletedItems',
'SERVICE-VERSION': '1.0.0',
'SECURITY-APPNAME': 'YourAppID', # Replace with your App ID
'RESPONSE-DATA-FORMAT': 'JSON',
'REST-PAYLOAD': '',
'keywords': keywords,
'itemFilter(0).name': 'SoldItemsOnly',
'itemFilter(0).value': 'true'
}
response = requests.get(url, params=params)
return response.json()
# Example usage
sold_items = get_sold_items('laptop')
print(sold_items)
5. Handle API Responses
- Parse the JSON response to extract relevant data such as item title, sold price, and date sold.
- Display this data in your application.
Here’s an example of how to handle API responses from eBay, parse the JSON, extract relevant data, and display it in your application:
import requests
from datetime import datetime
def get_sold_items(keywords):
url = 'https://svcs.ebay.com/services/search/FindingService/v1'
params = {
'OPERATION-NAME': 'findCompletedItems',
'SERVICE-VERSION': '1.0.0',
'SECURITY-APPNAME': 'YourAppID', # Replace with your App ID
'RESPONSE-DATA-FORMAT': 'JSON',
'REST-PAYLOAD': '',
'keywords': keywords,
'itemFilter(0).name': 'SoldItemsOnly',
'itemFilter(0).value': 'true'
}
response = requests.get(url, params=params)
return response.json()
def parse_sold_items(json_data):
parsed_items = []
try:
items = json_data['findCompletedItemsResponse'][0]['searchResult'][0]['item']
for item in items:
parsed_item = {
'title': item['title'][0],
'price': float(item['sellingStatus'][0]['currentPrice'][0]['__value__']),
'currency': item['sellingStatus'][0]['currentPrice'][0]['@currencyId'],
'end_time': datetime.strptime(item['listingInfo'][0]['endTime'][0], "%Y-%m-%dT%H:%M:%S.%fZ"),
'url': item['viewItemURL'][0]
}
parsed_items.append(parsed_item)
except KeyError as e:
print(f"Error parsing JSON: {e}")
return parsed_items
def display_sold_items(items):
print("\nRecently Sold Items:")
print("--------------------")
for item in items:
print(f"Title: {item['title']}")
print(f"Price: {item['currency']} {item['price']:.2f}")
print(f"Sold on: {item['end_time'].strftime('%Y-%m-%d %H:%M:%S')}")
print(f"URL: {item['url']}")
print("--------------------")
# Main application flow
keywords = input("Enter search keywords: ")
json_data = get_sold_items(keywords)
parsed_items = parse_sold_items(json_data)
display_sold_items(parsed_items)
This example demonstrates how to:
- Make the API call using the
get_sold_items
function. - Parse the JSON response with the
parse_sold_items
function, which extracts relevant data such as item title, sold price, currency, end time, and item URL. - Display the data using the
display_sold_items
function, which formats and prints the extracted information.
The main application flow at the bottom shows how these functions work together:
- It prompts the user for search keywords.
- It calls
get_sold_items
to fetch data from eBay’s API. - It passes the JSON response to
parse_sold_items
to extract the relevant data. - Finally, it calls
display_sold_items
to show the formatted results.
This approach separates concerns, making the code more modular and easier to maintain. You can easily modify the parse_sold_items
function to extract additional data fields if needed, and adjust the display_sold_items
function to change how the data is presented.
For a web application, you might replace the display_sold_items
function with code that renders the data in HTML, or for a mobile app, you could use this data to populate a list view or other UI components.
Remember to handle potential errors, such as network issues or unexpected JSON structures, to make your application more robust. The example includes basic error handling in the parsing function, but you may want to expand on this depending on your specific requirements.
6. Implement Error Handling and Rate Limiting
- Ensure your app handles errors gracefully and respects eBay’s API rate limits to avoid being throttled.
Here’s a detailed example of how to implement error handling and rate limiting for an eBay API application:
import requests
import time
from requests.exceptions import RequestException
from ratelimit import limits, sleep_and_retry
class EbayAPIClient:
BASE_URL = 'https://api.ebay.com/buy/browse/v1'
CALLS_PER_SECOND = 5
CALLS_PER_DAY = 5000
def __init__(self, app_id):
self.app_id = app_id
self.session = requests.Session()
self.session.headers.update({
'Authorization': f'Bearer {self.app_id}',
'X-EBAY-C-MARKETPLACE-ID': 'EBAY_US'
})
@sleep_and_retry
@limits(calls=CALLS_PER_SECOND, period=1)
@limits(calls=CALLS_PER_DAY, period=86400)
def make_request(self, endpoint, params=None):
url = f"{self.BASE_URL}/{endpoint}"
try:
response = self.session.get(url, params=params)
response.raise_for_status()
return response.json()
except RequestException as e:
self.handle_request_exception(e)
def handle_request_exception(self, exception):
if isinstance(exception, requests.HTTPError):
status_code = exception.response.status_code
if status_code == 429:
retry_after = int(exception.response.headers.get('Retry-After', 60))
print(f"Rate limit exceeded. Retrying after {retry_after} seconds.")
time.sleep(retry_after)
elif status_code in (500, 502, 503, 504):
print(f"Server error: {status_code}. Retrying in 5 seconds.")
time.sleep(5)
else:
print(f"HTTP error occurred: {status_code}")
raise
elif isinstance(exception, requests.ConnectionError):
print("Connection error occurred. Retrying in 5 seconds.")
time.sleep(5)
else:
print(f"An unexpected error occurred: {str(exception)}")
raise
def get_sold_items(self, keywords):
endpoint = 'item_summary/search'
params = {
'q': keywords,
'filter': 'soldItems',
'limit': 10
}
return self.make_request(endpoint, params)
def parse_sold_items(self, response):
items = response.get('itemSummaries', [])
return [
{
'title': item['title'],
'price': f"{item['price']['value']} {item['price']['currency']}",
'sold_date': item['soldDate'],
'url': item['itemWebUrl']
}
for item in items
]
def main():
client = EbayAPIClient('YOUR_APP_ID_HERE')
try:
keywords = input("Enter search keywords: ")
response = client.get_sold_items(keywords)
parsed_items = client.parse_sold_items(response)
print("\nRecently Sold Items:")
for item in parsed_items:
print(f"Title: {item['title']}")
print(f"Price: {item['price']}")
print(f"Sold on: {item['sold_date']}")
print(f"URL: {item['url']}")
print("--------------------")
except Exception as e:
print(f"An error occurred: {str(e)}")
if __name__ == "__main__":
main()
This example demonstrates several key aspects of error handling and rate limiting:
Rate Limiting:
- We use the
@limits
decorator from theratelimit
library to enforce rate limits. - Two limits are set: 5 calls per second and 5000 calls per day (adjust these based on eBay’s actual limits).
- The
@sleep_and_retry
decorator ensures that if a rate limit is exceeded, the function will sleep and then retry.
Error Handling:
- The
handle_request_exception
method deals with different types of exceptions:- For HTTP 429 (Too Many Requests), it reads the ‘Retry-After’ header and waits accordingly.
- For server errors (500, 502, 503, 504), it waits for 5 seconds before retrying.
- For connection errors, it also waits for 5 seconds before retrying.
- Other HTTP errors are logged and re-raised.
Graceful Degradation:
- The main function is wrapped in a try-except block to catch any unexpected errors and provide a user-friendly message.
Session Management:
- We use a
requests.Session()
object to maintain a persistent connection and headers across requests.
Parsing and Data Extraction:
- The
parse_sold_items
method extracts relevant information from the API response, demonstrating how to handle and process the data.
User Input and Output:
- The script takes user input for search keywords and displays the results in a readable format.
To use this script:
- Replace ‘YOUR_APP_ID_HERE’ with your actual eBay API App ID.
- Ensure you have the required libraries installed (
requests
andratelimit
). - Run the script and enter search keywords when prompted.
This implementation provides a robust foundation for handling errors and respecting rate limits when interacting with eBay’s API. It can be further customized based on specific needs and eBay’s exact API specifications.
7. Deploy Your Application
- Choose a hosting service (e.g., Heroku, AWS, Google Cloud) to deploy your application.
- Ensure your app is secure and scalable.
Best Practices for Scraping eBay Data
- Review eBay’s Terms of Service and Robots.txt: Ensure compliance with eBay’s policies.
- Throttling Requests: Mimic human browsing speeds to avoid overloading eBay’s servers.
- User-Agent and Headers: Send a User-Agent string with your requests to simulate a real browser session.
- Handle Pagination: Navigate through multiple pages of listings correctly.
- Respect Data Privacy: Avoid scraping personal data or infringing on eBay’s intellectual property.
- Error Handling: Implement robust error handling to manage issues like network problems and changes in website structure.
- Data Storage: Store scraped data responsibly and securely.
Most Useful eBay APIs for Real-Time Data
- eBay Finding API: For searching and retrieving data about items listed on eBay, including sold items.
- eBay Shopping API: For retrieving detailed information about specific items.
- eBay Buy API: For sales data for the past 90 days.
How to Authenticate Your Application to Use eBay’s API
- Create an eBay Developer Account: Register and create an application to obtain your API keys.
- Use OAuth 2.0: Authenticate your application using OAuth 2.0. Refer to eBay’s documentation for detailed steps on implementing OAuth.
Can You Use eBay’s API to Fetch Data for Multiple Markets Simultaneously?
You can use eBay’s API to fetch data for multiple markets simultaneously by specifying different site IDs in your API requests. eBay supports multiple international sites, and you can target specific markets by setting the siteid
parameter in your API calls.
Best Practices for Handling eBay API Rate Limits
- Monitor Your API Usage: Keep track of your API call count to avoid exceeding rate limits.
- Implement Exponential Backoff: Use exponential backoff strategies to handle rate limit errors gracefully.
- Optimize API Calls: Reduce the number of API calls by fetching only necessary data and caching results when possible.
- Request Higher Limits: If your application requires more API calls, you can request higher limits by submitting your app for a compatibility check to eBay[4].
By following these steps and best practices, you can create a robust and efficient app that retrieves the latest sold prices from eBay.
Citations:
[1] https://www.octoparse.com/blog/best-ebay-scraper-tools
[2] https://data-ox.com/ebay-scraping-2023
[3] https://oxylabs.io/blog/ebay-data-scraping-guide
[4] https://www.uvdesk.com/en/blog/increase_ebay_api_usage_limit/
[5] https://webscraping.ai/faq/ebay-scraping/what-are-the-best-practices-for-ebay-data-scraping
[6] https://forum.uipath.com/t/ebayapi-question/726736
[7] https://dev.to/satokenta/learning-the-basics-of-the-ebay-api-2kf1
[8] https://innovation.ebayinc.com/tech/product/ebays-new-apis-enable-developers-to-create-innovative-experiences-at-scale/
[9] https://www.youtube.com/watch?v=i9A3zvuMWNc
[10] https://innovation.ebayinc.com/tech/engineering/api-mindset-at-ebay/
[11] https://www.reddit.com/r/Ebay/comments/9hfnp0/100_hours_of_reading_documentation_just_to_write/
[12] https://www.reddit.com/r/CodingHelp/comments/1asahye/help_with_ebay_api/
[13] https://innovation.ebayinc.com/tech/engineering/ebays-notification-streaming-platform-how-ebay-handles-real-time-push-notifications-at-scale/
[14] https://stackoverflow.com/questions/24341580/ebay-api-call-to-revise-multiple-items-together
[15] https://scrapfly.io/blog/how-to-scrape-ebay/
[16] https://community.claris.com/en/s/question/0D53w00005Joj22CAB/how-to-integrate-ebay-api-why-cant-i-authenticate
[17] https://www.countdownapi.com/docs/ebay-product-data-api/parameters/search