【GAS】스프레드 시트로 스크래핑하여 시트에 정리

15595 단어 자바스크립트gas

개요



Google 스프레드시트를 사용하여 스크래핑을 했을 때의 메모입니다.
시트에 작성한 URL의 meta 정보를 얻는 스크립트를 작성했습니다.

스크래핑 방법



이번에는 아래와 같은 시트를 작성을 사용합니다.
이 예에서 URL에 CodeZine 님의 기사 URL을 입력했습니다.


1. Parser 라이브러리 추가



이번에는 더 쉽게 얻을 수 있도록 다음 라이브러리를 사용합니다.
  • 공식 페이지
  • 소스 코드

  • 스프레드시트 메뉴에서 도구 > 스크립트 편집기를 선택하여 편집기를 엽니다.
    왼쪽 메뉴의 「라이브러리+」로 ID를 지정하는 것으로 추가가 가능합니다.

    스크립트 ID는 M1lugvAXKKtUxn_vdAG9JZleS6DrsjUUV입니다.
    (소스 코드의 URL 부분이 ID입니다.※소스에 기재되어 있는 ID는 낡기 때문에 주의)

    ID를 입력·검색하고, 다음의 상태로 「추가」를 합니다.


    2. 소스 코드 구현



    소스 코드는 다음과 같습니다.
    function myFunction() {
      // 現在開いているシートを参照する
      const sheet = SpreadsheetApp.getActiveSheet();
    
      // 取得するデータ範囲
      const firstCol = 1; // A列
      const lastCol  = 1; // A列のみ
      const firstRow = 2; // 2行目から
      const lastRow  = sheet.getLastRow(); // 最終行まで
    
      // 入力するデータ範囲
      const titleCol       = 2; // B列
      const keywordCol     = 3; // C列
      const descriptionCol = 4; // D列
    
      // 指定範囲の値を取得して一次配列にする
      const values = sheet.getRange(firstRow, firstCol, lastRow, lastCol).getValues();
      const urls = values.map((line) => line[0]);
    
      for (var key in urls) {
        const url = urls[key];
    
        let title       = '-';
        let keyword     = '-';
        let description = '-';
    
        // URLに対しフェッチを行ってHTMLデータを取得する
        const html = UrlFetchApp.fetch(url).getContentText('UTF-8');
    
        // Parserライブラリを使用して条件を満たしたHTML要素を抽出する
        const head = Parser.data(html).from('<head>').to('</head').build();
        title = Parser.data(html).from('<title>').to('</title').build();
    
        // 空でないかチェック
        const hadKeyword = head.match(/<meta name="keywords" content="">/g);
        const hasKdescription = head.match(/<meta name="description" content="">/g);
    
        if (hadKeyword === null) {
          keyword = Parser.data(html).from('<meta name="keywords" content="').to('">').build();
        }
        if (hasKdescription === null) {
          description = Parser.data(html).from('<meta name="description" content="').to('">').build();
        }
    
        // 書き込む行数を取得
        const low = parseInt(key) + parseInt(firstRow);
    
        // シートに書き込み
        sheet.getRange(low, titleCol).setValue(title);
        sheet.getRange(low, keywordCol).setValue(keyword);
        sheet.getRange(low, descriptionCol).setValue(description);
      }
    }
    

    스크래핑



    스크래핑을 하는 부분은 다음과 같습니다.

    먼저 URL에 액세스하여 HTML을 얻고 원하는 요소를 Parser.data를 사용하여 구문 분석합니다..from()에서 검색할 시작 문자열.to()로 끝나는 문자열을 지정하고 .build()로 실행합니다.
    const html  = UrlFetchApp.fetch(url).getContentText('UTF-8');
    const title = Parser.data(html).from('<title>').to('</title').build();
    

    이제 <title>~~~</title>~~~ 부분을 검색할 수 있습니다..build() (은)는 최초의 요소를 돌려줍니다만, li 등 복수 취하는 경우는 .iterate() (을)를 사용하면 배열로 돌려줍니다.

    자세한 사용법은, 이하 참고 사이트가 상세하게 써 주시고 있습니다.
    GAS로 간단 WEB 스크래핑! HTML을 쉽게 파싱 할 수있는 라이브러리 인 Parser를 사용해 보았습니다.

    빈 요소 대책



    이번에 keyword와 description에 관해서는 일단 head의 소스를 취득해, 하늘인가 어떤가를 체크하고 있습니다.
    // Parserライブラリを使用して条件を満たしたHTML要素を抽出する
    const head = Parser.data(html).from('<head>').to('</head').build();
    
    // 空でないかチェック
    const hadKeyword = head.match(/<meta name="keywords" content="">/g);
    const hasKdescription = head.match(/<meta name="description" content="">/g);
    

     
    이것은, 간단하게 이하와 같이 취득해 content"" 부분이 비었을 때,
    Parser.data(html).from('<meta name="keywords" content="').to('">').build();
    

    닫기 태그가 의도하지 않은 위치에서 판정되어 비어 있지 않고 취득하고 싶지 않은 부분이 잡혀 버렸기 때문에의 대책입니다.
    .from 등에는 정규 표현도 사용할 수 없기 때문에, 여러가지 시도한 결과 이것에 침착했습니다.
    (라이브러리 소스를 복사하여 변경하면 잘 사용할 수 있지만 ...)

    요약



    이런 식으로 스크립트를 실행하고 무사히 meta 태그를 얻을 수있었습니다.

    실제로는 외부 사이트가 아니고, 자신의 사이트의 태그를 리스트 업 하기 위해서 작성한 것입니다만, PHP나 서버가 없어도 스크래핑을 할 수 있는 것은 매우 편리하다고 생각했습니다

    이상입니다!

    좋은 웹페이지 즐겨찾기