Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
WebView からデータをスクレイピングする
Search
Tatsunori Nakano
October 02, 2021
Programming
650
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
WebView からデータをスクレイピングする
React Native 祭での LT に使った資料です。
https://reactnative-matsuri.com/ja
Tatsunori Nakano
October 02, 2021
Other Decks in Programming
See All in Programming
[ハンズオン]AIへの指示だけで「五目並べ」を作ってみよう
satoshi256kbyte
1
380
HTML-in-Canvasで作る未来のWeb UI表現
clockmaker
5
5.1k
C#の現在地 進化の歴史と、AI時代の.NET Everywhere
neuecc
5
5.2k
Agentic Software Factoryに、すごく賢いIF文を。 / super smart IF statement into the Agentic Software Factory.
rkaga
8
2.3k
[JA] Domain Modeling with Vanilla Rails: 「操作」から再考するRailsの設計論
yasaichi
3
430
エージェントを使い続けるためのメタワーク / Meta-work for keeping using the agent
rkaga
0
130
【加筆修正版】Laravel のアプリケーションをどこにデプロイするか #phpcon_ehime
akase244
0
150
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
220
re:Inventに行く前に知っておきたい現地参加のノウハウ
nokomoro3
0
440
phperだってパンチカードでコーディングしたい
o0h
PRO
0
350
ActionController meets Protocol Buffers
sorah
0
560
コードレビューのボトルネックを"する側"と"される側"の両面から解消する
yub0n
2
1.6k
Featured
See All Featured
From π to Pie charts
rasagy
1
400
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
640
Navigating Team Friction
lara
192
16k
Claude Code どこまでも/ Claude Code Everywhere
nwiizo
68
59k
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
330
Highjacked: Video Game Concept Design
rkendrick25
PRO
1
480
Effective software design: The role of men in debugging patriarchy in IT @ Voxxed Days AMS
baasie
1
570
Automating Front-end Workflow
addyosmani
1369
210k
[SF Ruby Conf 2025] Rails X
palkan
3
1.5k
BBQ
matthewcrist
90
10k
Building an army of robots
kneath
307
47k
Optimising Largest Contentful Paint
csswizardry
37
4k
Transcript
WebView ͔Β σʔλΛεΫϨΠϐϯά͢Δ Tatsunori Nakano
ࣗݾհ • Tatsunori Nakano • ࡳຈग़ → ౦ژ • ฏͷ
Web ܥͷձࣾͰ React Λॻ͍͍ͯ·͢ɻ • ࠓ͔Β React Native ৮Γ࢝ΊɺिʹΞϓϦΛ࡞ͬͨΓ͍ͯ͠·͢ɻ
͢͜ͱ • ࡞ͨ͠ΞϓϦͷհ • WebView ͱΞϓϦͷσʔλͷΓऔΓʹ͍ͭͯ
ϋΠϥΠτɾϚωʔδϟʔ ɾKindle ͷϋΠϥΠτΛΠϯϙʔτ ɾෳͷຊͷϋΠϥΠτΛΞϓϦͰҰݩཧ ɾϥϯμϜදࣔϦϚΠϯυػೳͰهԱΛఆண
CSV ΤΫεϙʔτ PDF ΤΫεϙʔτ ݩʑ Kindle ʹΤΫεϙʔτػೳ͕උΘ͍ͬͯΔ ͕ɺΞϓϦͰѻ͍ʹ͍͘😥
Kindle ͷϋΠϥΠτϒϥβ͔ΒΞΫηεͰ͖Δ WebView Ͱ։͍ͯϋΠϥΠτΛऔಘ͢Δ💡
WebView ͰʮϝϞͱϋΠϥΠτʯΛ։͘ ຊͷҰཡใΛऔಘͯ͠දࣔ͢Δ બͨ͠ຊͷϋΠϥΠτΛऔಘ͢Δ
document.querySelectorAll("a.a-text-normal").forEach((a,index) => console.log(index,a.text)) ※ ຊͷλΠτϧҰཡΛऔಘ
injectJavaScript() • WebView ্Ͱ JavaScript ͷίʔυΛ࣮ߦ͢Δ • Ҿʹ࣮ߦ͍ͨ͠ JavaScript ͷίʔυΛ
string Ͱ͢ • WebView ʹ ref Λઃఆ͠ɺͦͷ ref ʹର࣮ͯ͠ߦ͢Δ // ྫɿഎܠΛ੨͘͢Δ webviewRef.current.injectJavaScript("document.body.style.backgroundColor = 'blue'")
window.ReactNativeWebView.postMessage() • WebView ͔ΒΞϓϦଆϝοηʔδΛ͛Δ • Ҿʹ͍͛ͨϝοηʔδΛ string Ͱ͢ // ྫɿΞϓϦଆʹ
"Hello" ͱ͍͏จࣈྻΛ͛Δ window.ReactNativeWebView.postMessage("Hello!")
onMessage • WebView ͷϓϩύςΟ • postMessage() ʹΑͬͯඈ͞ΕͨϝοηʔδΛड͚औΔ // ྫɿඈΜͰ͖ͨϝοηʔδΛ alert
Ͱදࣔ͢Δ return ( <View style={{ flex: 1 }}> <WebView source={{ html }} onMessage={(event) => { alert(event.nativeEvent.data); }} /> </View> );
ɾinjectJavaScript() ɾwindow.ReactNativeWebView.postMessage() ɾonMessage ͜ͷ 3 ͭΛΈ߹Θͤͯ WebView ͔ΒใΛऔಘ͠·͢
document.querySelectorAll("a.a-text-normal").forEach((a,index) => console.log(index,a.text)) ※ ຊͷλΠτϧҰཡΛऔಘ
document.querySelectorAll("a.a-text-normal").forEach((a,index) => console.log(index,a.text)) document.querySelectorAll("a.a-text-normal").forEach((a,index) => window.ReactNativeWebView.postMessage([index,a.text])) const getTitleList = 'document.querySelectorAll("a.a-text-normal").forEach((a,index)
=> window.ReactNativeWebView.postMessage([index,a.text]))' // WebView ͷ ref const webviewRef = useRef<WebView>(null!); // JavaScript ࣮ߦ༻ͷؔ const runJS = (code: string) => { webviewRef.current.injectJavaScript(code); }; return ( <SafeAreaView> <WebView source={{ uri: 'https://read.amazon.co.jp/notebook' }} onNavigationStateChange={() => runJS(getTitleList)} onMessage={(event) => { console.log(event.nativeEvent.data) }} ref={webviewRef} /> </SafeAreaView> );
string Λ Ճͯ͠ը໘ʹඳը͢Δ
// WebView Ͱ࣮ߦͤ͞Δ JavaScript ͷίʔυ const codes = { getTitleList:
'document.querySelectorAll("a.a-text-normal").forEach((a,i) => window.ReactNativeWebView.postMessage([i,a.text]))', getAsinList: 'document.querySelectorAll("#kp-notebook-library>div").forEach((div, i)=> window.ReactNativeWebView.postMessage([i,div.id,"asin"]))', click: 'document.querySelectorAll("a.a-text-normal")[number].click()', loadingCheck: 'window.ReactNativeWebView.postMessage(document.querySelector("div#kp-notebook-spinner.kp-spinner").style.display)', getTitle: 'window.ReactNativeWebView.postMessage(document.querySelector("#annotation-scroller div.a-column.a-span-last > h3").textContent)', getImg: 'window.ReactNativeWebView.postMessage(document.querySelector("#annotation-scroller div.a-column.a-span3 > a img").src)', getLocation:'window.ReactNativeWebView.postMessage([[...[...document.querySelectorAll("#kp-notebook-annotations > div > div > div > input")].filter(input => {return input.parentNode.nextElementSibling.contains(input.parentNode.nextElementSibling.querySelector(".a-alert-inline")) === false})].map(input => input.value)])', getText: 'window.ReactNativeWebView.postMessage([...document.querySelectorAll("#highlight")].map(span => span.textContent + "#*#--*#*"))', }; ຊͷλΠτϧऔಘ༻ɺΫϦοΫ༻ɺϋΠϥΠτऔಘ༻ͳͲͷ JavaScript ͷίʔυΛ·ͱΊͨ Object Λ༻ҙ͓͖ͯ͠ɺ ͷૢ࡞ʹԠͯ͡ injectJavaScript() Ͱ࣮ߦ
·ͱΊ • injectJavaScript() • window.ReactNativeWebView.postMessage() • onMessage ͜ͷ 3ͭΛΈ߹Θͤͯ WebView
͔ΒใΛऔಘ͠·͢
͋Γ͕ͱ͏͍͟͝·ͨ͠ @centerfield77