はじめに
DBDという対人ゲームで、あるキャラクターを使うと苦手なマップばかり当たるので、猜疑心からマップカウンターを作りました。(なお結果としては私が苦手なマップがDBDに多いだけでした!)
目次
- node.js+Express+pugインストール
- DBDのマップをスクリピング
- JSONの読み書き
- 動的リンクを扱う
- .pugへ変数を渡す
- .pugでhtmlを生成
- cssの記述
1.node.js+Express+pugインストール
ここを見ながらインストール
2.DBDのマップをスクレイピング
稚拙なソースですが動きます!
```python:dbdmap.py from time import sleep import jsondef 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)以上すべてのソースコードを記載したわけではありませんが、詰まる恐れがある点について解説できました。
もし質問があればどうぞコメントにどうぞ。