Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Crawleando sites com NodeJS

Crawleando sites com NodeJS

Aprenda na prática a usar os recursos do NodeJS para crawlear sites. Um exemplo prático de crawler de sites de receitas vai ser exposto e o código vai estar disponível no github.

https://github.com/allisson/jsday-campina-grande-2016

13991d197c3eb0f71b802337d5eb2719?s=128

Allisson Azevedo

April 22, 2016
Tweet

Transcript

  1. 1 CRAWLEANDO SITES COM NODEJS JSDAY CAMPINA GRANDE 2016 Allisson

    Azevedo
  2. 2 ALLISSON AZEVEDO allissonazevedo.com youtube.com/user/allissonazevedo github.com/allisson twitter.com/allisson allisson.github.io/slides/ allisson@gmail.com

  3. 3 OBJETIVO Crawlear o Obter as receitas com imagem Indexar

    no Elasticsearch Exibir os resultados com o ExpressJS http://www.tudogostoso.com.br
  4. 4 WEB CRAWLER / ROBOT / SPIDER Um programa que

    navega por toda a rede de maneira automática Googlebot, BingBot, Yahoo! Slurp, Baiduspider Opção quando não houver acesso aos dados via Web API
  5. 5 FUNCIONAMENTO 1. Carrega url 2. Parser do conteúdo 3.

    Carrega novas urls a partir dos links da atual
  6. 6 FERRAMENTAS npm install request npm install cheerio npm install

    simplecrawler
  7. 7 SPEAKERS DO JSDAY ' u s e s t

    r i c t ' ; c o n s t r e q u e s t = r e q u i r e ( ' r e q u e s t ' ) ; c o n s t c h e e r i o = r e q u i r e ( ' c h e e r i o ' ) ; r e q u e s t ( ' h t t p : / / j s d a y . c o m . b r / s p e a k e r s / ' , ( e r r o r , r e s p o n s e , b o d y ) = > { l e t $ = c h e e r i o . l o a d ( b o d y ) ; l e t s p e a k e r s = [ ] ; $ ( ' . p e o p l e - m o d a l ' ) . e a c h ( ( i , e l e m e n t ) = > { l e t s p e a k e r = { } ; s p e a k e r . t i t l e = $ ( e l e m e n t ) . f i n d ( ' h 4 ' ) . t e x t ( ) ; s p e a k e r . d e s c r i p t i o n = $ ( e l e m e n t ) . f i n d ( ' . t h e m e - d e s c r i p t i o n ' ) . t e x t ( ) ; s p e a k e r . n a m e = $ ( e l e m e n t ) . f i n d ( ' . n a m e ' ) . c o n t e n t s ( ) [ 0 ] . d a t a . t r i m ( ) ; s p e a k e r . a b o u t = $ ( e l e m e n t ) . f i n d ( ' . a b o u t ' ) . t e x t ( ) ; s p e a k e r . i m a g e = $ ( e l e m e n t ) . f i n d ( ' . p e o p l e - i m g ' ) . c s s ( ' b a c k g r o u n d - i m a g e ' ) . r e p l a c s p e a k e r s . p u s h ( s p e a k e r ) ; } ) ; c o n s o l e . l o g ( J S O N . s t r i n g i f y ( s p e a k e r s , n u l l , 2 ) ) ; } ) ;
  8. 8 PROGRAMAÇÃO DO JSDAY ' u s e s t

    r i c t ' ; c o n s t r e q u e s t = r e q u i r e ( ' r e q u e s t ' ) ; c o n s t c h e e r i o = r e q u i r e ( ' c h e e r i o ' ) ; r e q u e s t ( ' h t t p : / / j s d a y . c o m . b r / s c h e d u l e / ' , ( e r r o r , r e s p o n s e , b o d y ) = > { l e t $ = c h e e r i o . l o a d ( b o d y ) ; l e t s u b E v e n t s = [ ] ; $ ( ' . t i m e s l o t [ i t e m t y p e = " h t t p : / / s c h e m a . o r g / s u b E v e n t " ] ' ) . e a c h ( ( i , e l e m e n t ) = > { l e t e v e n t = { } ; e v e n t . t i t l e = $ ( e l e m e n t ) . f i n d ( ' . s l o t - t i t l e ' ) . t e x t ( ) ; e v e n t . t i m e = $ ( e l e m e n t ) . f i n d ( ' . s t a r t - t i m e ' ) . a t t r ( ' d a t e t i m e ' ) ; s u b E v e n t s . p u s h ( e v e n t ) ; } ) ; c o n s o l e . l o g ( J S O N . s t r i n g i f y ( s u b E v e n t s , n u l l , 2 ) ) ; } ) ;
  9. 9 CRAWLER SIMPLES ' u s e s t r

    i c t ' ; c o n s t r e q u e s t = r e q u i r e ( ' r e q u e s t ' ) ; c o n s t c h e e r i o = r e q u i r e ( ' c h e e r i o ' ) ; c o n s t s t a r t U r l = ' h t t p s : / / a l l i s s o n a z e v e d o . c o m / ' ; c o n s t h o s t n a m e = n e w R e g E x p ( s t a r t U r l ) ; l e t u r l S e t = n e w S e t ( ) ; l e t p a g e s = [ ] ; f u n c t i o n n o r m a l i z e U r l ( u r l ) { r e t u r n u r l . s p l i t ( ' ? ' ) [ 0 ] . s p l i t ( ' # ' ) [ 0 ] ; } f u n c t i o n v e r i f y U r l ( u r l ) { i f ( u r l . m a t c h ( / \ . x m l $ / i ) | | u r l . m a t c h ( / \ / f e e d \ / $ / i ) | | u r l . m a t c h ( / \ / a m p \ / $ / i ) ) {
  10. 10 SIMPLECRAWLER ' u s e s t r i

    c t ' ; c o n s t C r a w l e r = r e q u i r e ( ' s i m p l e c r a w l e r ' ) ; c o n s t m y C r a w l e r = n e w C r a w l e r ( ' a l l i s s o n a z e v e d o . c o m ' ) ; c o n s t c h e e r i o = r e q u i r e ( ' c h e e r i o ' ) ; l e t p a g e s = [ ] ; m y C r a w l e r . i n t e r v a l = 1 0 0 ; m y C r a w l e r . m a x C o n c u r r e n c y = 1 6 ; m y C r a w l e r . s t r i p Q u e r y s t r i n g = t r u e ; c o n s t v e r i f y U r l = m y C r a w l e r . a d d F e t c h C o n d i t i o n ( ( p a r s e d U R L , q u e u e I t e m ) = > { i f ( p a r s e d U R L . p a t h . m a t c h ( / \ . x m l $ / i ) | | p a r s e d U R L . p a t h . m a t c h ( / \ / f e e d \ / $ / i ) | | p a r s e d U R L . p a t h . m a t c h ( / \ / a m p \ / $ / i ) ) { r e t u r n f a l s e ; }
  11. 11 CRAWLEANDO O TUDOGOSTOSO 1. Veri car as urls que

    são carregadas 2. Identi car as urls que são receitas 3. Parser e indexação no Elasticsearch
  12. 12 VERIFICANDO URLS ' u s e s t r

    i c t ' ; c o n s t C r a w l e r = r e q u i r e ( ' s i m p l e c r a w l e r ' ) ; c o n s t m y C r a w l e r = n e w C r a w l e r ( ' w w w . t u d o g o s t o s o . c o m . b r ' ) ; m y C r a w l e r . i n t e r v a l = 1 0 0 ; m y C r a w l e r . s t r i p Q u e r y s t r i n g = t r u e ; m y C r a w l e r . m a x C o n c u r r e n c y = 1 6 ; m y C r a w l e r . o n ( ' f e t c h c o m p l e t e ' , ( q u e u e I t e m , r e s p o n s e B u f f e r , r e s p o n s e ) = > { c o n s o l e . l o g ( q u e u e I t e m . u r l ) ; } ) ; m y C r a w l e r . s t a r t ( ) ;
  13. 13 URLS QUE DEVEMOS EVITAR http://www.tudogostoso.com.br/favicon-v2.1.ico http://www.tudogostoso.com.br/app/assets/stylesheets/ie.css http://www.tudogostoso.com.br/images/layout/logo-v4.png http://www.tudogostoso.com.br/assets/layout/blank.gif http://www.tudogostoso.com.br/imagens/renew/footer-bg.jpg

    http://www.tudogostoso.com.br/dicas/10-pontos-do-brigadeiro/print http://www.tudogostoso.com.br/receita/print_recipe.php?recipe_id=2721 http://www.tudogostoso.com.br/receita/4683/comentarios.js
  14. 14 EVITANDO O DOWNLOAD DE URLS ' u s e

    s t r i c t ' ; c o n s t C r a w l e r = r e q u i r e ( ' s i m p l e c r a w l e r ' ) ; c o n s t m y C r a w l e r = n e w C r a w l e r ( ' w w w . t u d o g o s t o s o . c o m . b r ' ) ; m y C r a w l e r . i n t e r v a l = 1 0 0 ; m y C r a w l e r . s t r i p Q u e r y s t r i n g = t r u e ; m y C r a w l e r . m a x C o n c u r r e n c y = 1 6 ; c o n s t v e r i f y U r l = m y C r a w l e r . a d d F e t c h C o n d i t i o n ( ( p a r s e d U R L , q u e u e I t e m ) = > { i f ( p a r s e d U R L . p a t h . m a t c h ( / \ . i c o $ / i ) | | p a r s e d U R L . p a t h . m a t c h ( / \ . c s s $ / i ) | | p a r s e d U R L . p a t h . m a t c h ( / \ . p n g $ / i ) | | p a r s e d U R L . p a t h . m a t c h ( / \ . g i f $ / i ) | | p a r s e d U R L . p a t h . m a t c h ( / \ . j p g $ / i ) | | p a r s e d U R L . p a t h . m a t c h ( / \ . j s $ / i ) | | p a r s e d U R L . p a t h . m a t c h ( / p r i n t _ r e c i p e \ . p h p / i ) | | p a r s e d U R L . p a t h . m a t c h ( / \ / p r i n t $ / i )
  15. 15 URLS DE RECEITAS http://www.tudogostoso.com.br/receita/76147-anchova-assada.html ' u s e s

    t r i c t ' ; c o n s t r e = / \ / r e c e i t a \ / ( [ 0 - 9 ] + ) - ( [ \ w - ] + ) \ . h t m l $ / i ; c o n s t u r l s = [ ' h t t p : / / w w w . t u d o g o s t o s o . c o m . b r / ' , ' h t t p : / / w w w . t u d o g o s t o s o . c o m . b r / c a t e g o r i a s / b o l o s - e - t o r t a s - d o c e s . p h p ' , ' h t t p : / / w w w . t u d o g o s t o s o . c o m . b r / r e c e i t a / 1 7 9 2 3 6 - p e t i t - g a t e a u - d e - n u t e l l a - p e r f e i t o . ] ; f o r ( l e t u r l o f u r l s ) { i f ( r e . t e s t ( u r l ) ) { c o n s o l e . l o g ( u r l + ' é u m a r e c e i t a . ' ) ; } e l s e { c o n s o l e . l o g ( u r l + ' n ã o é u m a r e c e i t a ' ) ; } }
  16. 16 PARSER DA RECEITA ' u s e s t

    r i c t ' ; c o n s t c h e e r i o = r e q u i r e ( ' c h e e r i o ' ) ; c o n s t C r a w l e r = r e q u i r e ( ' s i m p l e c r a w l e r ' ) ; c o n s t m y C r a w l e r = n e w C r a w l e r ( ' w w w . t u d o g o s t o s o . c o m . b r ' ) ; c o n s t r e = / \ / r e c e i t a \ / ( [ 0 - 9 ] + ) - ( [ \ w - ] + ) \ . h t m l $ / i ; m y C r a w l e r . i n t e r v a l = 1 0 0 ; m y C r a w l e r . s t r i p Q u e r y s t r i n g = t r u e ; m y C r a w l e r . m a x C o n c u r r e n c y = 1 6 ; c o n s t v e r i f y U r l = m y C r a w l e r . a d d F e t c h C o n d i t i o n ( ( p a r s e d U R L , q u e u e I t e m ) = > { i f ( p a r s e d U R L . p a t h . m a t c h ( / \ . i c o $ / i ) | | p a r s e d U R L . p a t h . m a t c h ( / \ . c s s $ / i ) | | p a r s e d U R L . p a t h . m a t c h ( / \ . p n g $ / i ) | | p a r s e d U R L . p a t h . m a t c h ( / \ . g i f $ / i ) | | p a r s e d U R L . p a t h . m a t c h ( / \ . j p g $ / i ) | | p a r s e d U R L . p a t h . m a t c h ( / \ . j s $ / i ) | |
  17. 17 INDEXANDO NO ELASTICSEARCH ' u s e s t

    r i c t ' ; c o n s t c h e e r i o = r e q u i r e ( ' c h e e r i o ' ) ; c o n s t C r a w l e r = r e q u i r e ( ' s i m p l e c r a w l e r ' ) ; c o n s t m y C r a w l e r = n e w C r a w l e r ( ' w w w . t u d o g o s t o s o . c o m . b r ' ) ; c o n s t r e = / \ / r e c e i t a \ / ( [ 0 - 9 ] + ) - ( [ \ w - ] + ) \ . h t m l $ / i ; c o n s t e l a s t i c s e a r c h = r e q u i r e ( ' e l a s t i c s e a r c h ' ) ; c o n s t c l i e n t = n e w e l a s t i c s e a r c h . C l i e n t ( { h o s t : ' l o c a l h o s t : 9 2 0 0 ' , l o g : ' t r a c e ' } ) ; m y C r a w l e r . i n t e r v a l = 1 0 0 ; m y C r a w l e r . s t r i p Q u e r y s t r i n g = t r u e ; m y C r a w l e r . m a x C o n c u r r e n c y = 1 6 ; c o n s t v e r i f y U r l = m y C r a w l e r . a d d F e t c h C o n d i t i o n ( ( p a r s e d U R L , q u e u e I t e m ) = > { i f ( p a r s e d U R L . p a t h . m a t c h ( / \ . i c o $ / i ) | |
  18. 18 DEMO DO WEBAPP

  19. 19 OBRIGADO!