爬取網易buff CSGO飾品數據


最近steam遊戲瘋狂打折,然鵝我的steam裏餘額只有可憐的幾塊錢,想充點兒錢買遊戲,直接1:1充值人民幣進steam感覺有點兒虧,想買充值卡,但是充值卡畢竟黑產,而且最近大家對充值卡的需求一高,充值卡店鋪都變得特別傲嬌,發貨時間竟然是48天以內……想想前一段csgo裂網大行動,也是steam沒有餘額通行證,不得不直接拿現金1:1買了,甚是心疼。所以我在想,要不從第三方網站買個飾品,再高價賣到steam?雖然扣掉手續費之後,差價也沒剩多少了,但是至少比直接往steam充人民幣值一些吧。那麼問題來了,買哪個皮膚賣到steam裏更賺一些呢?總不能一個一個人肉去比價吧。不如就搞個爬蟲自動算一下。就算不賺錢,使用程序搞了一件自己喜歡的事情,雖然並不是多難的東西,至少也算是可以跟狐朋狗友吹逼的東西嘛。

想通過這種方法賺錢是不可能了,像這些第三方平臺本身就是搞這個的,哪個飾品如果真的通過倒賣有賺頭,他們肯定直接就截胡了。所以首先我們報的最高期待就是:在不買充值卡的情況下,從第三方平臺買一件飾品賣到steam,哪個能更賺steam餘額。

這個第三方平臺,就選網易buff吧。

需要的東西

想達到上述目的,大概需要知道以下數據:

  • 所有皮膚;
  • 每件皮膚在buff的最低價;
  • 每件皮膚在steam的價格;

然後就可以算差價,再扣去大概13%的steam交易稅,剩下的就是能賺到的steam餘額差價了。最後除以我們實際花掉的錢,大概就是投資回報比。找一個回報比最高的皮膚,美滋滋。

API

獲取所有飾品

首先我們需要一個爬取buff上所有飾品的辦法。

https://buff.163.com/market/?game=csgo#tab=selling&page_num=1,隨便打開一個飾品,比如鮑伊獵刀,觀察它的訪問按鈕,網頁顯示的是<li value="weapon_knife_survival_bowie">鮑伊獵刀</li>,點擊之後url是https://buff.163.com/market/?game=csgo#tab=selling&page_num=1&category=weapon_knife_survival_bowie。所以猜測它的訪問辦法就是前面的路徑是https://buff.163.com/market/?game=csgo#tab=selling&page_num=1&category=,後面加上類別即可。試了一下果然就是這樣。

那麼我們只需要知道所有的category,挨個用這個url訪問就行了。

好在這個並不難找,在每一個網頁上,我們都可以看到所有的類別選擇按鈕,可以選擇所有類別的皮膚:ak47、獵殺者匕首、usp等等。查看網頁源碼,可以看到這一塊的內容爲:

</div> <i class="icon icon_arr_right cru-market"></i> <span class="cru-market"><a href="/market/?game=csgo">飾品市場</a></span> <i class="icon icon_arr_right cru-filter" style="display:none;"></i> <span class="cru-filter" style="display:none;"></span> </div> <div class="market-list"> <div class="l_Layout"> <div class="market-header black"> <div class="h1z1-selType type_csgo" id="j_h1z1-selType"> <div class="item w-SelType csgo_filter"> <i class="icon icon_csgo_type_knife"></i> <p value="knife">匕首</p> <ul class="cols"> <li value="weapon_knife_survival_bowie">鮑伊獵刀</li> <li value="weapon_knife_butterfly">蝴蝶刀</li> <li value="weapon_knife_falchion">彎刀</li> <li value="weapon_knife_flip">摺疊刀</li> <li value="weapon_knife_gut">穿腸刀</li> <li value="weapon_knife_tactical">獵殺者匕首</li> <li value="weapon_knife_m9_bayonet">M9 刺刀</li> <li value="weapon_bayonet">刺刀</li> <li value="weapon_knife_karambit">爪子刀</li> <li value="weapon_knife_push">暗影雙匕</li> <li value="weapon_knife_stiletto">短劍</li> <li value="weapon_knife_ursus">熊刀</li> <li value="weapon_knife_gypsy_jackknife">折刀</li> <li value="weapon_knife_widowmaker">鋸齒爪刀</li> <li value="weapon_knife_css">海豹短刀</li> <li value="weapon_knife_cord">繫繩匕首</li> <li value="weapon_knife_canis">求生匕首</li> <li value="weapon_knife_outdoor">流浪者匕首</li> <li value="weapon_knife_skeleton">骷髏匕首</li> </ul> </div> <div class="item w-SelType csgo_filter"> <i class="icon icon_csgo_type_pistol"></i> <p value="pistol">手槍</p> <ul class="cols"> <li value="weapon_hkp2000">P2000</li> <li value="weapon_usp_silencer">USP 消音版</li> <li value="weapon_glock">格洛克 18 型</li> <li value="weapon_p250">P250</li> <li value="weapon_fiveseven">FN57</li> <li value="weapon_cz75a">CZ75 自動手槍</li> <li value="weapon_tec9">Tec-9</li> <li value="weapon_revolver">R8 左輪手槍</li> <li value="weapon_deagle">沙漠之鷹</li> <li value="weapon_elite">雙持貝瑞塔</li> </ul> </div> <div class="item w-SelType csgo_filter"> <i class="icon icon_csgo_type_rifle"></i> <p value="rifle">步槍</p> <ul class="cols"> <li value="weapon_galilar">加利爾 AR</li> <li value="weapon_scar20">SCAR-20</li> <li value="weapon_awp">AWP</li> <li value="weapon_ak47">AK-47</li> <li value="weapon_famas">法瑪斯</li> <li value="weapon_m4a1">M4A4</li> <li value="weapon_m4a1_silencer">M4A1 消音版</li> <li value="weapon_sg556">SG 553</li> <li value="weapon_ssg08">SSG 08</li> <li value="weapon_aug">AUG</li> <li value="weapon_g3sg1">G3SG1</li> </ul> </div> <div class="item w-SelType csgo_filter"> <i class="icon icon_csgo_type_smg"></i> <p value="smg">微型衝鋒槍</p> <ul class="cols"> <li value="weapon_p90">P90</li> <li value="weapon_mac10">MAC-10</li> <li value="weapon_ump45">UMP-45</li> <li value="weapon_mp7">MP7</li> <li value="weapon_bizon">PP-野牛</li> <li value="weapon_mp9">MP9</li> <li value="weapon_mp5sd">MP5-SD</li> </ul> </div> <div class="item w-SelType csgo_filter"> <i class="icon icon_csgo_type_shotgun"></i> <p value="shotgun">霰彈槍</p> <ul> <li value="weapon_sawedoff">截短霰彈槍</li> <li value="weapon_xm1014">XM1014</li> <li value="weapon_nova">新星</li> <li value="weapon_mag7">MAG-7</li> </ul> </div> <div class="item w-SelType csgo_filter"> <i class="icon icon_csgo_type_machinegun"></i> <p value="machinegun">機槍</p> <ul> <li value="weapon_m249">M249</li> <li value="weapon_negev">內格夫</li> </ul> </div> <div class="item w-SelType csgo_filter"> <i class="icon icon_type_hands"></i> <p value="hands">手套</p> <ul class="cols"> <li value="weapon_bloodhound_gloves">血獵手套</li> <li value="weapon_driver_gloves">駕駛手套</li> <li value="weapon_hand_wraps">手部束帶</li> <li value="weapon_moto_gloves">摩托手套</li> <li value="weapon_specialist_gloves">專業手套</li> <li value="weapon_sport_gloves">運動手套</li> <li value="weapon_hydra_gloves">九頭蛇手套</li> </ul> </div> <div class="item w-SelType csgo_filter"> <i class="icon icon_csgo_tool_sticker"></i> <p value="sticker">印花</p> </div> <div class="item w-SelType csgo_filter"> <i class="icon icon_csgo_type_other"></i> <p value="other">其他</p> <ul class="cols"> <li value="csgo_type_tool">工具</li> <li value="csgo_type_spray">塗鴉</li> <li value="csgo_type_collectible">收藏品</li> <li value="csgo_type_ticket">通行證</li> <li value="csgo_tool_gifttag">禮物</li> <li value="csgo_type_musickit">音樂盒</li> <li value="csgo_type_weaponcase">武器箱</li> <li value="csgo_tool_weaponcase_keytag">鑰匙</li> <li value="type_customplayer">探員</li> </ul> </div> </div> <div class="criteria">

首先抓取該網頁內容,掐頭去尾,只留下中間的核心部分,然後用正則將類別全摳出來即可:

    prefix = '<div class="h1z1-selType type_csgo" id="j_h1z1-selType">'
    suffix = '</ul> </div> </div> <div class="criteria">'
    # to match all csgo skin categories
    category_regex = re.compile(r'<li value="(.+?)"', re.DOTALL)

    # entry page
    root_url = BUFF_ROOT + 'market/?game=csgo#tab=selling&page_num=1'

    print("GET: " + root_url)
    root_html = http_util.open_url(root_url)

    remove_prefix = root_html.split(prefix, 1)[1]
    core_html = remove_prefix.split(suffix, 1)[0]

    # all categories
    categories = category_regex.findall(core_html)

這裏我們摳的是所有的類別,比如weapon_negev代表內格夫,weapon_sg556代表帥哥553,weapon_deagle代表沙鷹。

拼接url遍歷所有類別,所有類別的皮膚我們就都得到了。

獲取每一個類別的飾品

每訪問一個類別,得到了什麼呢?

比如瀏覽器訪問https://buff.163.com/market/?game=csgo#tab=selling&page_num=1&category=weapon_knife_survival_bowie鮑伊獵刀的url,返回的是所有的鮑伊獵刀。本來還想用和上面同樣的套路:看網頁源碼,用正則匹配出所有的鮑伊獵刀種類,然後摳出來。結果一看源碼我人傻了:沒有!網頁上明明顯示各式各樣的鮑伊獵刀,但是網頁源碼裏竟然沒這些數據,只有一些類似於JSP那種嵌入網頁的模板代碼。像這種:

    <% } else { %>
    <div class="list_card unhover" id="j_list_card">
        <ul class="card_csgo">
            <% for(var i = 0; i < items.length; i++){ %>
            <li>

顯然,瀏覽器是後來纔將數據和模板組合起來的,顯示成我們最終看到的完整的網頁的樣子。

但是!我不是前端啊!!!我哪知道它是用了什麼技術,一竅不懂啊!對於我來說,爬東西最難的一關可能就是怎麼找到API,哪個API對應哪些數據的獲取方式。後面的流程,通過這些API去獲取數據,處理數據,問題都不大,實在不行可以查嘛。但是前端的東西,我連用啥關鍵詞查都不知道,這纔是最絕望的!這也是我很久前就想搞這個,卻始終沒有搞的原因。

(2019年12月7日12:47:37增補:後來知道原來這就是ajax,查看網頁源碼看到的只能是原始網頁模板,但是網頁上的內容是模板+數據渲染後的樣子,也就是說,看到的內容和網頁的源碼不再相同了。如果有興趣,可以使用chrome的toggle javascript插件,開啓插件後,網頁將不會渲染js,網頁源碼將和看到的內容一致。)

絕望一會兒之後,想了想,既然是把數據渲染到頁面模板上,那數據哪來的呢?只要找到數據了不就行了嗎。打開瀏覽器的開發者模式,調到Network一欄,看到打開網頁時瀏覽器請求了好多資源:圖片、js、css腳本等等等等。仔細從上到下翻了半天,突然看到一個叫goods.json的東西!!打開一看,這不就是我心心念唸的數據嘛!一條條鮑伊獵刀的數據清清楚楚地記錄在json裏:

{
  "code": "OK", 
  "data": {
    "items": [...],
    "page_num": 1, 
    "page_size": 20, 
    "total_count": 115, 
    "total_page": 6
  }, 
  "msg": null
}

items是個數組,記錄着20條鮑伊獵刀的數據,下面的page_size就是說這20條數據,total_count表明總共有115條鮑伊獵刀的數據,total_page說明總共有6頁,而這正是第一頁page_num爲1。

開心到飛起啊!這麼一來,甚至都不需要用正則抓網頁數據了,直接請求這個數據就行了!它的API是https://buff.163.com/api/market/goods?game=csgo&page_num=1&category=weapon_knife_survival_bowie,既然可以知道總共6頁,把url中的page_num從1遍歷到6,所有115條鮑伊獵刀的數據不就全有了嗎!

再細看items裏的鮑伊獵刀數據記錄:

      {
        "appid": 730, 
        "bookmarked": false, 
        "buy_max_price": "1080", 
        "buy_num": 15, 
        "description": null, 
        "game": "csgo", 
        "goods_info": {
          "icon_url": "https://g.fp.ps.netease.com/market/file/5a9fbae6a750140659fd6620ozKc0tIl", 
          "info": {
            "tags": {
              "exterior": {
                "category": "exterior", 
                "internal_name": "wearcategory0", 
                "localized_name": "\u5d2d\u65b0\u51fa\u5382"
              }, 
              "quality": {
                "category": "quality", 
                "internal_name": "unusual", 
                "localized_name": "\u2605"
              }, 
              "rarity": {
                "category": "rarity", 
                "internal_name": "ancient_weapon", 
                "localized_name": "\u9690\u79d8"
              }, 
              "type": {
                "category": "type", 
                "internal_name": "csgo_type_knife", 
                "localized_name": "\u5315\u9996"
              }, 
              "weapon": {
                "category": "weapon", 
                "internal_name": "weapon_knife_survival_bowie", 
                "localized_name": "\u9c8d\u4f0a\u730e\u5200"
              }
            }
          }, 
          "item_id": null, 
          "original_icon_url": "https://g.fp.ps.netease.com/market/file/5a7abfad8b74278e3ebd85d32JbeFRZR", 
          "steam_price": "275", 
          "steam_price_cny": "1933.97"
        }, 
        "has_buff_price_history": true, 
        "id": 42495, 
        "market_hash_name": "\u2605 Bowie Knife | Marble Fade (Factory New)", 
        "market_min_price": "0", 
        "name": "\u9c8d\u4f0a\u730e\u5200\uff08\u2605\uff09 | \u6e10\u53d8\u5927\u7406\u77f3 (\u5d2d\u65b0\u51fa\u5382)", 
        "quick_price": "1134.5", 
        "sell_min_price": "1135", 
        "sell_num": 297, 
        "sell_reference_price": "1135", 
        "steam_market_url": "https://steamcommunity.com/market/listings/730/%E2%98%85%20Bowie%20Knife%20%7C%20Marble%20Fade%20%28Factory%20New%29", 
        "transacted_num": 0
      }

信息量真的豐富啊,和網頁上顯示的內容比對一下,每個字段的含義就很清晰了:飾品名稱、當前最低售價、最高求購價、steam最低售價、steam訪問該刀的URL等等信息一應俱全!

成了!所有飾品,所有飾品的buff最低售價都有了,只差steam價格了!

獲取所有飾品的steam售價

上面的item裏的steam_price_cny已經給出steam最低售價了。我一開始也是拿這個價格算的,但是存在兩個明顯的問題:

  1. buff的這個數據並不是實時更新的,這個價格並不是當前steam的最低售價;
  2. 另一個比較嚴重的問題是,steam最低售價並不是真正能賣出去的價格啊!

比如我算出來一把刀能收益好幾倍,是因爲steam上那個類別就掛了那一把刀,掛了1w+,但是實際求購價才1000多。所以這把刀賣這個價格實際並不會有人買。以這個價格算倒賣到steam能賺的差價是不合適的:真拿到steam上按這個價格賣,是賣不出去的。

那咋辦嘛!再去爬steam,找交易記錄,爬下來最近的交易價格,應該差不多。但是這工作量一下子就翻倍了呀,從爬一個網站到爬兩個網站。而且steam那麼大的網站,反爬機制應該做的相當完善吧,爬起來難度應該比buff大不少。

要不繼續按buff提供的現成的steam最低價格?但是這樣算出來也太不準了,實際可操作性沒了。

躊躇不決之際,作爲buff老用戶的我突然想到了buff在每種飾品的價格走勢裏有steam價格走勢。那個數據哪來的?有了那個數據不就能知道steam上該飾品最近交易的價格了嘛!

去buff上點開“流浪者匕首(★) | 表面淬火 (嶄新出廠)”,用找飾品信息goods.json的方法繼續翻開發者模式中的Network,果然找到了一個叫做price_history.json的東西:

{
  "code": "OK", 
  "data": {
    "currency": "\u7f8e\u5143", 
    "currency_symbol": "$", 
    "days": 7, 
    "price_history": [...],
    "price_type": "Steam\u4ef7\u683c", 
    "steam_price_currency": "\u7f8e\u5143"
  }, 
  "msg": null
}

裏面的price_history就是steam最近7天裏,每一件“流浪者匕首(★) | 表面淬火 (嶄新出廠)”的詳細交易價格!!!當然是dollar,問題不大,乘以匯率就是人民幣價格了。

它的url是https://buff.163.com/api/market/goods/price_history?game=csgo&goods_id=776332&currency=&days=7,看了看,比較複雜的就是goods_id了。這把刀在buff的id是776332。如果我知道所有飾品的id,然後替換到這個url裏,就能查到所有飾品的steam最近交易價格了!

這個id並不難找,在上面爬每一個飾品的信息的時候,裏面就有id一項,試了一下,把id 42495換到url裏,果然就是“Bowie Knife | Marble Fade (Factory New)”的交易價格記錄。

完美!前後端分離真的是舒服!數據和模板分開,方便了後端開發,也方便了我這個爬數據的人 😄

總結一下

上面說的訪問category的url和訪問steam歷史價格的url:

BUFF_ROOT = 'https://buff.163.com/'

BUFF_GOODS = BUFF_ROOT + 'api/market/goods?'
category_url = BUFF_GOODS + 'game=csgo&page_num=1&category=%s' % category

BUFF_HISTORY_PRICE = BUFF_ROOT + 'api/market/goods/price_history?'
BUFF_HISTORY_PRICE_CNY = BUFF_ROOT + 'api/market/goods/price_history/buff?'
STEAM_HISTORY_PRICE_URL = BUFF_HISTORY_PRICE + 'game=csgo&goods_id={}&currency=&days=7'.format(item_id)

在我看來,最困難的數據問題解決了,下面就簡單多了,全是爬蟲的一些通用的技術問題,實在不會可以Google嘛,終歸是有跡可循的。能查的問題,那就不是無解的難題。

模擬登錄

如何登錄是一個難題,畢竟直接訪問上面的那些url,都是讓你登錄。不經過登錄認證是不會返回真正的數據的。

怎麼登錄呢?又是一個前端相關的問題。問題不大,查總會吧。最終我選了最簡單的一種:使用登錄後的cookie。

大致原理就是:http是無狀態的,服務器怎麼知道我登陸了沒有?那就是在我登陸之後給我一個cookie,後面每次訪問服務器,都拿着這個cookie,這樣服務器就能將每一次的訪問都和我聯繫起來,構成了有狀態的訪問記錄。

那就好辦了,先使用賬戶登錄到buff上,開發者模式找到cookie,然後粘到程序裏,程序一直拿着這個cookie訪問數據,就能得到真正的數據了。瀏覽器只知道我向它請求了這個api,我再把瀏覽器的User-Agent粘到程序裏,服務器哪裏分的清這次對url的訪問是我的瀏覽器發出的還是我的程序發出的!

但是這麼做也有個很大的弊端:比如關機了,下次爬的時候,這個cookie肯定過期了,還得瀏覽器再登陸一次,把新的cookie粘到程序裏。

所以嘛,簡單的辦法生效快,但是以後用的時候流程就會麻煩一些。其他一些更高級的辦法自然能解決這個問題,比如把賬號密碼扔到程序裏,讓程序每次模擬登陸。但是考慮到buff在登陸時還有網易易盾驗證(就是那個拖動滑塊到圖片缺失的位置),所以應該還挺麻煩的。這種或者其他更高級的辦法以後有機會再探索吧。目前先用粘cookie這種簡單有效的辦法解決了。

參閱:

  • https://www.cnblogs.com/chenxiaohan/p/7654667.html
  • https://www.cnblogs.com/jiayongji/p/7143662.html

防止ip被封

爬蟲嘛,你老爬人家,自然對服務器造成了遠大於正常操作的訪問壓力。被封也挺正常的。所以怎麼才能做到爬數據還不被封呢?

我先進行了簡單的嘗試:慢慢爬。

只要我不貪心,每1-2秒才爬一次,是不會對服務器造成額外的壓力的,服務器可能就不會封我。試了下,果然buff並沒有封禁我的爬蟲,爬的很順利,就是略慢。csgo有10000多點兒飾品,每爬一次大概20個,那差不多要爬500-700次,二十分鐘以內基本是搞定了。

但是再加上steam歷史價格,每個飾品都要爬一次,10000多條飾品要怕10000多次……爬取量一下子翻了好幾十倍,這樣就太慢了……所以我後來又加了一些限制,比如價格高於100的才爬售價紀錄,其他飾品直接忽略了等等。這樣就把飾品數量從10000多點兒降到了3500種左右。當然這是後話。

我也嘗試了使用代理,如果使用代理,就類似於我委託了一批人以他們的身份去請求數據,假設我委託了100個人,每個人爬30多次,就能爬完所有3500條記錄了。每人30多次的數量很小,不用非得戰戰兢兢等一兩秒纔敢爬一次。這樣的話很快就能爬完所有數據了。

python中使用代理的做法參閱:

  • https://www.scrapehero.com/how-to-rotate-proxies-and-ip-addresses-using-python-3/

但是問題在於我去哪兒找代理?國內外都有一些免費的代理網站,我試了一下,質量實在不敢恭維,好多根本ping不通,更別提當做代理服務器用了。找一兩個都不容易,找一堆更是難上加難。如果只是找一兩個,那和我不找代理又有什麼區別。但是花錢買高質量代理?算了算了,不至於。

獲取免費代理的方法參閱:

  • https://blog.csdn.net/weixin_43968923/article/details/86682068

所以這個問題最終又用了最簡單的解決方案:還是自己一個人爬,一兩秒爬一次就行了。

(但是後來試了下還是有些問題的,似乎buff對單個ip有訪問數量上限限制?爬取每個飾品的價格實在需要訪問太多次服務器,一天如果爬一兩次,往後爬着爬着就爬不動了。這個問題日後再解決吧。)

唉,一杯茶,一根菸,一個ip爬一天……

延伸閱讀:

  • https://www.scrapehero.com/how-to-prevent-getting-blacklisted-while-scraping/

其他問題

價格區間限制

基於上述單ip每隔一兩秒爬一次的設定,爬取大於100塊的飾品,總共3500種左右,條目API加上價格API,大概4000多次爬取,老牛拉破車爬了倆小時……

END: 2019-12-02 02:30:05.096589. TIME USED: 2:06:13.511323.

所以我最終決定設定個價格區間,卡100-300塊錢之間的(價格再高我也懶得買來扔到steam裏賣了,往steam裏放那麼多錢幹啥……我這麼窮的人……)

平均售價

關於steam歷史平均售價,這裏是去掉一個最高價,去掉一個最低價,剩下的再取的均價。

多次爬取

默認第一次爬取之後,後面的爬取優先使用之前爬取並保存的本地數據。除非:

  • 配置強制爬取;
  • 超出了時間範疇。例如以天爲單位,到了第二天運行時就會從網站爬取;如果配置以小時爲單位,則下一個小時再爬取時就會從網站上爬。

冷門飾品過濾

7天在steam上都賣不了超過10次的飾品,這裏就不考慮了。

關於steam飾品賣到buff

這個功能也有,但是感覺意義不大所以沒有繼續完善,畢竟steam的飾品第三方交易的話需要7天cd,7天后可能一切都變了,所以這個看看就行,不必當真。

結論分析

下面貼一些程序自動分析出的結論吧,還是很好玩的:

buff買steam賣:
單位價錢收益最大——

首先,今天(2019年12月2日)如果buff買飾品賣到到steam裏:

               price     sell_num  steam_predict_price  buy_max_price            gap  gap_percent  history_sold  history_days  average_sold_price  average_sold_price_after_tax
count    3319.000000  3319.000000          3319.000000    3319.000000    3319.000000  3319.000000   3319.000000    3319.00000         3319.000000                   3319.000000
mean     1786.190196    46.145224          2049.202932     783.597349      -7.213430     0.271601     11.023501       5.18831          865.545202                    753.024326
std      8102.147813   141.030682          4562.658929    1686.629342    5490.225566     0.636890     22.424101       3.06634         1196.959990                   1041.355192
min       100.400000     1.000000           100.500000       0.000000 -149010.300000    -0.993402      0.000000       0.00000            0.000000                      0.000000
25%       399.000000     3.000000           581.775000     130.000000      21.348496     0.066383      0.000000       0.00000            0.000000                      0.000000
50%       720.000000     9.000000          1087.240000     420.000000     125.949400     0.234745      3.000000       7.00000          543.602500                    472.934175
75%      1388.440000    35.000000          2124.020000     850.000000     371.753469     0.366613     11.000000       7.00000         1129.726111                    982.861717
max    300000.000000  3318.000000        175815.000000   40000.000000   19363.000000    16.173575    162.000000       7.00000        12114.130000                  10539.293100

剛剛說了,大於100塊錢的飾品總共有3319種。過濾掉七天內在steam上還沒賣掉10件的冷門物品:

After threshold(history_sold >= 10) filtered: 
              price     sell_num  steam_predict_price  buy_max_price          gap  gap_percent  history_sold  history_days  average_sold_price  average_sold_price_after_tax
count    903.000000   903.000000           903.000000     903.000000   903.000000   903.000000    903.000000         903.0          903.000000                    903.000000
mean     628.866235   125.530454           932.755083     554.158361   104.211634     0.185932     34.162791           7.0          842.618240                    733.077869
std      907.966593   247.951096          1169.944022     760.729292   312.992334     0.172418     33.085709           0.0          978.752596                    851.514758
min      100.400000     1.000000           105.420000       0.000000 -4905.176920    -0.920829     10.000000           7.0           72.710000                     63.257700
25%      203.250000    17.000000           282.535000     169.500000    23.564950     0.127844     14.000000           7.0          265.992983                    231.413895
50%      390.000000    47.000000           588.980000     342.000000    78.944555     0.229248     21.000000           7.0          547.512000                    476.335440
75%      702.500000   124.500000          1048.210000     637.500000   164.666248     0.288242     38.000000           7.0          990.052053                    861.345286
max    13888.000000  3318.000000         12623.310000   12000.000000  1488.952000     0.824527    162.000000           7.0        10325.084000                   8982.823080

還剩903件。

在這些飾品中,收益最高的有以下這些:

短劍(★) | 多普勒 (嶄新出廠): 2204.9403249999996(steam average sold price after tax) - 1208.5(buff) = 996.4403249999996(beyond 82.45%). Sold 14 items in 7 days.
 steam url:https://steamcommunity.com/market/listings/730/%E2%98%85%20Stiletto%20Knife%20%7C%20Doppler%20%28Factory%20New%29
鮑伊獵刀(★) | 多普勒 (嶄新出廠): 1575.8979697674422(steam average sold price after tax) - 923.08(buff) = 652.8179697674422(beyond 70.72%). Sold 45 items in 7 days.
 steam url:https://steamcommunity.com/market/listings/730/%E2%98%85%20Bowie%20Knife%20%7C%20Doppler%20%28Factory%20New%29
暗影雙匕(★) | 多普勒 (嶄新出廠): 938.4260704918031(steam average sold price after tax) - 567.0(buff) = 371.4260704918031(beyond 65.51%). Sold 63 items in 7 days.
 steam url:https://steamcommunity.com/market/listings/730/%E2%98%85%20Shadow%20Daggers%20%7C%20Doppler%20%28Factory%20New%29
折刀(★) | 多普勒 (嶄新出廠): 951.7136222222223(steam average sold price after tax) - 602.5(buff) = 349.2136222222223(beyond 57.96%). Sold 29 items in 7 days.
 steam url:https://steamcommunity.com/market/listings/730/%E2%98%85%20Navaja%20Knife%20%7C%20Doppler%20%28Factory%20New%29
摺疊刀(★) | 伽瑪多普勒 (嶄新出廠): 1774.8963959999996(steam average sold price after tax) - 1148.72(buff) = 626.1763959999996(beyond 54.51%). Sold 27 items in 7 days.
 steam url:https://steamcommunity.com/market/listings/730/%E2%98%85%20Flip%20Knife%20%7C%20Gamma%20Doppler%20%28Factory%20New%29
爪子刀(★) | 伽瑪多普勒 (嶄新出廠): 3944.1749666666665(steam average sold price after tax) - 2567.0(buff) = 1377.1749666666665(beyond 53.65%). Sold 11 items in 7 days.
 steam url:https://steamcommunity.com/market/listings/730/%E2%98%85%20Karambit%20%7C%20Gamma%20Doppler%20%28Factory%20New%29
獵殺者匕首(★) | 多普勒 (嶄新出廠): 1355.3042207547169(steam average sold price after tax) - 898.0(buff) = 457.3042207547169(beyond 50.92%). Sold 55 items in 7 days.
 steam url:https://steamcommunity.com/market/listings/730/%E2%98%85%20Huntsman%20Knife%20%7C%20Doppler%20%28Factory%20New%29
蝴蝶刀(★) | 多普勒 (嶄新出廠): 4046.7939272727276(steam average sold price after tax) - 2700.0(buff) = 1346.7939272727276(beyond 49.88%). Sold 13 items in 7 days.
 steam url:https://steamcommunity.com/market/listings/730/%E2%98%85%20Butterfly%20Knife%20%7C%20Doppler%20%28Factory%20New%29
獵殺者匕首(★) | 表面淬火 (破損不堪): 770.6362125000003(steam average sold price after tax) - 515.0(buff) = 255.63621250000028(beyond 49.64%). Sold 10 items in 7 days.
 steam url:https://steamcommunity.com/market/listings/730/%E2%98%85%20Huntsman%20Knife%20%7C%20Case%20Hardened%20%28Well-Worn%29

短劍從buff買,然後賣到steam裏最划算。(2019年12月7日12:51:08增補:這裏其實不能這麼算,畢竟多普勒,玄學刀,玄學武器可以忽略。後續更新使用價格的.25分位點價格,拋棄了均價,這種情況應該會緩解很多。)buff最低賣1208.5元,steam最近7天的平均售價扣完13%的稅之後是2204.9,所以假設以這個價格賣到steam,能多出996.4的差價,收益82.45%!

嗯,貌似比充值卡還賺唉!充值卡50刀的大概228,收益率也才(350-228)/228=53.5%,這個收益率竟然達到了82.45%!不過最近7天才賣了14件,也許不是那麼好賣。往下瞅瞅,暗影雙匕收益率65.51%呢,而且最近七天賣了63件,穩啊!

收益最高的前50個基本全是刀、手套之類的,收益比較高且比較好賣的槍械類飾品是大姐姐:

AWP(StatTrak™) | 黑色魅影 (嶄新出廠): 861.5006272727269(steam average sold price after tax) - 620.0(buff) = 241.5006272727269(beyond 38.95%). Sold 35 items in 7 days.
 steam url:https://steamcommunity.com/market/listings/730/StatTrak%E2%84%A2%20AWP%20%7C%20Neo-Noir%20%28Factory%20New%29

不過38.95%的收益率跟刀比起來還是差太遠啊!

代碼

最後最重要的,代碼在哪兒?

  • https://github.com/puppylpg/buff_csgo_skin_crawler

代碼我放到自己的github上了,開源免費,具體採用什麼開源協議我暫時還沒空想,畢竟這兩天忙裏偷閒臨時寫的程序,先把基礎功能搞上吧。後續視情況再慢慢完善完善。使用方法在README裏已經(不完善地)寫了寫,有興趣的小夥伴歡迎研究代碼,順便點個贊。能提個完善功能的Merge Request自然是最好不過的了。

最後說一句:搞這個純屬興趣愛好,並不是爲了倒賣飾品賺錢(當然也賺不了錢),更不是出於惡意,禁止惡意使用該爬蟲,否則後果自負。同時不要爬的太頻繁,給buff服務器造成太大壓力。要不然被封了……爬蟲何必爲難服務器,服務器又何必爲難爬蟲呢……

First Rule: BE GOOD AND TRY TO FOLLOW A WEBSITE’S CRAWLING POLICIES. Don’t crawl the website to often!

後續更新

爬取網易buff CSGO飾品數據 - 優化篇

本文從我的個人網站搬運過來,畢竟現在Google搜索好像並不能搜到我的文章,還是在csdn再放一份吧。以後我的blog基本都發在個人網站上了,thank you CSDN~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章