Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Denoでやってみるスクレイピング

 Denoでやってみるスクレイピング

Deno でやってみるスクレイピング

Deno 向けに提供されている各種パッケージを使い、
リンク切れ探索するスクレイピングツールを作成する。

https://github.com/Octo8080X/deno-scraiping-find-break-link

虎の穴ラボ株式会社

February 17, 2023
Tweet

More Decks by 虎の穴ラボ株式会社

Other Decks in Technology

Transcript

  1. Copyright (C) 2021 Toranoana Inc. All Rights Reserved. 2023/02/15
 toranoana.deno

    #11 
 
 虎の穴ラボ
 奥谷 一陽
 Denoでやってみるスクレイピング

  2. Copyright (C) 2021 Toranoana Inc. All Rights Reserved. 自己紹介
 奥谷

    一陽
 所属:虎の穴ラボ株式会社
 担当:Fantiaなど新規事業系の開発
 興味:TypeScript、Deno
 おすすめコンテンツ:
   『暴太郎戦隊ドンブラザーズ』
   『STAR WARS ハイリパブリック 』
 
 Twitter:@okutann88

  3. Copyright (C) 2021 Toranoana Inc. All Rights Reserved. Denoでやってみるスクレイピング
 -

    「スクレイピング」とは
 - 作るもの
 - 利用技術/モジュール
 - fetch
 - deno-dom
 - SQLite
 - できたもの
 - まとめ
 

  4. Copyright (C) 2021 Toranoana Inc. All Rights Reserved. 「スクレイピング」
 wikipedia曰く


    ウェブスクレイピング(英: Web scraping)とは、ウェブサイトから情報を抽出するコンピュータソフトウェア 技術のこと。通常このようなソフトウェアプログラムは低レベルのHTTPを実装することで、もしくはウェブ ブラウザを埋め込むことによって、WWWのコンテンツを取得する。ウェブスクレイピングはユーザーが 手動で行なうこともできるが、一般的にはボットやクローラ(英: Web crawler)を利用した自動化プロセス を指す。
 Wikipedia ウェブスクレイピングの頁より 
 Webから情報の抽出をする = スクレイピング

  5. Copyright (C) 2021 Toranoana Inc. All Rights Reserved. 作るもの
 指定したWebサイトをクロールして、


    参照先が無い「リンク切れを探すツール」を作成します。

  6. Copyright (C) 2021 Toranoana Inc. All Rights Reserved. 利用技術/モジュール
 -

    fetch
 - deno-dom
 - SQLite
 スクレイピングの第一歩目は、
 Webへのアクセス。
 とりあえずこれがあれば(CSRがなければ)
 これで十分戦えます。

  7. Copyright (C) 2021 Toranoana Inc. All Rights Reserved. 利用技術/モジュール -

    fetch
 export async function download(url: string, path: string) { try { const getResult = await fetch(url); if (!getResult.ok) throw new Error("Fetch response error"); const html = await getResult.text(); Deno.writeTextFile(path, html); insertDownloadLog(url, path); return { html }; } catch (error) { console.error(error); } return { html: undefined }; }
  8. Copyright (C) 2021 Toranoana Inc. All Rights Reserved. 利用技術/モジュール
 -

    fetch
 - deno-dom
 - SQLite
 domの解析には、モジュールを使ったほうが 格段に楽です。
 公式マニュアルでも紹介されているモジュー ルです。

  9. Copyright (C) 2021 Toranoana Inc. All Rights Reserved. 利用技術/モジュール -

    deno-dom
 import { DOMParser } from "https://deno.land/x/deno_dom/deno-dom-wasm.ts"; export function inspect(html: string) { const doc = new DOMParser().parseFromString(html, "text/html")!; const elements = doc.querySelectorAll("a")!; const anchors = new Set( Array.from(elements) .filter((e) => e.attributes[0].nodeName == "href") .map((e) => e.attributes[0].value! as string) .filter((url: string) => url.match(/^(\/)(?!.*\#)/)) ); anchors.forEach((url) => { insertInspectEntry(url); }); }
  10. Copyright (C) 2021 Toranoana Inc. All Rights Reserved. 利用技術/モジュール
 -

    fetch
 - deno-dom
 - SQLite
 簡易なCLIツールとして実装したいので、 環境 構築を要するようなRDBMSは、避けました。
 sqlite_のような名称のモジュールは多数あります が、☆が多いものから選定しています。
 
 

  11. Copyright (C) 2021 Toranoana Inc. All Rights Reserved. 利用技術/モジュール -

    SQLite
 import { DB } from "https://deno.land/x/sqlite/mod.ts"; const db = new DB("scraping.db"); db.execute(` CREATE TABLE IF NOT EXISTS download_logs ( url TEXT, path TEXT, created_at INTEGER ) `); db.execute(` CREATE TABLE IF NOT EXISTS inspection_logs ( targetUrlPathName TEXT primary key, isExist INTEGER, created_at INTEGER ) `); export function insertDownloadLog(url: string, path: string) { const timestamp = new Date().getTime(); db.query("INSERT INTO download_logs (url, path, created_at) VALUES (?, ?, ?)", [url, path, timestamp], ); }
  12. Copyright (C) 2021 Toranoana Inc. All Rights Reserved. できたもの -

    動かしてみると...
 
 
 
 - 実際に切れているリンクが、2つ見つかりました
 - 近日中に直したいと思います
 - 「どこ」に切れたリンクが書いてあるのか?
 という視点が無い出力になっているので、修正予定
 $ deno run --allow-net --allow-write --allow-read scraping.ts --url http://host.docker.internal:4507/blog/
 # 出力省略
 ** リンク切れ **
 /blog/2019/10/16/sequelize0/
 /blog/2019/11/18/ruby18
 - 

  13. Copyright (C) 2021 Toranoana Inc. All Rights Reserved. まとめ
 -

    Deno でスクレイピングは、あまり困らずできる
 - SSRされるだけのサイトであれば、fetchで十分対応可能
 - CSRされるサイトであれば puppeteer が使える
 - ツールは公開していますが、取り扱いにはご注意ください