Steam bot

Для тех, кто хочет сделать мир лучше.
Сообщение
Автор
Rififi
Нович0к
Нович0к
Сообщения: 15
Зарегистрирован: 25.09.2013
Поблагодарили: 2 раза
Контактная информация:

#31 Сообщение 01.10.2013, 00:22

Maxx_aka_Phx писал(а):Выкладываю исходник своего бота (С#) для автоматической покупки предметов в steam community market.
Код конечно грубый, быстрая реализация идеи, но при желании интересующие моменты можно разобрать (к примеру тем, у кого проблема с авторизацией).
Проект на github, периодически обновляется.
thanx, меня как раз интересует возможность автоматизации торговой площадки, но я застрял на зомороченной процедуре авторизации.

поигрался с гуи в режиме парсинга айтемов
логиниться и покупать пока не пробовал - судя по комментам в коде
//FIX: using SSL - https:// in url - оно щас работает?

- очень не хватает ресайза. винформсы позволяют делать простейший ресайз (anchors etc)

- IP у меня был русский, но цены почему-то выдавались в еврах.. в связи с этим есть глючок: походу при парсинге не учитываются региональные настройки
например цена в евро "0,17", после чистки строки получается "017"
и вообще, мне кажется что парсинг можно упростить и сделать всё одним регэкспом

- ну и лично для меня (а может и не только) была бы полезна такая фишка:
сейчас игр с карточками немерянно, и в дальнейшем их количество будет расти.
таким образом, нужен сценарий для самой распространенной ситуации: покупка всех обычных карт * 5, для крафтинга максимального значка (количество каждой карты можно и в гуи настравивать с дефолтом 5)
причём список карт лучше выдавать не в табах (по ним неудобно переключаться, ообенно когда карт за десяток), а в одном и том-же listview

- можно приделать и парсинг динамики цен, чтобы ориентироваться какую оптимальную цену выставлять для вотчера

это так, что внешне по интерфейсу заметил, в код пока детально не смотрел.

Maxx_aka_Phx
Нович0к
Нович0к
Сообщения: 8
Зарегистрирован: 01.12.2007
Контактная информация:

#32 Сообщение 01.10.2013, 09:27

Rififi
спасибо за проявленный интерес.
авторизация написана очень скомкано, "лишь бы работало". ну а принципы описаны в этой теме, по ним и делал. по конкретным вопросам, свяжитесь со мной лично.
Rififi писал(а):оно щас работает?
да, логин и покупка работают
Rififi писал(а):IP у меня был русский, но цены почему-то выдавались в еврах.
все верно, пока не залогинишься, цены будут отображаться в той валюте, в какой продавец выставил в продажу. к примеру, товар европейца виден в евро, американца - в долларах, русского - в рублях.
Rififi писал(а):цена в евро "0,17", после чистки строки получается "017"
после конверта в int, лишние нули уходят.
Rififi писал(а):можно упростить и сделать всё одним регэкспом
конечно, в списке TODO.
Rififi писал(а):сценарий для самой распространенной ситуации: покупка всех обычных карт * 5
согласен, будет полезно. сейчас процесс покупки идет до тех пор, пока вручную не остановишь.
Rififi писал(а):список карт лучше выдавать не в табах
интерфейсу нужно уделить больше времени. первоначально я хотел следить только за одним предметом. идея со списком, пришла намного позже, отсюда и табы.

Rififi
Нович0к
Нович0к
Сообщения: 15
Зарегистрирован: 25.09.2013
Поблагодарили: 2 раза
Контактная информация:

#33 Сообщение 01.10.2013, 14:57

и вообще, мне кажется что парсинг можно упростить и сделать всё одним регэкспом

изучаю код, посмотрел что приходит в post-запросах... похоже неправ был, там регекспом вырезается некислая такая портянка тэгов. вычищать её довольно запарно.

по-моему проще парсить используя HtmlAgilityPack:

Код: Выделить всё

public static class Market
{
	public const string RowLink = @"//a[@class='market_listing_row_link'][@href]";
	public const string Name = @"//span[@id='result_{0}_name'][@class='market_listing_item_name']/text()";
	public const string Price = @"div/div/span/text()[4]";
	public const string Picture = @"//img[@id='result_{0}_image'][@src]";
	public const string Quantity = @"//span[@class='market_listing_num_listings_qty']/text()";
	public const string Game = @"//span[@class='market_listing_game_name']/text()";
}

private static IList<Item> ParseCards(HtmlNode root)
{
	var db = new List<Item>();
	var items = root.SelectNodes(Market.RowLink);
	IFormatProvider culture = CultureInfo.CreateSpecificCulture("en-US");

	for (var i = 0; i < items.Count; i++)
	{
		var name = items[i].SelectSingleNode(string.Format(Market.Name, i)).InnerText;
		if (RxFoilCard.IsMatch(name)) // отсеиваем металлические карточки
			continue;

		var priceTxt = WebUtility.HtmlDecode(items[i].SelectSingleNode(Market.Price).InnerText.Trim());

		var item = new Item
		{
			_name = name,
			_url = items[i].Attributes["href"].Value,
			_pictureUrl = items[i].SelectSingleNode(string.Format(Market.Picture, i)).Attributes["src"].Value,
			_quantity = int.Parse(items[i].SelectSingleNode(Market.Quantity).InnerText, NumberStyles.Integer | NumberStyles.AllowThousands, culture),
			_game = items[i].SelectSingleNode(Market.Game).InnerText,
			_price = double.Parse(priceTxt.Split(' ')[0], NumberStyles.AllowCurrencySymbol | NumberStyles.AllowDecimalPoint, culture)
		};

		db.Add(item);
	}

	return db;
}

Аватара пользователя
VIT
Майор
Майор
Сообщения: 831
Зарегистрирован: 15.01.2007
Откуда: ::1
Благодарил (а): 69 раз
Поблагодарили: 451 раз
Контактная информация:

#34 Сообщение 01.10.2013, 17:39

Maxx_aka_Phx
Rififi
в JSON'е сила
результаты для предмета

Код: Выделить всё

http://steamcommunity.com/market/listings/570/Treasure%20Key/render/?query=&start=0&count=10
результаты поиска по фразе, в данном примере по "card"

Код: Выделить всё

http://steamcommunity.com/market/search/render/?query=card&start=0&count=10
* count max = 100

Maxx_aka_Phx
Нович0к
Нович0к
Сообщения: 8
Зарегистрирован: 01.12.2007
Контактная информация:

#35 Сообщение 01.10.2013, 18:50

VIT
знаем, знаем... все руки не доходят прикрутить.
полезная информация есть в статье, на которую я давал ссылку.

Rififi
Нович0к
Нович0к
Сообщения: 15
Зарегистрирован: 25.09.2013
Поблагодарили: 2 раза
Контактная информация:

#36 Сообщение 01.10.2013, 21:32

VIT

интересная инфа, но при поиске карт на маркете, в получаемом json'е нет полезной инфы.
а вот при парсинге цен на карточку - да, тут проще получается чем шариться по html.

PS.
и у меня попутно назрел актуальный вопрос: в соглашении стима прописано что нельзя пользоваться ботами. поэтому интересует - бота сложно вычислить?
если например подделаться в user-agent под браузер и ввести случайные задержки перед покупками?
и возможно такое, что акк забанят?

Аватара пользователя
VIT
Майор
Майор
Сообщения: 831
Зарегистрирован: 15.01.2007
Откуда: ::1
Благодарил (а): 69 раз
Поблагодарили: 451 раз
Контактная информация:

#37 Сообщение 01.10.2013, 21:38

Rififi писал(а):и возможно такое, что акк забанят?
http://forum.csmania.ru/viewtopic.php?f=38&t=40891

Maxx_aka_Phx
Нович0к
Нович0к
Сообщения: 8
Зарегистрирован: 01.12.2007
Контактная информация:

#38 Сообщение 02.10.2013, 09:56

Rififi писал(а):интересная инфа, но при поиске карт на маркете, в получаемом json'е нет полезной инфы.
тоже самое, что на готовой странице. json содержит все тот же голый html, который парсить придется привычным способом. а я то губу раскатал...
ладно хоть инвентарь /inventory/json/ приходит с каноничным содержимым.

Rififi
Нович0к
Нович0к
Сообщения: 15
Зарегистрирован: 25.09.2013
Поблагодарили: 2 раза
Контактная информация:

#39 Сообщение 04.10.2013, 16:58

Появился вопрос по сервису ehsankia.com/steam/cards/

мне нужна примерно похожая функциональность - я получаю список значков, отсутствующих на акке, и пытаюсь отсортировать наборы карт по цене, чтобы бот начал их выкупать, начиная с наиболее низких цен..

вот только заковырочка... как он получает прайс для фулл-сета так быстро?
игр почти три сотни, а страница генерируется за пару секунд.

Аватара пользователя
Pr0Ger
Модератор
Модератор
Сообщения: 1829
Зарегистрирован: 16.01.2009
Благодарил (а): 17 раз
Поблагодарили: 214 раз
Контактная информация:

#40 Сообщение 04.10.2013, 19:35

Rififi
Кешируют локально информацию о ценах на разные карточки, периодически ее обновляя, а когда рисуют страницу просто берут из кеша информацию.

Rififi
Нович0к
Нович0к
Сообщения: 15
Зарегистрирован: 25.09.2013
Поблагодарили: 2 раза
Контактная информация:

#41 Сообщение 04.10.2013, 21:07

Кешируют локально информацию о ценах на разные карточки, периодически ее обновляя

Списался с автором, он подтвердил эту догадку. у него многопоточный бот.
но что самое приятное, поддерживается выдача инфы в формате json.

так что можно самому даже не париться, а просто забирать всю инфу у него, точность в данном случае не принципиальна.

Ответить