patternpythonMinor
CSGO inventory and price python code
Viewed 0 times
priceinventorycodepythonandcsgo
Problem
```
#!/usr/bin/python
# -- coding: utf-8 --
import urllib2
import json
import datetime
import time
global file_name
file_name = "skins 2017-05-05 23-15-16.txt"
wear_list = ["Factory New", "Minimal Wear", "Field-Tested", "Well-Worn", "Battle-Scarred"]
wear_val = {"Factory New": 1, "Minimal Wear": 2, "Field-Tested": 3, "Well-Worn": 4, "Battle-Scarred": 5}
items = []
item_prices = {}
def getInventory(steamid):
try:
data = urllib2.urlopen('http://steamcommunity.com/profiles/'+steamid+'/inventory/json/730/2')
except:
print("Overloaded the server...")
print("Waiting...")
time.sleep(60)
data = urllib2.urlopen('http://steamcommunity.com/profiles/'+steamid+'/inventory/json/730/2')
json_data = json.loads(data.read())
descriptions = json_data['rgDescriptions']
now = datetime.datetime.now()
date = now.strftime("%Y-%m-%d %H-%M-%S")
global file_name
file_name = "skins " + str(date) + ".txt"
txt = open(file_name, "w+")
for v in descriptions:
name = str([descriptions[v]['market_name']])
name = name[3:]
name = name[:-2]
if name.endswith("Flip Knife | Rust Coat (Battle-Scarred)"):
name = name[7:]
if name.startswith("StatTrak"):
name = name[15:]
name = 'StatTrak ' + name
if name.endswith("(Dragon King) (Minimal Wear)"):
name = "M4A4 | Dragon King (Minimal Wear"
txt.write(name)
txt.write('\n')
#txt.write(str(descriptions[v]))
#txt.write('\n')
print(name)
txt.close()
print('Done!')
return
def getPrice():
x = 1
gun_name_wear = 0
txt = open(file_name, "r+")
for line in txt:
stattrak = 0
wear = line[line.find("(")+1:line.find(")")]
if wear in wear_list:
print(wear)
wear = wear.replace(" ","%20")
gun = line.split(' |', 1)[0].replace('.', '')
print(gun)
if "StatTr
#!/usr/bin/python
# -- coding: utf-8 --
import urllib2
import json
import datetime
import time
global file_name
file_name = "skins 2017-05-05 23-15-16.txt"
wear_list = ["Factory New", "Minimal Wear", "Field-Tested", "Well-Worn", "Battle-Scarred"]
wear_val = {"Factory New": 1, "Minimal Wear": 2, "Field-Tested": 3, "Well-Worn": 4, "Battle-Scarred": 5}
items = []
item_prices = {}
def getInventory(steamid):
try:
data = urllib2.urlopen('http://steamcommunity.com/profiles/'+steamid+'/inventory/json/730/2')
except:
print("Overloaded the server...")
print("Waiting...")
time.sleep(60)
data = urllib2.urlopen('http://steamcommunity.com/profiles/'+steamid+'/inventory/json/730/2')
json_data = json.loads(data.read())
descriptions = json_data['rgDescriptions']
now = datetime.datetime.now()
date = now.strftime("%Y-%m-%d %H-%M-%S")
global file_name
file_name = "skins " + str(date) + ".txt"
txt = open(file_name, "w+")
for v in descriptions:
name = str([descriptions[v]['market_name']])
name = name[3:]
name = name[:-2]
if name.endswith("Flip Knife | Rust Coat (Battle-Scarred)"):
name = name[7:]
if name.startswith("StatTrak"):
name = name[15:]
name = 'StatTrak ' + name
if name.endswith("(Dragon King) (Minimal Wear)"):
name = "M4A4 | Dragon King (Minimal Wear"
txt.write(name)
txt.write('\n')
#txt.write(str(descriptions[v]))
#txt.write('\n')
print(name)
txt.close()
print('Done!')
return
def getPrice():
x = 1
gun_name_wear = 0
txt = open(file_name, "r+")
for line in txt:
stattrak = 0
wear = line[line.find("(")+1:line.find(")")]
if wear in wear_list:
print(wear)
wear = wear.replace(" ","%20")
gun = line.split(' |', 1)[0].replace('.', '')
print(gun)
if "StatTr
Solution
There are quite a few improvements possible. I will try to describe all the changes I made in your code.
First, you should define that function that just gets data from an URL and retries if there have been too many requests recently. For this you should try to
Put all the URLs into constants at the top of the file.
I made
The same for the prices. I added one function whose sole purpose it is to retrieve the price of one item and then another function to call this function for all items.
Both these methods take a
You should use
Get rid of all the replacing of
I removed a lot of the intermediate debugging output.
I think I found some bugs with your building of name, where your hardcoded indices for the
Use
At the end I added a
```
#!/usr/bin/python
# -- coding: utf-8 --
import urllib2
import json
import datetime
import time
import re
wear_val = {"Factory New": 1, "Minimal Wear": 2,
"Field-Tested": 3, "Well-Worn": 4, "Battle-Scarred": 5}
INVENTORY_URL = 'http://steamcommunity.com/profiles/{}/inventory/json/730/2'
STATTRAK_URL = "http://steamcommunity.com/market/priceoverview/?appid=730¤cy=2&market_hash_name=StatTrak%E2%84%A2%20{gun}%20|%20{name}%20({wear})"
KNIFE_URL = "http://steamcommunity.com/market/priceoverview/?appid=730¤cy=2&market_hash_name=★%20{gun}%20|%20{name}%20({wear})"
GUN_URL = "http://steamcommunity.com/market/priceoverview/?appid=730¤cy=2&market_hash_name={gun}%20|%20{name}%20({wear})"
def get_data(url):
while True:
try:
return urllib2.urlopen(url)
except urllib2.HTTPError as e:
if e.code == 429:
print("Overloaded the server, waiting 60s...")
time.sleep(60)
else:
print(url)
raise
def get_inventory(steamid):
data = get_data(INVENTORY_URL.format(steamid))
descriptions = json.loads(data.read())['rgDescriptions'].values()
for description in descriptions:
name = description['market_name']
name = re.sub(r'[^\x00-\x7f]', r'', name)
if name.endswith("(Dragon King) (Minimal Wear)"):
name = "M4A4 | Dragon King (Minimal Wear)"
yield name
def save_inventory(steamid, file_name):
with open(file_name, "w+") as txt:
for item in get_inventory(steamid):
txt.write(item + '\n')
print('Done!')
def get_price(url, gun, name, wear):
data = get_data(url.format(**locals()))
json_data = json.loads(data.read())
try:
price = json_data['lowest_price']
except KeyError:
price = json_data['median_price']
return price[-4:]
def get_info(item):
# print(item)
wear = item[item.find("(") + 1:item.find(")")]
if wear not in wear_val:
return "", None
gun = item.split(' |', 1)[0].replace('.', '')
stattrak = "StatTrak" in gun
gun = gun.replace("StatTrak", "").strip()
name = item[item.find("| ") + 1:item.find(" (")].strip()
if stattrak:
url = STATTRAK_URL
elif "knife" in item.lower():
url = KNIFE_URL
else:
url = GUN_URL
price = get_price(url, urllib2.quote(gun), urllib2.quote(name), urllib2.quote(wear))
return "{gun} {name} {wear}".format(**locals()), price
def get_prices(file_name):
item_prices = {}
with open(file_name, "r+") as txt:
for item in txt:
name, price = get_info(item)
if price is not None:
item_prices[name] = price
print(name, price)
time.sleep(5)
return item_prices
if __name__ == "__main__":
now = datetime.datetime.now()
# fil
First, you should define that function that just gets data from an URL and retries if there have been too many requests recently. For this you should try to
except the most specific exception possible. This way the user can abort e.g. the 60s waiting period. Also, even if you only except urllib2.HTTPError, you still want to be more specific (and not except e.g. Error 500, the internal server error if you wrongly escape spaces in the URL).Put all the URLs into constants at the top of the file.
x in d works for dictionaries and sees if x is a key of the dictionary d, so you don't need wear_list (you also never use the values of wear_val, but I left it there).I made
get_inventory a generator that just returns the retrieved items and a second function that saves it to a file. This way you can skip the saving part if you ever want to, or do something else with it.The same for the prices. I added one function whose sole purpose it is to retrieve the price of one item and then another function to call this function for all items.
Both these methods take a
file_name argument, which gets rid of the global file_name.You should use
str.format throughout, because it is better than string addition. Note also that it can take a custom formatting string, which makes formatting dates a lot more concise.Get rid of all the replacing of
" " with "%20" and vice-versa by just quoting the variables that need to be url-encoded using urllib2.quote.I removed a lot of the intermediate debugging output.
I think I found some bugs with your building of name, where your hardcoded indices for the
"StatTrak" etc seemed to be off. I made this more explicitly deleting all unicode symbols using a REGEX found here.Use
str.strip where needed to get rid of leftover white-space at the beginning or end of strings.At the end I added a
if __name__ == "__main__": guard to ensure the code there is only run when directly invoking this script via python csgo_inventory.py.```
#!/usr/bin/python
# -- coding: utf-8 --
import urllib2
import json
import datetime
import time
import re
wear_val = {"Factory New": 1, "Minimal Wear": 2,
"Field-Tested": 3, "Well-Worn": 4, "Battle-Scarred": 5}
INVENTORY_URL = 'http://steamcommunity.com/profiles/{}/inventory/json/730/2'
STATTRAK_URL = "http://steamcommunity.com/market/priceoverview/?appid=730¤cy=2&market_hash_name=StatTrak%E2%84%A2%20{gun}%20|%20{name}%20({wear})"
KNIFE_URL = "http://steamcommunity.com/market/priceoverview/?appid=730¤cy=2&market_hash_name=★%20{gun}%20|%20{name}%20({wear})"
GUN_URL = "http://steamcommunity.com/market/priceoverview/?appid=730¤cy=2&market_hash_name={gun}%20|%20{name}%20({wear})"
def get_data(url):
while True:
try:
return urllib2.urlopen(url)
except urllib2.HTTPError as e:
if e.code == 429:
print("Overloaded the server, waiting 60s...")
time.sleep(60)
else:
print(url)
raise
def get_inventory(steamid):
data = get_data(INVENTORY_URL.format(steamid))
descriptions = json.loads(data.read())['rgDescriptions'].values()
for description in descriptions:
name = description['market_name']
name = re.sub(r'[^\x00-\x7f]', r'', name)
if name.endswith("(Dragon King) (Minimal Wear)"):
name = "M4A4 | Dragon King (Minimal Wear)"
yield name
def save_inventory(steamid, file_name):
with open(file_name, "w+") as txt:
for item in get_inventory(steamid):
txt.write(item + '\n')
print('Done!')
def get_price(url, gun, name, wear):
data = get_data(url.format(**locals()))
json_data = json.loads(data.read())
try:
price = json_data['lowest_price']
except KeyError:
price = json_data['median_price']
return price[-4:]
def get_info(item):
# print(item)
wear = item[item.find("(") + 1:item.find(")")]
if wear not in wear_val:
return "", None
gun = item.split(' |', 1)[0].replace('.', '')
stattrak = "StatTrak" in gun
gun = gun.replace("StatTrak", "").strip()
name = item[item.find("| ") + 1:item.find(" (")].strip()
if stattrak:
url = STATTRAK_URL
elif "knife" in item.lower():
url = KNIFE_URL
else:
url = GUN_URL
price = get_price(url, urllib2.quote(gun), urllib2.quote(name), urllib2.quote(wear))
return "{gun} {name} {wear}".format(**locals()), price
def get_prices(file_name):
item_prices = {}
with open(file_name, "r+") as txt:
for item in txt:
name, price = get_info(item)
if price is not None:
item_prices[name] = price
print(name, price)
time.sleep(5)
return item_prices
if __name__ == "__main__":
now = datetime.datetime.now()
# fil
Code Snippets
#!/usr/bin/python
# -*- coding: utf-8 -*-
import urllib2
import json
import datetime
import time
import re
wear_val = {"Factory New": 1, "Minimal Wear": 2,
"Field-Tested": 3, "Well-Worn": 4, "Battle-Scarred": 5}
INVENTORY_URL = 'http://steamcommunity.com/profiles/{}/inventory/json/730/2'
STATTRAK_URL = "http://steamcommunity.com/market/priceoverview/?appid=730¤cy=2&market_hash_name=StatTrak%E2%84%A2%20{gun}%20|%20{name}%20({wear})"
KNIFE_URL = "http://steamcommunity.com/market/priceoverview/?appid=730¤cy=2&market_hash_name=★%20{gun}%20|%20{name}%20({wear})"
GUN_URL = "http://steamcommunity.com/market/priceoverview/?appid=730¤cy=2&market_hash_name={gun}%20|%20{name}%20({wear})"
def get_data(url):
while True:
try:
return urllib2.urlopen(url)
except urllib2.HTTPError as e:
if e.code == 429:
print("Overloaded the server, waiting 60s...")
time.sleep(60)
else:
print(url)
raise
def get_inventory(steamid):
data = get_data(INVENTORY_URL.format(steamid))
descriptions = json.loads(data.read())['rgDescriptions'].values()
for description in descriptions:
name = description['market_name']
name = re.sub(r'[^\x00-\x7f]', r'', name)
if name.endswith("(Dragon King) (Minimal Wear)"):
name = "M4A4 | Dragon King (Minimal Wear)"
yield name
def save_inventory(steamid, file_name):
with open(file_name, "w+") as txt:
for item in get_inventory(steamid):
txt.write(item + '\n')
print('Done!')
def get_price(url, gun, name, wear):
data = get_data(url.format(**locals()))
json_data = json.loads(data.read())
try:
price = json_data['lowest_price']
except KeyError:
price = json_data['median_price']
return price[-4:]
def get_info(item):
# print(item)
wear = item[item.find("(") + 1:item.find(")")]
if wear not in wear_val:
return "", None
gun = item.split(' |', 1)[0].replace('.', '')
stattrak = "StatTrak" in gun
gun = gun.replace("StatTrak", "").strip()
name = item[item.find("| ") + 1:item.find(" (")].strip()
if stattrak:
url = STATTRAK_URL
elif "knife" in item.lower():
url = KNIFE_URL
else:
url = GUN_URL
price = get_price(url, urllib2.quote(gun), urllib2.quote(name), urllib2.quote(wear))
return "{gun} {name} {wear}".format(**locals()), price
def get_prices(file_name):
item_prices = {}
with open(file_name, "r+") as txt:
for item in txt:
name, price = get_info(item)
if price is not None:
item_prices[name] = price
print(name, price)
time.sleep(5)
return item_prices
if __name__ == "__main__":
now = datetime.datetime.now()
# file_name = "skins 2017-05-05 23-15-16.txt"
file_name = "skins {:%Y-%m-%d %H-%M-%S}.txt".format(now)Context
StackExchange Code Review Q#162745, answer score: 3
Revisions (0)
No revisions yet.