Slide 1

Slide 1 text

Copyright (C) 2021 Toranoana Inc. All Rights Reserved. 2023/02/15
 toranoana.deno #11 
 
 虎の穴ラボ
 奥谷 一陽
 Denoでやってみるスクレイピング


Slide 2

Slide 2 text

Copyright (C) 2021 Toranoana Inc. All Rights Reserved. 自己紹介
 奥谷 一陽
 所属:虎の穴ラボ株式会社
 担当:Fantiaなど新規事業系の開発
 興味:TypeScript、Deno
 おすすめコンテンツ:
   『暴太郎戦隊ドンブラザーズ』
   『STAR WARS ハイリパブリック 』
 
 Twitter:@okutann88


Slide 3

Slide 3 text

Copyright (C) 2021 Toranoana Inc. All Rights Reserved. 普段Denoで何をされていますか?


Slide 4

Slide 4 text

Copyright (C) 2021 Toranoana Inc. All Rights Reserved. CLI


Slide 5

Slide 5 text

Copyright (C) 2021 Toranoana Inc. All Rights Reserved. GUIアプリ


Slide 6

Slide 6 text

Copyright (C) 2021 Toranoana Inc. All Rights Reserved. Web


Slide 7

Slide 7 text

Copyright (C) 2021 Toranoana Inc. All Rights Reserved. 今回は「スクレイピング」を試します


Slide 8

Slide 8 text

Copyright (C) 2021 Toranoana Inc. All Rights Reserved. Denoでやってみるスクレイピング
 - 「スクレイピング」とは
 - 作るもの
 - 利用技術/モジュール
 - fetch
 - deno-dom
 - SQLite
 - できたもの
 - まとめ
 


Slide 9

Slide 9 text

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


Slide 10

Slide 10 text

Copyright (C) 2021 Toranoana Inc. All Rights Reserved. 作るもの
 指定したWebサイトをクロールして、
 参照先が無い「リンク切れを探すツール」を作成します。


Slide 11

Slide 11 text

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


Slide 12

Slide 12 text

Copyright (C) 2021 Toranoana Inc. All Rights Reserved. 利用技術/モジュール
 - fetch
 - deno-dom
 - SQLite
 スクレイピングの第一歩目は、
 Webへのアクセス。
 とりあえずこれがあれば(CSRがなければ)
 これで十分戦えます。


Slide 13

Slide 13 text

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 }; }

Slide 14

Slide 14 text

Copyright (C) 2021 Toranoana Inc. All Rights Reserved. 利用技術/モジュール
 - fetch
 - deno-dom
 - SQLite
 domの解析には、モジュールを使ったほうが 格段に楽です。
 公式マニュアルでも紹介されているモジュー ルです。


Slide 15

Slide 15 text

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); }); }

Slide 16

Slide 16 text

Copyright (C) 2021 Toranoana Inc. All Rights Reserved. 利用技術/モジュール
 - fetch
 - deno-dom
 - SQLite
 簡易なCLIツールとして実装したいので、 環境 構築を要するようなRDBMSは、避けました。
 sqlite_のような名称のモジュールは多数あります が、☆が多いものから選定しています。
 
 


Slide 17

Slide 17 text

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], ); }

Slide 18

Slide 18 text

Copyright (C) 2021 Toranoana Inc. All Rights Reserved. できたもの
 deno-scraiping-find-break-link
 
 https://github.com/Octo8080X/deno-scraiping-find-break-link 


Slide 19

Slide 19 text

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
 - 


Slide 20

Slide 20 text

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


Slide 21

Slide 21 text

Copyright (C) 2021 Toranoana Inc. All Rights Reserved. ありがとうございました