Skip to content

Commit 96f0cba

Browse files
ddxvdale-wahl
andauthored
New charts url (#9) replaces collections
* Add optional timeout option to all requests * Add description of timeout option * Since API already returns all apps for a developer, add function to return all results * Update to new charts url * Rever to tabs for consistency with old library * Seems the collections need a new name to use charts API * Now API only returns IDs * Requires two letter country code, upper or lower * Requires two letter country code, upper or lower * merge fixes * update tests * fix get_app_ids_for_developers * add collection test --------- Co-authored-by: Dale Wahl <[email protected]>
1 parent b1987a0 commit 96f0cba

File tree

4 files changed

+47
-25
lines changed

4 files changed

+47
-25
lines changed

itunes_app_scraper/scraper.py

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -89,29 +89,31 @@ def get_app_ids_for_collection(self, collection="", category="", num=50, country
8989
if not collection:
9090
collection = AppStoreCollections.TOP_FREE_IOS
9191

92-
country = self.get_store_id_for_country(country)
93-
params = (collection, category, num, country)
94-
url = "http://ax.itunes.apple.com/WebObjects/MZStoreServices.woa/ws/RSS/%s/%s/limit=%s/json?s=%s" % params
92+
country = country.lower()
93+
params = (country, category, collection, num)
94+
url = "https://itunes.apple.com/WebObjects/MZStoreServices.woa/ws/charts?cc=%s&g=%s&name=%s&limit=%s" % params
95+
9596

9697
try:
9798
result = requests.get(url, timeout=timeout).json()
9899
except json.JSONDecodeError:
99100
raise AppStoreException("Could not parse app store response")
100101

101-
return [entry["id"]["attributes"]["im:id"] for entry in result["feed"]["entry"]]
102+
return result["resultIds"]
102103

103-
def get_app_ids_for_developer(self, developer_id, country="nl", lang="", timeout=None):
104+
def get_apps_for_developer(self, developer_id, country="nl", lang="", timeout=None):
104105
"""
105-
Retrieve App IDs linked to given developer
106+
Retrieve Apps linked to given developer
106107
107108
:param int developer_id: Developer ID
108109
:param str country: Two-letter country code for the store to search in.
109110
Defaults to 'nl'.
110111
:param str lang: Dummy argument for compatibility. Unused.
111112
:param int timeout: Seconds to wait for response before stopping.
112113
113-
:return list: List of App IDs linked to developer
114+
:return list[dict]: List of Apps linked to developer
114115
"""
116+
country = country.lower()
115117
url = "https://itunes.apple.com/lookup?id=%s&country=%s&entity=software" % (developer_id, country)
116118

117119
try:
@@ -120,11 +122,31 @@ def get_app_ids_for_developer(self, developer_id, country="nl", lang="", timeout
120122
raise AppStoreException("Could not parse app store response")
121123

122124
if "results" in result:
123-
return [app["trackId"] for app in result["results"] if app["wrapperType"] == "software"]
125+
return [app for app in result["results"] if app["wrapperType"] == "software"]
124126
else:
125127
# probably an invalid developer ID
126128
return []
127129

130+
def get_app_ids_for_developer(self, developer_id, country="nl", lang="", timeout=None):
131+
"""
132+
Retrieve App IDs linked to given developer
133+
134+
:param int developer_id: Developer ID
135+
:param str country: Two-letter country code for the store to search in.
136+
Defaults to 'nl'.
137+
:param str lang: Dummy argument for compatibility. Unused.
138+
:param int timeout: Seconds to wait for response before stopping.
139+
140+
:return list: List of App IDs linked to developer
141+
"""
142+
apps = self.get_apps_for_developer(developer_id, country=country, lang=lang, timeout=timeout)
143+
if len(apps) > 0:
144+
app_ids =[app["trackId"] for app in apps if app["wrapperType"] == "software"]
145+
else:
146+
return []
147+
return app_ids
148+
149+
128150
def get_similar_app_ids_for_app(self, app_id, country="nl", lang="nl", timeout=None):
129151
"""
130152
Retrieve list of App IDs of apps similar to given app

itunes_app_scraper/util.py

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,23 +25,18 @@ class AppStoreCollections:
2525
"""
2626
App store collection IDs
2727
28-
Borrowed from https://github.com/facundoolano/app-store-scraper. These are
28+
Based on https://itunes.apple.com/WebObjects/MZStoreServices.woa/ws/genres?id=6000. These are
2929
the various collections displayed in the app store, usually on the front
3030
page.
3131
"""
32-
TOP_MAC = 'topmacapps'
33-
TOP_FREE_MAC = 'topfreemacapps'
34-
TOP_GROSSING_MAC = 'topgrossingmacapps'
32+
TOP_FREE_MAC = 'freeMacAppsV2'
3533
TOP_PAID_MAC = 'toppaidmacapps'
36-
NEW_IOS = 'newapplications'
37-
NEW_FREE_IOS = 'newfreeapplications'
38-
NEW_PAID_IOS = 'newpaidapplications'
39-
TOP_FREE_IOS = 'topfreeapplications'
40-
TOP_FREE_IPAD = 'topfreeipadapplications'
41-
TOP_GROSSING_IOS = 'topgrossingapplications'
42-
TOP_GROSSING_IPAD = 'topgrossingipadapplications'
43-
TOP_PAID_IOS = 'toppaidapplications'
44-
TOP_PAID_IPAD = 'toppaidipadapplications'
34+
TOP_FREE_IOS = 'freeAppsV2'
35+
TOP_FREE_IPAD = 'freeIpadApplications'
36+
TOP_GROSSING_IOS = 'appsByRevenue'
37+
TOP_GROSSING_IPAD = 'ipadAppsByRevenue'
38+
TOP_PAID_IOS = 'paidApplications'
39+
TOP_PAID_IPAD = 'paidIpadApplications'
4540

4641
class AppStoreCategories:
4742
"""

scraper_test.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,9 @@ def test_query_multiple_pages():
5858
if page_results:
5959
[results.add(x) for x in page_results]
6060
assert len(results) > (page-1)*50
61-
print(f"Total results for query {query}: {len(results)}")
61+
print(f"Total results for query {query}: {len(results)}")
62+
63+
def test_get_app_ids_for_collection():
64+
scraper = AppStoreScraper()
65+
results = scraper.get_app_ids_for_collection(AppStoreCollections.TOP_FREE_IOS, country="us", lang="en")
66+
assert len(results) > 0

util_test.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ def test_category_does_not_exist():
1515

1616
def test_collection_exists():
1717
collection = AppStoreCollections()
18-
assert collection.NEW_IOS == 'newapplications'
18+
assert collection.TOP_FREE_IOS == 'freeAppsV2'
1919

2020
def test_collection_does_not_exist():
2121
collection = AppStoreCollections()
@@ -24,5 +24,5 @@ def test_collection_does_not_exist():
2424

2525
def test_app_utils():
2626
utils = AppStoreUtils()
27-
json_object = json.loads(utils.get_entries(AppStoreCollections()))
28-
assert "names" in json_object
27+
collections = utils.get_entries(AppStoreCollections())
28+
assert "TOP_FREE_IOS" in collections

0 commit comments

Comments
 (0)