Ξύσιμο ιστού από πλευράς πελάτη με JavaScript χρησιμοποιώντας το jQuery και το Regex

Όταν έφτιαχνα το πρώτο μου έργο ανοιχτού κώδικα, codeBadges, σκέφτηκα ότι θα ήταν εύκολο να λάβω δεδομένα προφίλ χρήστη από όλους τους κύριους ιστότοπους εκμάθησης κώδικα.

Ήμουν εξοικειωμένος με τις κλήσεις API και να λάβω αιτήματα. Νόμιζα ότι θα μπορούσα απλώς να χρησιμοποιήσω το jQuery για να ανακτήσω τα δεδομένα από τα διάφορα API και να τα χρησιμοποιήσω.

var name = 'codemzy'; $.get('//api.github.com/users/' + name, function(response) { var followers = response.followers;});

Λοιπόν, αυτό ήταν εύκολο. Αλλά αποδεικνύεται ότι δεν έχει κάθε ιστότοπος ένα δημόσιο API από το οποίο μπορείτε απλώς να αρπάξετε τα δεδομένα από τα οποία θέλετε.

Αλλά επειδή δεν υπάρχει δημόσιο API δεν σημαίνει ότι πρέπει να σταματήσετε! Μπορείτε να χρησιμοποιήσετε το web scraping για να τραβήξετε τα δεδομένα, με λίγη επιπλέον δουλειά .

Ας δούμε πώς μπορούμε να χρησιμοποιήσουμε την απόξεση ιστού από την πλευρά του πελάτη με JavaScript.

Για παράδειγμα, θα τραβήξω τις πληροφορίες χρήστη από το δημόσιο προφίλ μου στο FreeCodeCamp. Αλλά μπορείτε να χρησιμοποιήσετε αυτά τα βήματα σε οποιαδήποτε δημόσια σελίδα HTML.

Το πρώτο βήμα στη διαγραφή των δεδομένων είναι να αρπάξετε ολόκληρη τη σελίδα html χρησιμοποιώντας ένα .getαίτημα jQuery .

var name = "codemzy";$.get('//www.freecodecamp.com/' + name, function(response) { console.log(response);});

Φοβερό, ολόκληρος ο πηγαίος κώδικας της σελίδας μόλις συνδεθήκατε στην κονσόλα.

Σημείωση: Εάν εμφανιστεί σφάλμα σε αυτό το στάδιο σύμφωνα με το No ‘Access-Control-Allow-Origin’ header is present on the requested resourceμην ανησυχείς. Κάντε κύλιση προς τα κάτω στην ενότητα Μην αφήσετε τους CORS να σας σταματήσουν από αυτήν την ανάρτηση.

Αυτό ήταν εύκολο. Χρησιμοποιώντας JavaScript και jQuery, ο παραπάνω κώδικας ζητά μια σελίδα από το www.freecodecamp.org, όπως θα έκανε ένα πρόγραμμα περιήγησης. Και το freeCodeCamp αποκρίνεται με τη σελίδα. Αντί για ένα πρόγραμμα περιήγησης που εκτελεί τον κώδικα για την προβολή της σελίδας, λαμβάνουμε τον κώδικα HTML.

Και αυτό είναι το web scraping, εξαγωγή δεδομένων από ιστότοπους.

Εντάξει, η απάντηση δεν είναι ακριβώς τόσο τακτοποιημένη όσο τα δεδομένα που λαμβάνουμε από ένα API.

Αλλά… έχουμε τα δεδομένα, εκεί κάπου.

Μόλις έχουμε τον πηγαίο κώδικα, οι πληροφορίες που χρειαζόμαστε είναι εκεί, απλώς πρέπει να αρπάξουμε τα δεδομένα που χρειαζόμαστε!

Μπορούμε να αναζητήσουμε την απάντηση για να βρούμε τα στοιχεία που χρειαζόμαστε.

Ας υποθέσουμε ότι θέλουμε να μάθουμε πόσες προκλήσεις έχει ολοκληρώσει ο χρήστης, από την απόκριση προφίλ χρήστη που λάβαμε πίσω.

Κατά τη στιγμή της γραφής, οι ολοκληρωμένες προκλήσεις ενός τροχόσπιτου οργανώνονται σε πίνακες στο προφίλ χρήστη. Για να ολοκληρωθεί ο συνολικός αριθμός των προκλήσεων, μπορούμε να μετρήσουμε τον αριθμό των σειρών.

Ένας τρόπος είναι να τυλίξετε ολόκληρη την απόκριση σε ένα αντικείμενο jQuery, έτσι ώστε να μπορούμε να χρησιμοποιήσουμε μεθόδους jQuery όπως .find()να πάρουμε τα δεδομένα.

// number of challenges completedvar challenges = $(response).find('tbody tr').length;

Αυτό λειτουργεί καλά - έχουμε το σωστό αποτέλεσμα. Αλλά δεν είναι ένας καλός τρόπος για να έχουμε το αποτέλεσμα που επιδιώκουμε. Η μετατροπή της απόκρισης σε αντικείμενο jQuery φορτώνει πραγματικά ολόκληρη τη σελίδα, συμπεριλαμβανομένων όλων των εξωτερικών σεναρίων, γραμματοσειρών και φύλλων στυλ από αυτήν τη σελίδα… Ωχ!

Χρειαζόμαστε μερικά κομμάτια δεδομένων. Πραγματικά δεν χρειαζόμαστε τη φόρτωση της σελίδας, και σίγουρα δεν είναι όλοι οι εξωτερικοί πόροι που συνοδεύουν.

Θα μπορούσαμε να αφαιρέσουμε τις ετικέτες σεναρίων και μετά να εκτελέσουμε την υπόλοιπη απάντηση μέσω του jQuery. Για να το κάνουμε αυτό, θα μπορούσαμε να χρησιμοποιήσουμε το Regex για να αναζητήσουμε μοτίβα σεναρίων στο κείμενο και να τα καταργήσουμε.

Ή ακόμα καλύτερα, γιατί να μην χρησιμοποιήσετε το Regex για να βρείτε αυτό που ψάχνουμε πρώτα;

// number of challenges completedvar challenges = response.replace(/[\s|\S]*?/g).match(//g).length;

Και λειτουργεί! Χρησιμοποιώντας τον κωδικό Regex παραπάνω, αφαιρούμε τις σειρές κεφαλίδας πίνακα (που δεν περιείχαν προκλήσεις) και, στη συνέχεια, αντιστοιχίζουμε όλες τις σειρές πίνακα για να μετρήσουμε τον αριθμό των προκλήσεων που έχουν ολοκληρωθεί.

Είναι ακόμα πιο εύκολο εάν τα δεδομένα που θέλετε είναι απλώς εκεί στην απάντηση σε απλό κείμενο. Κατά τη στιγμή της σύνταξης, τα σημεία του χρήστη ήταν στο html όπως

[ 1498 ]

απλά περιμένω να ξυστούν

var points = response.match(/

\[ ([\d]*?) \]/)[1];

Στο παραπάνω μοτίβο Regex ταιριάζουμε με το στοιχείο h1 που ψάχνουμε, συμπεριλαμβανομένου του [ ]που περιβάλλει τους πόντους, και ομαδοποιούμε οποιονδήποτε αριθμό μέσα με ([\d]*?).Παίρνουμε έναν πίνακα πίσω, το πρώτο [0]στοιχείο είναι ολόκληρος ο αγώνας και ο δεύτερος [1]είναι ομαδικός αγώνας μας (οι πόντοι μας ).

Το Regex είναι χρήσιμο για την αντιστοίχιση όλων των ειδών μοτίβων σε χορδές και είναι εξαιρετικό για αναζήτηση μέσω της απάντησής μας για τη λήψη των δεδομένων που χρειαζόμαστε.

Μπορείτε να χρησιμοποιήσετε την ίδια διαδικασία 3 βημάτων για να αποκόψετε δεδομένα προφίλ από διάφορους ιστότοπους:

  1. Χρησιμοποιήστε JavaScript από την πλευρά του πελάτη
  2. Χρησιμοποιήστε το jQuery για να αποκόψετε τα δεδομένα
  3. Χρησιμοποιήστε το Regex για να φιλτράρετε τα δεδομένα για τις σχετικές πληροφορίες

Μέχρι να χτυπήσω ένα πρόβλημα, CORS.

Μην αφήσετε τους CORS να σας σταματήσουν!

Το CORS ή το Cross-Origin Resource Sharing, μπορεί να είναι ένα πραγματικό πρόβλημα με το web scrap από τον πελάτη.

Για λόγους ασφαλείας, τα προγράμματα περιήγησης περιορίζουν αιτήματα HTTP πολλαπλής προέλευσης που ξεκινούν από σενάρια. Και επειδή χρησιμοποιούμε Javascript από την πλευρά του πελάτη στο μπροστινό άκρο για απόξεση ιστού, ενδέχεται να προκύψουν σφάλματα CORS.

Ακολουθεί ένα παράδειγμα που προσπαθεί να αποκόψει δεδομένα προφίλ από το CodeWars…

var name = "codemzy";$.get('//www.codewars.com/users/' + name, function(response) { console.log(response);});

Κατά τη στιγμή της σύνταξης, η εκτέλεση του παραπάνω κώδικα σάς δίνει ένα σχετικό σφάλμα CORS.

Εάν δεν υπάρχει Access-Control-Allow-Originκεφαλίδα από το σημείο που αποκόπτετε, μπορεί να αντιμετωπίσετε προβλήματα.

Τα κακά νέα είναι ότι πρέπει να εκτελέσετε τέτοιου είδους αιτήματα από την πλευρά του διακομιστή για να αντιμετωπίσετε αυτό το ζήτημα.

Τι ναι, αυτό υποτίθεται ότι είναι απόξεση ιστού από την πλευρά του πελάτη ;!

Τα καλά νέα είναι, χάρη σε πολλούς άλλους υπέροχους προγραμματιστές που αντιμετώπισαν τα ίδια ζητήματα, δεν χρειάζεται να αγγίξετε τον εαυτό σας.

Παραμένοντας σταθερά στο σενάριο διεπαφών, μπορούμε να χρησιμοποιήσουμε εργαλεία μεταξύ τομέων όπως Any Origin, Any Origin, All Origins, crossorigin και πιθανώς πολλά άλλα. Έχω διαπιστώσει ότι πρέπει συχνά να δοκιμάσετε μερικά από αυτά για να βρείτε αυτό που θα λειτουργήσει στον ιστότοπο που προσπαθείτε να διαγράψετε.

Πίσω στο παράδειγμα CodeWars, μπορούμε να στείλουμε το αίτημά μας μέσω ενός εργαλείου μεταξύ τομέων για να παρακάμψουμε το ζήτημα CORS.

var name = "codemzy";var url = "//anyorigin.com/go?url=" + encodeURIComponent("//www.codewars.com/users/") + name + "&callback=?";$.get(url, function(response) { console.log(response);});

Και όπως και η μαγεία, έχουμε την απάντησή μας.