0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have 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のマップをスクレイピング

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

```python: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()


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

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


<h3>3.JSONの読み書き</h3>
<p>ここで詰まったのでいくつか注意点を書いておきます</p>
<p>jsonはクライアント側からは読み書きできません。</p>
<p>つまり生成されたウェブページに組み込まれたスクリプトからは操作できないです。</p>そのためサーバー側で操作する必要があります。</p>
<p>また、サーバー側での操作はroutes/index.jsonで行います。(リクエストされたページに対応したファイル)</p>

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)
})


<h3>4.動的リンクを扱う</h3>
<p>カウンターなので、index/"map名"/"up/down"のような動的リンクを扱えるようにします。</p>
<p>複数個設定できます。</p>

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

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

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

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;
}
}

<h3>5.pugへ変数を渡す</h3>
<p>json形式で変数を渡します。</p>

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


<p>以上index.jsの完全なソースはこちら</p>
```javascript: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のようにインデントで管理されているようです。

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

```pug: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}
<p>pugの記述方法は<a href="https://pugjs.org/api/getting-started.html">こちら</a></p>

<h3>7.cssの記述</h3>
<p>cssよく分からないのですが、こんな感じにしたらいい感じになりました。。。</p>
```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に記載する。

```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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148969/fb99001a-cd30-fc84-5834-cac39ee93dca.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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?