카운티의 GoTo Et 웹사이트를 이용하기 어려워 플레이 wright+앱시트로 자체 앱을 제작했다

Go To Eat는 매우 실속 있는 조치를 취하면 된다"며"어느 점포에서 이용할 수 있을까요?"그렇죠?이때 본 카운티 고투 잇 홍보 캠페인 사이트는 의외로 이용이 어려워 플레이 wright+앱시트로 자체 앱을 제작했다.

왜 했어요?


이바라키현의 고투 잇 이벤트 사이트는 여기에 있다.
첫 페이지 느낌이 좋아요.
https://www.gotoeat-ibaraki.com/

그런데...
가게 일람페이지로 옮기면 갑자기 낡은 좋은 업무 시스템이 되는 느낌.😇
(조금만 더 노력해라.)

이 페이지라면.
  • 스마트폰이 지원되지 않아 스마트폰으로 볼 수 없음
  • 지도에서 검색할 수 없기 때문에 현재 소재지 주변의 점포를 찾는 것이 번거롭다
  • 그래서 무부호 공구AppSheet로 재제작을 시도했다.
    이런 형태의 점포 일람 앱을 만들면Glide도 편리하지만, 글래드의 경우 무료 테두리에 500줄 제한이 있어 이번에 앱시트를 쓰기로 했다.
    글라이드에 관해서는 이전에 이쪽 기사에서 총결산한 적이 있다.
    무사이즈!Glide 폭발 속도로 음식점 검색 앱을 만들어 봤습니다. - Qita

    시제품


    앱시트로 만든 건 이쪽이야.

    해당 스마트폰은 점포 명칭과 요소를 통해 검색하거나 맵스를 통해 현재 소재지 주변 점포에서 검색할 수 있어 개인 이용이 필요하다.
    다음 항목부터 이 방법을 해설한다.
    잘라내기를 통해 데이터를 얻을 때 사용 약관을 주의하십시오.
    이번 앱은 외부에 공개되지 않고 개인적으로만 사용된다.

    생성 방법


    1. 플레이 wright에서 롤업


    프로그램을 만드는 데 데이터가 필요하기 때문에 커튼으로 그것을 얻는다.
    스클린은 노드다.js를 이용한 면도기Playwright.
    Node.제이스의 커튼Puppeteer이 유명하다고 하니 이번에는 플레이 wright를 사용해 봤다.Playwright는 Puppeettier에서 파생된 것이기 때문에 기본적으로 같은 API를 사용할 수 있다.
    https://github.com/microsoft/playwright

    1-1. 환경 구조


    우선, 모든 디렉터리에 프로젝트를 만듭니다.
    $ yarn init -y
    
    의존 모듈을 추가합니다.
    json2csv 객체의 CSV 해석에 사용됩니다.
    ts-node는 노드입니다.js의 Type Script 실행 환경입니다.TypeScript는 명시적으로 컴파일할 필요가 없습니다.
    $ yarn add ts-node playwright typescript json2csv
    
    ts-node의 실행 스크립트를 package.json에 추가합니다.
    package.json
      "scripts": {
        "start": "ts-node index.ts"
      },
    
    이렇게 환경 구축이 완성되었다.

    1-2. 덮어쓰다

    index.ts를 추가하고 다음 코드를 기재합니다.
    코드는 커튼의 관계상 이해하기 어렵지만 다음과 같은 동작이 있다.
  • 고투 잇츠시티의 점포 일람페이지
  • 열기
  • 점포 상세 행마다 점포 상세 페이지로 이동 & 정보 획득
  • 모든 페이지가 끝난 후 결과는 CSV 형식으로 해석
  • 쓰기 파일
  • index.ts
    import { chromium } from "playwright";
    import { Parser } from "json2csv";
    import * as fs from "fs";
    
    const options = {
      headless: false,
    };
    
    const BASE_URL =
      "https://area34.smp.ne.jp/area/table/27130/3jFZ4A/M?S=%70%69%6D%67%6E%32%6C%62%74%69%6E%64&_page_27130";
    const PER_PAGE = 10;
    
    (async () => {
      const stores = [];
      const browser = await chromium.launch(options);
      const page = await browser.newPage();
      const navigationPromise = page.waitForNavigation();
    
       await page.goto(BASE_URL);
    
      // 最大ページ数を取得
      const maxPage = await page.evaluate(() => {
        return Math.ceil(
          Number(document.querySelector(".smp-count").textContent) / 10
        );
      });
    
      // 最大ページ数の分だけループ
      for (let pageNumber = 1; pageNumber <= maxPage; pageNumber++) {
        const currentPageUrl = `${BASE_URL}=${pageNumber}`;
        await page.goto(currentPageUrl);
    
        // 5行目からが店舗データなので5始まりとする
        for (let rowNumber = 5; rowNumber < PER_PAGE + 5; rowNumber++) {
          // 詳細リンクを取得
          const detailLinkSelector = (rowNumber: number) => { return `#smp-table-27130 > tbody > tr.smp-row-${rowNumber}.smp-row-data .smp-cell-col-2 > a` }
          const detailLink = await page.$(detailLinkSelector(rowNumber));
    
          // 詳細リンクがなければスキップ
          if ( !detailLink ) { continue; }
    
          // 詳細ページに遷移してデータを保存
          await page.click(detailLinkSelector(rowNumber));
          await navigationPromise;
    
          const store = await page.evaluate(() => {
            const detailContentData = (rowNumber: number) => {
              return document.querySelector(`body > table > tbody > tr > td > div > div.whole > table > tbody > tr:nth-child(${rowNumber}) > td`)?.textContent?.trim() || ''
            }
    
            return {
              type: detailContentData(10),
              name: detailContentData(3),
              "phone number": detailContentData(8),
              address: detailContentData(6).replace(/\s+/g, "") + detailContentData(7),
              homepage: detailContentData(9),
              holiday: detailContentData(11),
              "business hours": detailContentData(12)
            };
          });
    
          await page.goto(currentPageUrl);
          await navigationPromise;
    
          stores.push(store)
        }
      }
      await browser.close();
    
      // CSVへのパース
      const parser = new Parser;
      const csv = parser.parse(stores);
    
      // ファイル書き込み
      fs.writeFileSync('goto-eat.csv', csv)
    })();
    
    실행만 남았다.
    $ yarn start
    
    플레이 wright의 옵션에서 헤드리스를 가짜로 만들었기 때문에 크롬이 일어서서 행동할 것 같다.

    완성 후 goto-eat.csv 완성.
    (260쪽이 있어 시간이 오래 걸린다.)

    2. 앱시트에서 앱 만들기


    점포 데이터가 완성됐기 때문에 앱시트로 적용했습니다.

    2-1. Google 스프레드시트 만들기


    먼저 Google 스프레드시트에서 CSV를 가져옵니다.
    스프레드시트ファイル > インポート > アップロード를 열어서 아까 거goto-eat.csv를 올리면 돼요.
    https://www.google.com/intl/ja_jp/sheets/about/

    2-2. AppSheet을 통해 가져오기


    방문AppSheet.
    https://www.appsheet.com/
    클릭Start for free
    선택Make a new app>Start with your own data Choose your data에서 방금 만든 스프레드시트를 선택하면 됩니다.

    가져오기가 완료되면 응용 프로그램이 생성됩니다.
    워크시트 제목에서 앱의 카테고리를 자동으로 인식해 좋은 느낌을 낼 수 있어야 한다(대단하다).

    그리고 프로젝트 이름을 조금만 고치고 디자인을 하면 완성됩니다.

    AppSheet의 디자인에 관해서는 참고를 하겠습니다.
    https://tonari-it.com/appsheet-free-deploy/

    끝말


    이상은'이츠청현의 고투 잇 사이트는 보기 어려워 플레이 wright+앱시트로 다시 만든 이야기'였다.
    Playwright도 AppSheet을 처음 사용해서 둘 다 잘 쓰인다.
    앱시트를 포착하는 데 3시간가량 걸렸다.이번처럼 한정된 용도로 애플리케이션을 제작하는 것이 편리할 것 같다.
    나는 이 앱을 조심스럽게 사용해서 Go To Eat를 진행하고 싶다.

    좋은 웹페이지 즐겨찾기