Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
スクレイピングの安定運用のために苦労したところ、工夫したところ
Search
shida
August 21, 2016
Programming
2.2k
4
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
スクレイピングの安定運用のために苦労したところ、工夫したところ
Bayside Tech Bridge 2 016.08.21
クローリングのスペシャリストが語る、クローラー運用の裏側!
shida
August 21, 2016
More Decks by shida
See All by shida
受託開発で ビジネスづくりを楽しむ
shida
0
2.6k
受託アジャイルでの契約書作り請求や、外注パートナーへの支払いスキームまで
shida
0
960
DevLOVEリンスタカフェ vol.7
shida
1
220
DevLOVE リンスタカフェ vol2 成長を促すKPIが見つからん
shida
0
150
現場の開発者でもできるユーザー中心かつ 仮説検証型の企画アプローチ
shida
0
3k
ユーザーが「それいいね!」と言うまで
shida
0
3.4k
ハイブリッドアプリの 受け入れテスト自動化
shida
0
260
SkypインタビューとKA法による分析
shida
4
1k
CucumberによるHTML5アプリの 受け入れテスト自動化
shida
1
530
Other Decks in Programming
See All in Programming
The NotImplementedError Problem in Ruby
koic
1
920
Signal Forms: Details & Live Coding @enterJS 2026 in Mannheim
manfredsteyer
PRO
0
190
Lessons from Spec-Driven Development
simas
PRO
0
220
エンジニア向け会社紹介/Findy Company Profile
findyinc
6
350k
Javaの型とAI時代に型が大事な理由 / java types and type in AI era
kishida
2
150
作って学ぶ、 JSX (TSX) ランタイムの基本
syumai
7
1.7k
エージェンティックRAGにAWSで入門しよう!
har1101
9
1.7k
代数的データ型って何が嬉しいの? #frontend_phpcon_do
kajitack
8
3.8k
Hunting Vulnerabilities in Symfony with LLMs
vinceamstoutz
0
560
Vite+ Unified Toolchain for the Web
naokihaba
0
340
AI 輔助遺留系統現代化的經驗分享
jame2408
1
990
Contextとはなにか
chiroruxx
1
370
Featured
See All Featured
Odyssey Design
rkendrick25
PRO
2
710
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
310
How to make the Groovebox
asonas
2
2.2k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.8k
How to train your dragon (web standard)
notwaldorf
97
6.7k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
38
2.9k
Building Flexible Design Systems
yeseniaperezcruz
330
40k
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
2
330
Game over? The fight for quality and originality in the time of robots
wayneb77
1
200
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
370
Conquering PDFs: document understanding beyond plain text
inesmontani
PRO
4
2.8k
Hiding What from Whom? A Critical Review of the History of Programming languages for Music
tomoyanonymous
2
870
Transcript
εΫϨΠϐϯάͷ҆ఆӡ༻ͷͨΊʹ ۤ࿑ͨ͠ͱ͜Ζɺͨ͠ͱ͜Ζ #BZTJEF5FDI#SJEHF ΫϩʔϦϯάͷεϖγϟϦετ͕ޠΔɺΫϩʔϥʔӡ༻ͷཪଆʂ ג ϏʔɾΞδϟΠϧ݉ɺδʔΫϥυ ג ࢤా༟थ
גࣜձࣾϏʔɾΞδϟΠϧ(΄΅ϑϦʔϥϯεɺ2012ΑΓ) δʔΫϥυגࣜձࣾ औక ݉ ϑϦʔϥϯε͕ू·ͬͯɺνʔϜ։ൃ डୗ։ൃ(8ׂ)ɺࣗࣾαʔϏε։ൃ(2ׂ) ϦʔϯɾελʔτΞοϓɺΞδϟΠϧ(اըɺ։ൃɺӡ༻) RailsɺSwiftɺ Java for
Android ։ൃҊ݅ɺҰॹʹಇ͖͍ͨϑϦʔϥϯεͷํ େืूத!!! ຊൃදͰɺࣗࣾαʔϏεͷ҆ఆӡ༻ͷͨΊʹۤ ࿑ͨ͠ͱ͜Ζɺͨ͠ͱ͜ΖΛ͝հ
ۤ࿑ͨ͠ͱ͜Ζ
+BWB4DSJQU͕࣮ߦ͞Εͳ͍ͱ ใ͕ͱΕͳ͍ αΠτଆͰ+4ͰಈతʹϖʔδΛߏஙͯ͠ΔͨΊ
1PSUFSHFJTUͰεΫϨΠϐϯά Ruby Capybara Poltergeist PhantomJS ରαΠτ Safariͱಉ͡JSΤϯδϯ͕ಈ͘ Headlessϒϥβ CapybaraͷPhantomJSυϥΠό ड͚ೖΕςετ༻ςεςΟϯά
ϑϨʔϜϫʔΫ
require 'capybara/poltergeist' Capybara.register_driver :poltergeist do |app| Capybara::Poltergeist::Driver.new(app) end Capybara.default_driver =
:poltergeist agent = Capybara.current_session agent.visit('URL') number = agent.find('CSSηϨΫλ').text.to_i 1PSUFSHFJTUͰεΫϨΠϐϯά
Ϣʔβʔೝূ͠ͳ͍ͱ ใ͕ͱΕͳ͍
agent.visit login_url agent.find('input[name="email"]').set(email) agent.find('input[name="pasword"]').set(password) agent.find('#login-btn').trigger('click') agent.visit account_url ೝূ͔ͯ͠Βର63-ʹΞΫηε
ຖճೝূ͕͠͠ॏ͍
def save_cookie(agent, user) cookies_str = Base64.encode64( Marshal.dump( agent.driver.browser.cookies)) user.update_attributes(cookies: cookies_str)
end def load_cookie(agent, user) cookies = Marshal.load( Base64.decode64(user.cookies)) cookies.values.each do |cookie| cookie_hash = JSON.parse(cookie.to_json) ["attributes"] agent.driver.browser.set_cookie(cookie_hash) end end $PPLJFʹΑΔೝূ
DPPLJFͷ༗ޮظݶ͕ Ε͍ͯΔ͕࣌͋Δ
DPPLJF͕Ε͍ͯͨΒSFUSZ scrape(need_login: true) do agent.visit('URL') agent.find('CSSηϨΫλ').text.to_i end # εΫϨΠϐϯά͢ΔՕॴ༻ڞ௨ϝιου def
scrape need_login: false begin yield rescue => e if need_login && ! login? login retry end end end
ԿೝূτϥΠ͍ͯ͠Δͱ ϩοΫ͞ΕΔ
agent.driver.headers = { "User-Agent" => "Mozilla/5.0 (Macintosh; Intel Mac OS
X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36 #{Time.now.to_f.to_s}" } 6TFS"HFOUΛͪΐ͍ͪΐ͍ม͑Δ
ΞΫηε͠·͍ͬͯ͘Δͱ ϒϩοΫ͞ΕΔ
Proxy1 (AWS) ΞϓϦ αʔό ର αΠτ ΞΫηεݩΛͪΐ͍ͪΐ͍ม͑Δ Proxy1 (AWS) ᶃϒϩοΫ
ᶄ৽͘͠ىಈ
)5.-ߏ͕มΘΓ εΫϨΠϐϯάࣦഊ ͱ͔
"#ςετͯ͠ΔΒ͘͠ ΞΧϯτຖͰ)5.-͕ҧ͏
Ͱ͖Δ͚ͩදࣔܥ͔ΒεΫϨΠϐϯά͠ͳ͍ ॓ധਓ 9໊ ใදࣔը໘ ॓ധਓ 9 ϑΥʔϜը໘ ໊ ϑΥʔϜ෦ͷϚʔΫΞοϓαʔόʔαΠυͷϓϩάϥϜͱ࿈ ܞ͍ͯ͠ΔͷͰมߋ͕ൃੜ͠ʹ͍͘
<div data-bootstrap-data="{a: 'b', ... }" /> JavaScriptଆʹJSONจࣈྻͰใΛ͍ͯ͠Δͱ͜Ζͱ͔ม ߋ͕ൃੜ͠ʹ͍͘ http://example.com/users/12345678 URLมߋ͕ൃੜ͠ʹ͍͘
αΠτ͕ॏͯ͘ ͨ·ʹλΠϜΞτͨ͠Γ མͪͨΓ͢Δ
ϩʔυͪɺදࣔ࣌ؒΛԆ͢ Capybara.register_driver :poltergeist do |app| Capybara::Poltergeist::Driver.new(app, :timeout => 60) end
Capybara.default_driver = :poltergeist Capybara.default_max_wait_time = 30 agent = Capybara.current_session # ࠷େ60ඵͬͯ͘ΕΔ agent.visit('URL') # ࠷େ30ඵJavaScriptͷඇಉظߋ৽ͳͲͷऴྃΛͬͯ͘ΕΔ number = agent.find('CSSηϨΫλ').text.to_i
εΫϨΠϐϯάࣦഊ ඞ͓͖ͣΔ )5.-ߏͷมԽ ӬଓతΤϥʔ ଓΤϥʔ Ұ࣌తͳΤϥʔ
ϢχοτςετΛఆظతʹࣗಈ࣮ߦ project='ϦϙδτϦ໊' branch='master' api_token='APIτʔΫϯ' url=https://circleci.com/api/v1/project/${project}/ tree/${branch}?circle-token=${api_token} curl \ --header "Accept:
application/json" \ --header "Content-Type: application/json" \ --request POST ${url} CircleCIͷϏϧυΛAPIΛͬͯcron͔Βఆظ࣮ߦ ͚ͨ͜ΒCircleCI͕Slackʹ௨ͯ͘͠ΕΔ
4JEFLJRͷར༻ # 1000ళฮ͋ͬͨͱͯ͠ shops.each do |shop| # ͠10ళฮͰΤϥʔͰॲཧ͕ͱ·ͬͯ͠·ͬͨΒ # 990ళฮ͕ະॲཧʹͳͬͯ͠·͏
shop.scrape end Ұ࣌తͳଓΤϥʔ ಛఆͷshopʹ͚ͩൃੜ͢Δఆ֎ͷΤϥʔ
4JEFLJRͷར༻ ಛఆͷshopͰམͪͯɺଞͷshopͷॲཧݺΕΔ
4JEFLJRͷͦͷଞར ಛఆͷshopͰམͪͯɺଞͷshopͷॲཧݺΕΔ εϨουىಈىಈ·Ͱͷͪ࣌ؒΛ੍ޚ͠ɺରαΠτʹ ෛՙΛ͔͚ա͗ͳ͍ མͪͨ࣌ʹslackʹ௨ͯ͘͠ΕΔ མͪͨεϨουΛϦτϥΠͯ͘͠ΕΔ ࠷େϦτϥΠճࢦఆՄೳ దʹϦτϥΠִؒΛ͛ͳ͕Β(15, 16, 31,
96, 271, ... ) ϦτϥΠ࣌ͷslack௨ΛؒҾ͍ͨΓͰ͖Δ ฒྻॲཧαʔόʔͷεέʔϧΞτͰύϑΥʔϚϯεΞοϓ
·ͱΊ વͰ͖Δ͚ͩεΫϨΠϐϯάΤϥʔɺଓΤϥʔΛճආ͢ ΔΑ͏ʹྗ ͦΕͰશʹճආͰ͖ͳ͍ εΫϨΠϐϯάΤϥʔΛ͔ʹݕ͢ΔΈΛ༻ҙ Ұ࣌తʹଓΤϥʔෆଌͷΤϥʔ͕ൃੜͨ͠߹ɺ֘ॲ ཧҟৗऴྃͭͭ͠ɺ༧ఆ͍ͯͨ͠όονॲཧܧଓ Ұ࣌తΤϥʔ(ଓΤϥʔɺcookie༗ޮظݶΕ)ϦτϥΠ εΫϨΠϐϯάͷӡ༻ʹ͔͔Δ࣌ؒίετΛ͋Β͔͡ΊϓϩδΣ Ϋτॳظʹؔऀʹཧղͯ͠Β͏ඞཁ͕͋Δ(߹ʹΑͬͯ
Ϣʔβʔʹ)
࠷ޙʹએϦϯελΧϑΣ ΦϯϥΠϯ ϦʔϯɾελʔτΞοϓ(ͦͷଞྨࣅ)ख๏Λϕʔεʹͨ͠αʔ Ϗεاըɾ։ൃͷ࣮ફऀͷͨΊͷίϛϡχςΟ աڈ8ճͷΦϑϥΠϯษڧձΛ࣮ࢪ ΠϯλϏϡʔͷํɺϢʔβʔςετͷํɺMVPͷܾΊ ํɺࣾελʔτΞοϓͷۤ࿑ɺͳͲͳͲ ͦΕͷΦϯϥΠϯ൛ ຖिਫ༵ 21:30
GoogleϋϯάΞτʹͯ ݱࡏϝϯόʔ 4໊ ࢀՃऀ֤͕ࣗؔΘ͍ͬͯΔαʔϏεͷݱঢ়ใࠂɺ໘͍ͯ͠Δ ՝ͷڞ༗ͱ૬ޓΞυόΠεͱ͔ɺϦϯελܥͷຊͷಡॻձ ͝ڵຯ͋ΕΛ͔͚͍ͯͩ͘͞!