$30 off During Our Annual Pro Sale. View Details »

WebView からデータをスクレイピングする

WebView からデータをスクレイピングする

React Native 祭での LT に使った資料です。
https://reactnative-matsuri.com/ja

Tatsunori Nakano

October 02, 2021
Tweet

Other Decks in Programming

Transcript

  1. ࣗݾ঺հ • Tatsunori Nakano • ࡳຈग़਎ → ౦ژ • ฏ೔͸౎಺ͷ

    Web ܥͷձࣾͰ React Λॻ͍͍ͯ·͢ɻ • ࠓ೥͔Β React Native ৮Γ࢝Ίɺि຤ʹΞϓϦΛ࡞ͬͨΓ͍ͯ͠·͢ɻ
  2. injectJavaScript() • WebView ্Ͱ JavaScript ͷίʔυΛ࣮ߦ͢Δ • Ҿ਺ʹ࣮ߦ͍ͨ͠ JavaScript ͷίʔυΛ

    string Ͱ౉͢ • WebView ʹ ref Λઃఆ͠ɺͦͷ ref ʹର࣮ͯ͠ߦ͢Δ // ྫɿഎܠΛ੨͘͢Δ webviewRef.current.injectJavaScript("document.body.style.backgroundColor = 'blue'")
  3. onMessage • WebView ͷϓϩύςΟ • postMessage() ʹΑͬͯඈ͹͞ΕͨϝοηʔδΛड͚औΔ // ྫɿඈΜͰ͖ͨϝοηʔδΛ alert

    Ͱදࣔ͢Δ return ( <View style={{ flex: 1 }}> <WebView source={{ html }} onMessage={(event) => { alert(event.nativeEvent.data); }} /> </View> );
  4. 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> );
  5. // 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() Ͱ࣮ߦ