Devacron.com

Web scraping – Ο κλεψας του κλεψαντος

Μπορει να μην εχετε ακουσει τον ορο web scraping αλλα σχεδον σιγουρα εχετε πλοηγηθει εστω μια φορα σε καποιο website που κανει χρηση web scraping. Σαν ορισμο θα λεγαμε οτι προκειται για την τεχνικη του να παιρνουμε πληροφοριες απο καποιο site. Αυτο ειτε με καποιο software εγκατεστημενο στον υπολογιστη μας ή μεσω bot – script που επισκεπτονται website και διαβαζουν τον κωδικα τους, τον αποθηκευουν σε καποια βαση και τον αξιοποιουν αναλογα. Αυτο οπως καταλαβαινετε βεβαια δημιουργει θεμα νομιμοτητας σχετικα με τα πνευματικα δικαιωματα αφου μπορει ο ιδιοκτητης να μην εχει δωσει την συγκαταθεση του. Και μαλιστα ειναι απειρα εκει εξω τα site που μεσω webscraping παιρνουν ολοκληρα αρθρα και τα περνανε στο δικο τους site. Ετσι μαλιστα αποκομιζουν κερδη μεσω των διαφημισεων. Ομως υπαρχουν περιπτωσεις που θα θελαμε σε ενα blog πχ να βαλουμε ενα ticker που να δειχνει την πρωτη προταση απο τις κυριες ειδησεις ενος ας πουμε αθλητικου site. Αν μαλιστα παρουμε και την συγκαταθεση του ιδιοκτητη τοτε και οι δυο κερδιζουν αφου και εμεις παιρνουμε φρεσκο υλικο αλλα και θα στελνουμε visits.

Χρειαστηκε να ασχοληθω λιγο περισσοτερο με το web scraping λογω δουλειας  και ετσι στον ελευθερο μου χρονοεφτιαξα ενα τικερακι το οποιο παιρνει τις ειδησεις απο την κατηγορια “Οικονομικα” του naftemporiki.gr και μεσω της .animate() της παρουσιαζει μια μια σε ενα div. Για να μπορεσω να παρω τις ειδησεις απο την naftemporiki χρησιμοποιησα την YQL της yahoo. Kαι ο λογος ηταν για να αποφυγω το προβλημα του cross domain request. Αναλυτικα για το same origin policy μπορειτε να δειτε εδω.

Αυτο που θα φτιαξουμε λοιπον ειναι το παρακατω:

 

Οπως θα δειτε και στον κωδικα παρακατω προκειται για καθαρα μια client side λυση η οποια δεν αποθηκευει πουθενα δεδομενα αλλα μονο τα προβαλει. Και ολο αυτο σε λιγοτερο απο 30 γραμμες javascript κωδικα. Ας τον δουμε λοιπον και θα εξηγησω παρακατω.

<html>
<head>
    <title>Web scraping + Jquery ticker by xDev.gr</title>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
    <style>
        body {margin: 0 auto; width: 400px; background-color: white; padding:20;}
        .divs{border:1px; border-style:solid; border-color:grey; border-radius:5px; width:400px; margin:0 auto; overflow: hidden; height:200px; font-family:Verdana;        
        background: -moz-linear-gradient(top,  rgba(0,0,0,0.26) 0%, rgba(0,0,0,0.26) 1%, rgba(0,0,0,0) 100%); /* FF3.6+ */
        background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(0,0,0,0.26)), color-stop(1%,rgba(0,0,0,0.26)), color-stop(100%,rgba(0,0,0,0))); /* Chrome,Safari4+ */
        background: -webkit-linear-gradient(top,  rgba(0,0,0,0.26) 0%,rgba(0,0,0,0.26) 1%,rgba(0,0,0,0) 100%); /* Chrome10+,Safari5.1+ */
        background: -o-linear-gradient(top,  rgba(0,0,0,0.26) 0%,rgba(0,0,0,0.26) 1%,rgba(0,0,0,0) 100%); /* Opera 11.10+ */
        background: -ms-linear-gradient(top,  rgba(0,0,0,0.26) 0%,rgba(0,0,0,0.26) 1%,rgba(0,0,0,0) 100%); /* IE10+ */
        background: linear-gradient(to bottom,  rgba(0,0,0,0.26) 0%,rgba(0,0,0,0.26) 1%,rgba(0,0,0,0) 100%); /* W3C */
        filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#42000000', endColorstr='#00000000',GradientType=0 ); /* IE6-9 */       
        }
    </style>
</head>

<body>
<div id="test" class="divs">
<ul id="ticker" style="list-style:none; overflow: hidden; padding:20; margin:0;"></ul>
</div>
<script type="text/javascript">   

    var content = [];   

    $.getJSON('http://query.yahooapis.com/v1/public/yql?callback=?',
      {
        q: 'select * from html where url="http://www.naftemporiki.gr/news/_categ.asp?categ=fin" and xpath="//li[contains(@style,\'background-image:none\')]"',
        format: 'json'
      },
      function (data) {
            console.log(data.query.results) 
            stuff = data.query.results;
            for (i = 0; i<20; i++){          
                    content.push(stuff.li[i+1])     
            $('#ticker').append("<li id='divnum"+i+"'><div style='height:220px;'><a href='http://www.naftemporiki.gr"+content[i].a.href+"'><b>"+content[i].a.content+"</b></a><br/><p style='font-size:12px;'>"+ content[i].p.content+ "</p></div></li>");
        }   
        var ticker = function()
        {
             setTimeout(function(){
                $('#ticker li:first').animate( {marginTop: '-220px'}, 1000, function()
                    {
                        $(this).detach().appendTo('ul#ticker').removeAttr('style'); 
                    });
                ticker();
            }, 4000);       
        };
        ticker();
      }
    );
</script>
</body>
</html>

Οπως βλεπετε ξεκιναω με το css styling και την απαραιτητη προσθηκη της jQuery. Αν και εχουμε φτασει στην 1.8.2 εκδοση εγω ακομα χρησιμοποιω την 1.7.1 και αυτο γιατι δεν εχω προλαβει να δω τα νεα χαρακτηριστικα της. Επειτα εχουμε καποια div και την δημιουργεια της λιστας των ειδησεων που ακομα ειναι αδεια. Συνεχιζουμε με javascript οπου μεσω της $.getJSON παιρνουμε απο την yahoo τις πληροφοριες που θελουμε. Οπως  βλεπετε το συντακτικο του query μοιαζει με αυτο των SQL βασεων και αυτο γιατι η yahoo θεωρει το web μια βαση. Περναμε το url απο το οποιο θελουμε να παρουμε τα δεδομενα και μεσω xpath φιλτραρουμε αυτα που χρειαζομαστε. Συνηθως επιλεγουμε καποιο μοναδικο χαρακτηριστικο. Επειτα τα δεδομενα που μου στελνει η yahoo τα περναω σε ενα array και μεσω ενος for loop προσθετω ενα ενα τα list items με τις ειδησεις στο ul tag που εφτιαξα παραπανω. Τελος μεσω της setTimeout επιλεγω το πρωτο στοιχειο της λιστας και το μετακινω. Επειτα το βαζω ξανα στο κατω μερος της λιστας με appendTo() ωστε μετα απο λιγο να επανελθει στην αρχη. Τελος αφηνω την καθε ειδηση 4 δευτερολεπτα. Ξερω οτι ισως φαινεται λιγο περιπλοκο αλλα στην πραγματικοτητα δεν ειναι. Αφιερωστε λιγο χρονο για την κατανοηση του javascript κομματιου και θα δειτε οτι η YQL πραγματικα ειναι φοβερο δωρεαν εργαλειο.

Kατεβαστε το παρακατω αρχειο και τρεξτε στον browser σας.

(xDevGR)webscrapper_ticker

Exit mobile version