从 SteamDB 获取最新免费游戏并通过 ASF 自动领取(转载/备忘)

前言

对于游戏玩家而言,没有什么比喜加一更令人心情愉悦的了。Steamdb 在今年年初也专门设置了一个展示当前 Steam 处于活动免费的游戏列表,其中 Weekend 为标记的就是常见的周末免费体验,而 Keep 则代表可以免费入库的游戏。大多数 Steam 中文资讯也是从 Steamdb 中获取到的消息,这得益于被充分利用的 Steam API。在之前的文章中,我已经介绍了 ASF 的强大作用,它的网页功能其实是基于程序 API 完成的。在 Headless 下我们可以通过 ASF 密码即可远程调用这些 API,从而达到自动领取免费游戏的目的。

 

解决方案

抓取免费游戏列表

  • 使用 Python 的 request 库,很容易抓取到这个网页
  • 创建一个 list 来储存抓取的数据
    • 2D 表结构为 [[sub number],[sub name],[sub Steam URL]]
          
       headers = {
          "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36"}
          # 发起request
          req = request.Request("https://steamdb.info/upcoming/free/#upcoming-promotions", headers=headers)
          response = request.urlopen(req)  # 打开网站
          html = response.read()  # 读取内容
      
          charset = chardet.detect(html)  # 获取编码格式
          html = html.decode(charset["encoding"])  # 解码
          freeGameList = []  # 初始化免费游戏sub列表
          soup = BeautifulSoup(html, features="lxml")
          freeGame_list_soup = soup.find('table', attrs={
              'class': 'table-products table-responsive-flex table-hover text-left table-sortable'})  # 找到免费游戏表格

      从表格中读取 Sub 信息

      • 需要从表中提取到 Sub 编号,Sub 名称和对应的 Steam 链接
      • 需要判断免费种类是周末免费还是入库免费
    • for game_sub in freeGame_list_soup.find_all('tr', attrs={'class': 'app sub'}):
              game_subid = str(game_sub["data-subid"])
              print("Sub id:", game_subid)  # 打印标签属性 game_sub.attrs会打印所有
      
              # 找到该游戏的Steam链接
              for game_logo in game_sub.find_all('td', attrs={'class': 'applogo'}):
                  game_steamLink = game_logo.find('a')
                  game_steamLink = game_steamLink["href"]
                  # print("Steam link:", game_steamLink)
      
              # 找到该游戏的名字
              game_td = game_logo.find_next_sibling('td')
              game_sub_link = game_td.find('a')
              game_name = game_sub_link.find('b').string
              print(game_name)
      
              # 确定免费属性 (Keep or Weekend)
              game_type_menu = game_sub.find_all('td', attrs={'class': 'price-discount'})
              if "Keep" in str(game_type_menu):
                  game_type_string = "Keep"
              else:
                  game_type_menu = game_sub.find('td', attrs={'class': 'text-center'})
                  # print(game_type_menu)
                  game_type_string = game_type_menu.next_sibling.next_sibling.string
                  # print(game_type_Weekend)
              print(game_type_string)
      
              # 生成免费入库游戏列表
              if game_type_string == "Keep":  # Not Weekend
                  freeGame_Add = [game_subid, game_name, game_steamLink]
                  freeGameList.append(freeGame_Add)
                  # print(freeGameList)

      生成 ASF 领取游戏命令

      • 免费游戏 Sub 列表已经被储存在 freeGameList 中,只需列表即可生成完整的 SubList
      • 根据 ASF 文档,为整个 ASF 程序下所有 bot 领取 Sub 的命令为 addlicense ASF sub/123, sub/456
    •  ASFCommand = "addlicense ASF sub/"
          if (len(freeGameList) != 0):
              for i in range(len(freeGameList)):
                  ASFCommand = ASFCommand + freeGameList[i][0]
                  ASFCommand += ", sub/"
              ASFCommand = ASFCommand[:-6]  # 删除最后一组", sub/"
              print(ASFCommand)
          else:
              print("No Free Game Available!")

      发起 ASF API 请求

       # 定义header
          api_headers = {
              "accept": "application/json",
              "Authentication": "YourASFPasswd",
              "Content-Type": "application/json",
              "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36"
          }
          # 定义Body
          api_POST_data = {
              "Command": ASFCommand
          }
          # print(api_POST_data)
          # 定义URL
          asf_url = "https://yourASFURL/Api/Command"
          # 发起POST request
          asf_req = requests.post(asf_url, headers=api_headers, data=json.dumps(api_POST_data))
          print(asf_req.text)

      运行效果

      运行效果

点赞

发表回复

电子邮件地址不会被公开。必填项已用 * 标注