HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

CSGO inventory and price python code

Submitted by: @import:stackexchange-codereview··
0
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

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 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&currency=2&market_hash_name=StatTrak%E2%84%A2%20{gun}%20|%20{name}%20({wear})"
KNIFE_URL = "http://steamcommunity.com/market/priceoverview/?appid=730&currency=2&market_hash_name=★%20{gun}%20|%20{name}%20({wear})"
GUN_URL = "http://steamcommunity.com/market/priceoverview/?appid=730&currency=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.