summaryrefslogtreecommitdiff
path: root/app/scrapers/navey-floor.ts
blob: 14736dab7680879c45cb8aca34d5807b29eb1dba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import * as cheerio from "cheerio";
import type { Scraper, VenueMeta } from "./base";
import type { EventInput } from "~/lib/db.server";

export const venue: VenueMeta = {
  id: "navey-floor",
  name: "navey floor",
  url: "https://navey-floor.com",
  area: "赤坂",
  capacity: 150,
};

function parseNaveyDate(text: string): string | null {
  const m = text.trim().match(/(\d{4})\/(\d{2})\/(\d{2})/);
  if (!m) return null;
  return `${m[1]}-${m[2]}-${m[3]}`;
}

export const scraper: Scraper = {
  venue,
  async scrape(): Promise<EventInput[]> {
    const res = await fetch("https://navey-floor.com/event/");
    if (!res.ok) throw new Error(`HTTP ${res.status}`);
    const html = await res.text();
    const $ = cheerio.load(html);
    const events: EventInput[] = [];

    $("article.hentry").each((_, el) => {
      const $el = $(el);

      const date = parseNaveyDate($el.find("h3.event-date__h").text());
      if (!date) return;

      const $titleLink = $el.find("h2.event-title__h > a");
      const title = $titleLink.text().replace(/\s+/g, " ").trim();
      const sourceUrl = $titleLink.attr("href") ?? null;
      if (!title) return;

      let openTime: string | null = null;
      let startTime: string | null = null;
      let artist: string | null = null;
      let price: string | null = null;

      $el.find("ul.event-ul li").each((_, li) => {
        const $li = $(li);
        const label = $li.find("span").first().text().trim();

        if (label === "open/start") {
          const m = $li.text().match(/(\d{2}:\d{2})\/(\d{2}:\d{2})/);
          if (m) { openTime = m[1]; startTime = m[2]; }
        } else if (label === "act") {
          const $clone = $li.clone();
          $clone.find("span").remove();
          artist = $clone.text().replace(/^\s*:\s*/, "").replace(/\s+/g, " ").trim() || null;
        } else if (label === "ticket") {
          const $clone = $li.clone();
          $clone.find("span").remove();
          price = $clone.text().replace(/^\s*:\s*/, "").replace(/\s+/g, " ").trim() || null;
        }
      });

      const ticketUrl = $el.find("div.attention a").attr("href") ?? null;

      events.push({
        venue_id: venue.id,
        title,
        artist,
        date,
        open_time: openTime,
        start_time: startTime,
        price,
        ticket_url: ticketUrl,
        source_url: sourceUrl,
      });
    });

    return events;
  },
};