LoginSignup
0
1

More than 1 year has passed since last update.

node.js+Express+pugでDBDのマップカウンターを作る

Last updated at Posted at 2021-07-24

はじめに

DBDという対人ゲームで、あるキャラクターを使うと苦手なマップばかり当たるので、猜疑心からマップカウンターを作りました。(なお結果としては私が苦手なマップがDBDに多いだけでした!)

目次

  1. node.js+Express+pugインストール
  2. DBDのマップをスクリピング
  3. JSONの読み書き
  4. 動的リンクを扱う
  5. .pugへ変数を渡す
  6. .pugでhtmlを生成
  7. cssの記述

1.node.js+Express+pugインストール

ここを見ながらインストール

2.DBDのマップをスクレイピング

稚拙なソースですが動きます!

dbdmap.py
from time import sleep
import json

def main():
    import requests
    from bs4 import BeautifulSoup

    FullURL = "https://deadbydaylight.fandom.com"
    URL = "https://deadbydaylight.fandom.com/wiki/Dead_by_Daylight_Wiki"
    page = requests.get(URL)

    soup = BeautifulSoup(page.content, "html.parser")

    results = soup.find(id="fpRealms")
    results = results.find("div", {"class": "fplinks"})
    results = results.find_all("a")

    maplst = []

    mapdict = {}

    for result in results:
        dbdmap = result["href"]
        if not dbdmap in maplst:
            maplst.append(dbdmap)

    for mapdbd in maplst:
        mapurl = FullURL + mapdbd
        mappage = requests.get(mapurl)
        mapsoup = BeautifulSoup(mappage.content, "html.parser")

        mapresults = mapsoup.find("table", {"class": "wikitable"})
        mapresults = mapresults.find("tbody")
        mapresults = mapresults.find("tr")
        mapresults = mapresults.find_all("td")

        for mapresult in mapresults:
            mapresult = mapresult.find("center")
            mapresult = mapresult.find("a")
            mapdict[mapresult.text.strip()] = 0

        sleep(3)

    with open('<保存したい場所>.json', 'w') as outfile:
        json.dump(mapdict, outfile)

if __name__ == "__main__":
    main()

これにより以下の様なJSONを得られる。

{"Coal Tower": 0, "Groaning Storehouse": 0, "Ironworks of Misery": 0, ...

3.JSONの読み書き

ここで詰まったのでいくつか注意点を書いておきます

jsonはクライアント側からは読み書きできません。

つまり生成されたウェブページに組み込まれたスクリプトからは操作できないです。

そのためサーバー側で操作する必要があります。

また、サーバー側での操作はroutes/index.jsonで行います。(リクエストされたページに対応したファイル)

const fs = require('fs');
const filePath = "./routes/dbdmap.json"

//jsonを読み取る
const dbdmaplst = require("./dbdmap.json");

//jsonに書き込む
fs.writeFile(filePath, JSON.stringify(dbdmaplst), (err) => {
  if (err) console.log('Error writing file:', err)
})

4.動的リンクを扱う

カウンターなので、index/"map名"/"up/down"のような動的リンクを扱えるようにします。

複数個設定できます。

router.get('/', function(req, res, next) {

router.get('/:map/:vote', function(req, res, next) {

受け取ったリンクのキーワードを引数のように扱えます

router.get('/:map/:vote', function(req, res, next) {
  const dbdmaplst = require("./dbdmap.json");
  const vote = req.params.vote;
  if (vote == "up") {
    dbdmaplst[req.params.map] += 1;
  }
  else if (vote == "down") {
    if (dbdmaplst[req.params.map] > 0) {
      dbdmaplst[req.params.map] -= 1;
    }
  }

5.pugへ変数を渡す

json形式で変数を渡します。

res.render('index', { title: 'Epress', dbdmap: dbdmaplst});

以上index.jsの完全なソースはこちら

index.js
var express = require('express');
var router = express.Router();

//read json
const fs = require('fs');
const filePath = "./routes/dbdmap.json"

/* GET home page. */
router.get('/', function(req, res, next) {
  const dbdmaplst = require("./dbdmap.json");
  res.render('index', { title: 'Epress', dbdmap: dbdmaplst});
});

router.get('/:map/:vote', function(req, res, next) {
  const dbdmaplst = require("./dbdmap.json");
  const vote = req.params.vote;
  if (vote == "up") {
    dbdmaplst[req.params.map] += 1;
  }
  else if (vote == "down") {
    if (dbdmaplst[req.params.map] > 0) {
      dbdmaplst[req.params.map] -= 1;
    }
  }

  fs.writeFile(filePath, JSON.stringify(dbdmaplst), (err) => {
    if (err) console.log('Error writing file:', err)
  })

  res.render('index', { title: 'DBD MAP LOG', dbdmap: dbdmaplst});
});
module.exports = router;

6 .pugでhtmlを生成

pugはpythonのようにインデントで管理されているようです。

以下ソース内に注意点を記載

index.pug
//layout.pugをテンプレートに使う
extends layout

//テンプレート内のblock contentに置き換えられる
block content
  //'-'を先頭に記載することでjavascriptを組み込むことができる。
  -var count = 0;
  div(class="tbl")
    table(cellpadding=10)
      //pug 独自のfor/while/if-else文を扱える
      //ここの'dbdmap'はindex.jsから受け取ったもの
      each val, key in dbdmap
        -count += val;
        tr 
          //'#{}'で変数を扱うことができる。
          td #{val}
          td #{key}
          td
            a(href= "/" + key + "/up") up
          td 
            a(href= "/" + key + "/down") down

      h2 Match count: #{count}

pugの記述方法はこちら

7.cssの記述

cssよく分からないのですが、こんな感じにしたらいい感じになりました。。。

style.css
body {
  padding: 50px;
  font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
}

a {
  color: #00B7FF;
}

table, tr, td {
  border: 1px solid black;
  padding: 10px;
}

table {
  display: inline-block;
  float: left;
}

cssの読み込み方。テンプレートのlayout.pugに記載する。

layout.pug
doctype html
html
  head
    title= title
  body
    block content
    //javascript
    script(src='/javascripts/todo.js')
    //css
    link(rel='stylesheet', href='/stylesheets/style.css')

終わりに

DBD MAP LOG — Mozilla Firefox 2021_07_24 12_33_16 (2).png

以上すべてのソースコードを記載したわけではありませんが、詰まる恐れがある点について解説できました。

もし質問があればどうぞコメントにどうぞ。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1