Slide 1

Slide 1 text

LINEͰഅ݊Λߪೖ͢Δ ؔ੢NodeֶԂ #3 2018/08/03 େౡ ޫو@sbntaminif

Slide 2

Slide 2 text

ࣗݾ঺հ • ΢ΣϒϦΦגࣜձࣾWEBΤϯδχΞ + ϓϩμΫτ Ϛωʔδϟʔɹ࠷ۙ͸ϚωʔδϟʔଟΊ • ҰԠओ࠵΍ͬͯ·͕͢ࢲͩͬͯ஻Γ͍ͨ • ීஈ͸ژ౎Ͱಇ͍͍ͯ·͢ • ࠓ೔͜Εͷ࿩Ұ੾͠·ͤΜ↘

Slide 3

Slide 3 text

Q. അ݊͸ Ͳ͏΍ͬͯ ߪೖ͢Δʁ A. ωοτߪೖ αʔϏεΛ ࢖༻͠·͢

Slide 4

Slide 4 text

അ݊ωοτߪೖαʔϏε • JRA I-PATͱݴ͍·͢ɻ • ଈPAT, A-PAT΋͋Γ·͢ • ਃ͠ࠐΈ੍ͷձһઐ༻αΠτ • Webݶఆ • ΋ͪΖΜ20ࡀҎ্ʢֶੜͰ΋OKʣ

Slide 5

Slide 5 text

ϑΝϛίϯ + ి࿩ઢͰ΋ ߪೖͰ͖ͨ ※ݱࡏ͸αʔϏεऴྃɻεʔϑΝϛɺυϦʔϜΩϟετͰ΋ങ͑·ͨ͠ https://www.youtube.com/watch?v=ks0JeyhZsR4

Slide 6

Slide 6 text

LINEͰഅ݊ΛങͬͯΈ͍ͨ εϚʔτϑΥϯશ੝ظ ࣗ෼ͷ޷͖ͳUIͰ അ݊Λങ͍͍ͨ

Slide 7

Slide 7 text

͍ͣΕ௕೥ͷເ അ݊Λߪೖ͢ΔΞϓϦΛ ࡞Γ͍ͨ ※ͨͩ͠API͸ఏڙ͞Εͳ͍

Slide 8

Slide 8 text

API͕ͳ͍ͳΒ ࡞Ε͹ྑ͍

Slide 9

Slide 9 text

I-PAT https://www.ipat.jra.go.jp/

Slide 10

Slide 10 text

ΦϯϥΠϯߪೖ͸Ͱ͖Δ WebαΠτΛ AutomationԽ࣮ͯ͠ݱ Ͳ͏΍Δ͔➡

Slide 11

Slide 11 text

Headless Chrome https://developers.google.com/web/updates/2017/04/headless-chrome?hl=en

Slide 12

Slide 12 text

Headless Chromeͱ͸ • ChromeΛϔουϨεͰಈ࡞͢Δ • ϔουϨε = UIͳ͠Ͱ࣮ߦ • Chrome59͕Πϯετʔϧ͞Ε͍ͯΕ͹࢖༻Մ ೳʢWindows͸61ʣ • Chromeͷػೳ͕શͯ࢖͑Δ

Slide 13

Slide 13 text

ίϚϯυ͔Β ChromeΛUIͳ͠Ͱ ࣮ߦͰ͖Δ

Slide 14

Slide 14 text

Ͱ΋CLIͰ શͯͷૢ࡞Λॻ͘ͷ͸ਏ͍

Slide 15

Slide 15 text

ChromeΛ ૢ࡞͢ΔͨΊʹ։ൃ͞Εͨ ϥΠϒϥϦ

Slide 16

Slide 16 text

puppeteer https://github.com/GoogleChrome/puppeteer

Slide 17

Slide 17 text

puppeteerͱ͸ • NodeJSͰHeadless ChromeΛ
 ૢ࡞͢ΔϥΠϒϥϦ • Chrome DevToolsͷ্͔Βૢ࡞͢ΔAPI • GoogleChromeνʔϜ͕࣮૷ • ʮύϖςΟΞʯͱൃԻ

Slide 18

Slide 18 text

ಈ࡞ϨΠϠʔ

Slide 19

Slide 19 text

ChromeΛࣗಈͰಈ͔ͯ͠ അ݊ߪೖ·Ͱ ͨͲΓͭ͘

Slide 20

Slide 20 text

࣮૷͢Δ const puppeteer = require(‘puppeteer'); (async () => { const browser = await puppeteer.launch({headless: true}); const page = await browser.newPage(); await page.setViewport({width: 640, height: 460}); await page.goto(‘https://www.ipat.jra.go.jp/’); //////////////////////////////////////////// })(); $ISPNFΛىಈ ৽͍͠λϒΛ։͘ ΢Οϯυ΢αΠζΛܾఆ 63-Λࢦఆͯ͠ભҠ

Slide 21

Slide 21 text

࣮૷͢Δ

Slide 22

Slide 22 text

࣮૷͢Δ //////////////////////////////////////////// await page.type(‘[name=“inetid”]’,’********’); await page.click(".button a"); await page.waitForNavigation(); //////////////////////////////////////////// *%Λೖྗ ϩάΠϯϘλϯΛΫϦοΫ ભҠΛ଴ͭ

Slide 23

Slide 23 text

࣮૷͢Δ

Slide 24

Slide 24 text

͜Μͳײ͡Ͱ Ұͭͣͭૢ࡞ͯ͠ ໨త·Ͱୡ੒͢Δ

Slide 25

Slide 25 text

࡞ͬͨ΋ͷ͕ͪ͜Β https://github.com/taminif/bettingInTheIPAT

Slide 26

Slide 26 text

await஍ࠈ

Slide 27

Slide 27 text

Ͳ͏ͯ͠΋ϦΫΤετΛ ଴ͭඞཁ͕͋ΔͷͰ ݁ՌΛ଴ͨ͟ΔΛಘͳ͍

Slide 28

Slide 28 text

ίϚϯυΛୟ͚͹ അ͕݊ങ͑ΔAPI͕Ͱ͖ͨ

Slide 29

Slide 29 text

API͕Ͱ͖ͨ .BD؀ڥͰ ಈ࡞͢Δ"1* ίϚϯυݺͼग़͠ ͜Ε͚ͩͰ͸͜ͷMacͰ͔͠࢖͑ͳ͍

Slide 30

Slide 30 text

͜ͷAPIΛαʔόʔͰ ݺͼग़ͤΔΑ͏ʹ͍ͨ͠

Slide 31

Slide 31 text

APIΛͲ͜Ͱಈ͔͔͢ • Headless Chrome͸Ͳͷ؀ڥͰ΋ಈ͘ • puppeteer͸Node v6.4.0͔Βಈ͘ • ͭ·Γαʔόʔߏஙͯ͠؀ڥΛ༻ҙ͢Ε͹ಈ͘
 -> Ͱ΋ΊΜͲ͍͘͞ • AWS Lambda΍GCPͰ΋ಈ͘ ->AWS LambdaͰಈ͔ͯ͠APIʹ͢Δ

Slide 32

Slide 32 text

LambdaͰಈ͔ͨ͠ -BNCEBͰ ಈ࡞͢Δ"1* -BNCEBݺͼग़͠ +40/ \ QMBDFbവؗ  SBDF/Pb  SBDFS/P``  BNPVOU  ^ ʢิ଍ʣ "84-BNCEBͷ࠷େλΠϜΞ΢τઃఆ͸ ඵ෼ ભҠ͕ଟ͗͢Δͱ͕࣌ؒ଍Γͳ͍ Մೳੑ͸͋Δ

Slide 33

Slide 33 text

·ͩAWSͷ ؅ཧը໘͔Β͔͠࢖͑ͳ͍ ͜ͷAPIΛͲ͔͜ΒͰ΋ ݺͼग़ͤΔΑ͏ʹ͍ͨ͠

Slide 34

Slide 34 text

API Gateway͔Βݺͼग़͢ -BNCEBͰ ಈ࡞͢Δ"1* )5513FRVFTUΛ ड͚෇͚Δ )5514௨৴ +40/ \ QMBDFbവؗ  SBDF/Pb  SBDFS/P``  BNPVOU  ^

Slide 35

Slide 35 text

͔͠͠ɺ্ख͍͜ͱ ಈ͍ͯ͘Εͳ͍ API GatewayͷλΠϜΞ΢τʹ Ҿ͔͔ͬΔ

Slide 36

Slide 36 text

API GatewayͷλΠϜΞ΢τ͸ ໿2෼

Slide 37

Slide 37 text

Lambda͔ΒLambdaΛίʔϧ ඇಉظͰݺͼग़͢ )5514௨৴ +40/ \ QMBDFbവؗ  SBDF/Pb  SBDFS/P``  BNPVOU  ^ ݺͼग़ͨ͠Β ऴΘΓ

Slide 38

Slide 38 text

Ͳ͔͜ΒͰ΋APIΛ ݺͼग़ͤΔΑ͏ʹͳͬͨ

Slide 39

Slide 39 text

ωοτϫʔΫΛܦ༝͢Ε͹ അ݊Λങ͑ΔΑ͏ʹͳͬͨ

Slide 40

Slide 40 text

ωοτϫʔΫؒͰ LINE͕APIΛݺͼग़ͤ͹ അ͕݊ങ͑ΔͷͰ͸

Slide 41

Slide 41 text

LINE Messaging API https://developers.line.me/ja/services/messaging-api/

Slide 42

Slide 42 text

LINE Messaging APIͱ͸ • LINE DeveloperͷҰػೳ • ʮ͋ͳͨͷαʔϏεͱLINEϢʔβʔͷ
 ɹ૒ํ޲ίϛϡχέʔγϣϯΛՄೳʹ͢Δʯ • LINEͷ༑ୡ௥Ճ΍ϝοηʔδૹ৴ͳͲͷΠϕϯτ ΛτϦΨʔʹWebhookΛ࣮ߦ͢Δ

Slide 43

Slide 43 text

LINEʹૹ৴ͨ͠஋Λ API Gateway͔ΒLambdaʹ ౉͢

Slide 44

Slide 44 text

LINE BotͰഅ݊Λߪೖ͢Δ ʢਖ਼֬ʹ͸͜͜ʹ-*/&͞Μͷ αʔόʔ͕͋Δʣ ϝοηʔδ  വؗ    -*/&ʹೖྗ͞Εͨ ৘ใΛड෇ -BNCEB༻ʹՃ޻ +40/ \ QMBDFbവؗ  SBDF/Pb  SBDFS/P``  BNPVOU  ^

Slide 45

Slide 45 text

ങ͑ΔΑ͏ʹ͸ͳ͕ͬͨ Ϩεϙϯε͕ͳ͍ LINE Messaging APIͰ ϦΫΤετΛड͚ͨޙʹ Ԡ౴ϝοηʔδΛฦ͢

Slide 46

Slide 46 text

Ԡ౴ϝοηʔδػೳ • Ϣʔβʔ͔ΒͷϝοηʔδҰ݅ʹରͯ͠
 Ұճ͚ͩฦ٫Ͱ͖Δ • ϝοηʔδʹ͍͍ͭͯΔϢʔβʔIDΛ࢖ͬͯ
 Ԡ౴ϝοηʔδΛૹ৴ • ࣗ༝ʹϢʔβʔʹૹ৴͢ΔPush API͸༗ྉɾɾ
 ˢ͜Ε͕͋Ε͹ߪೖ൑ఆ͕ฦͤΔɾɾ

Slide 47

Slide 47 text

Ԡ౴ϝοηʔδΛฦ͢ \ QMBDFbവؗ  SBDF/Pb  SBDFS/P``  BNPVOU  ^ വؗ    ύϥϝʔλʔ͕ਖ਼ৗͳΒ -BNCEBΛݺͼग़ͯ͠ Ԡ౴ϝοηʔδΛૹΔ -BNCEB͔Β-BNCEBΛඇಉظͰ ݺͼग़͍ͯ͠ΔͷͰ੒ޭ͔ͨ͠͸ෆ໌

Slide 48

Slide 48 text

LINEͰഅ݊Λ ങ͑ΔΑ͏ʹͳͬͨ!

Slide 49

Slide 49 text

࣮ફฤ puppeteerͰ ͭ·͍ͮͨ͜ͱ

Slide 50

Slide 50 text

puppeteerͰͭ·͍ͮͨ͜ͱ • ൣғ֎ͷཁૉΫϦοΫ • onclickΠϕϯτ͕ൃՐ͠ͳ͍ • waitForͱwaitForNavigationͱwaitForSelector • ChromeͱpuppeteerͷόʔδϣϯΛ߹ΘͤΔ • (AWS Lambda͸ͱͯ΋ॲཧ͕஗͍)

Slide 51

Slide 51 text

ൣғ֎ͷཁૉΫϦοΫ

Slide 52

Slide 52 text

Headless ChromeͰ͸ ը໘֎ͷཁૉͷΫϦοΫ͕ൃՐ͠ͳ͍ ΢Οϯυ΢αΠζΛ ͜͜·Ͱʹઃఆ ͜ͷϘλϯ͸ ΫϦοΫͰ͖ͳ͍ ϒϥ΢β෯

Slide 53

Slide 53 text

const puppeteer = require(‘puppeteer'); (async () => { const browser = await puppeteer.launch({headless: true}); const page = await browser.newPage(); await page.setViewport({width: 1920, height: 2160}); await page.goto(‘https://www.ipat.jra.go.jp/’); })(); ը໘શ͕ͯ࿮಺ʹ͓͞·ΔΑ͏ͳେ͖͞ ʢղܾࡦʣ ը໘Λେ͖͘͢Δ

Slide 54

Slide 54 text

͜͏͢Ε͹ԡͤΔΑ͏ʹͳͬͨʂ ϒϥ΢β෯ ۭന

Slide 55

Slide 55 text

waitForͱ waitForNavigationͱ waitForSelector

Slide 56

Slide 56 text

ͦΕͧΕͷ࢖͍෼͚ • waitFor
 -> ϛϦඵΛࢦఆɻࢦఆ͚ͨ࣌ؒͩ͠଴ͭ • waitForNavigation
 -> Ҿ਺ͳ͠ɻ • waitForSelector
 -> ηϨΫλͰࢦఆɻཁૉ͕දࣔ͞ΕΔ·Ͱ଴ͭ ->͜ΕΒ͚ͩͰ͸ͳ͍ɻଞʹ΋·ͩ͋Δ

Slide 57

Slide 57 text

࠷ॳͷ͏ͪ͸waitForͰ ϩʔυΛ଴ͭ ׳Εͯ͘Ε͹ ਖ਼͘͠࢖͍෼͚Δͱ ਐΊ΍͍͢

Slide 58

Slide 58 text

·ͩHeadless Chromeͷ ັྗΛ஻ͬͯͳ͍

Slide 59

Slide 59 text

Ξϐʔϧฤ Headless Chrome͸ ૉ੖Β͍͠ϓϩμΫτͰ͋Δʂ

Slide 60

Slide 60 text

·ͣ͸͡Ίʹ Headless ChromeΛ࿩্͢Ͱ ͔ܽͤͳ͍ಈը

Slide 61

Slide 61 text

The power of Headless Chrome https://www.youtube.com/watch?v=lhZOFUY1weo 2018೥ͷGoogle IOͷߨԋ

Slide 62

Slide 62 text

Headless Chromeͱ puppeteerͰग़དྷΔ 10ͷ͜ͱ͕࿩͞Ε͍ͯ·͢ ʢൈਮʣ SSR ABςετ Web Audio ύοΫϚϯ

Slide 63

Slide 63 text

Headless Chrome͸ େ͖ͳՄೳੑΛൿΊ͍ͯΔ

Slide 64

Slide 64 text

ࢲͷߟ͑Δ ࠷΋ັྗతͳٕज़

Slide 65

Slide 65 text

ͲΜͳWebαʔϏεͰ΋ APIԽͰ͖Δ

Slide 66

Slide 66 text

Πϯλʔωοτશ੝ظ ϒϥ΢βΛ࢖Θͳ͍ਓ͸ ΄΅͍ͳ͍Ͱ͢ΑͶ

Slide 67

Slide 67 text

ීஈͷωοταʔϑΟϯΛ ࣗಈԽͰ͖Δ

Slide 68

Slide 68 text

ࣗಈԽͯ͠APIʹ͢Ε͹ ͍ͭͰ΋ݺͼग़ͤΔ

Slide 69

Slide 69 text

APIԽ͓͚ͯ͠͹ ΠϯλʔϑΣʔε͸ ͲΕͰ΋࢖͑Δ ࠓ࿩୊ͷεϚʔτεϐʔΧʔ Ͱ΋OK

Slide 70

Slide 70 text

ԿͰ΋Ͱ͖Δ

Slide 71

Slide 71 text

ເ͕޿͕Γ·ͤΜ͔ʁ

Slide 72

Slide 72 text

⚠8BSOJOH

Slide 73

Slide 73 text

Ԭ࡚ࢢཱதԝਤॻؗࣄ݅ https://ja.wikipedia.org/wiki/Ԭ࡚ࢢཱதԝਤॻؗࣄ݅

Slide 74

Slide 74 text

΍Γ͗͢Δͱॻྨૹݕ·Ͱ ͋Γ·͢ ৗࣝతͳΞΫηεʹ ԡ͑͞·͠ΐ͏

Slide 75

Slide 75 text

͜ͷηογϣϯʹײԽ͞Εͯ ൃੜͨ͠ଛ֐౳ʹ͍ͭͯɺ ੹೚͸ෛ͍݉Ͷ·͢

Slide 76

Slide 76 text

༻๏༻ྔΛकͬͯ ศརʹ࢖͍·͠ΐ͏

Slide 77

Slide 77 text

ͱ͜ΖͰɺࠓ·Ͱͷ εΫϨΠϐϯάπʔϧͰ͸ Ͱ͖ͳ͔ͬͨͷʁ

Slide 78

Slide 78 text

Ͱ͖ͳ͍͜ͱ͸ͳ͍͚ΕͲ ೉͔ͬͨ͠ • ֤ݴޠͷHTTPϦΫΤετͰ͸ϩάΠϯ৘ใΛ
 อ࣋͢Δ͜ͱ͕೉͔ͬͨ͠ • PhantomJS͸webkitϕʔεͰɺSPA΍৽͍͠λϒ Λ։͘Α͏ͳαʔϏεͷରԠ͕Ͱ͖ͳ͔ͬͨ
 (Headless Chrome͕ग़ͨ͜ͱͰαʔϏεऴྃ) • Selenium͸৮ͬͯͳ͍͚ͲɺAPIԽ͸೉͍͠ʁ

Slide 79

Slide 79 text

Headless Chrome͸ ChromeΛ࢖͍ͬͯΔ Α͏ͳ΋ͷͳͷͰ ΄ͱΜͲͷ͜ͱΛָʹରԠͰ͖Δ

Slide 80

Slide 80 text

࠷ߴ͡Όͳ͍Ͱ͔͢ʁ

Slide 81

Slide 81 text

͜ͷಈըͷதͰ ڧ͘࿩͞Ε͍ͯΔ͜ͱ https://www.youtube.com/watch?v=lhZOFUY1weo

Slide 82

Slide 82 text

ʮ͜ͷ࿩͸ςετࣗಈԽͷ ࿩Ͱ͸͋Γ·ͤΜʯ ʮࣗಈԽ͢Δ͜ͱ͕Ͱ͖Δʯ ʮࣗಈԽ͢ΔπʔϧͰ͋Δʯ

Slide 83

Slide 83 text

ීஈͷ࡞ۀΛࣗಈԽ͢Δ ͜Εͦ͜ΤϯδχΞϦϯά

Slide 84

Slide 84 text

΍ͬͯΈͨ͘ͳΓ·ͤΜ͔ʁ

Slide 85

Slide 85 text

ࣗಈԽ Έͳ͞Μͥͻ ΍ͬͯΈ·͠ΐ͏ʂ

Slide 86

Slide 86 text

͋Γ͕ͱ͏͍͟͝·ͨ͠