گرفتن قیمت روز طلا با وب سرویس Web Scraping با Node.js

15 بهمن 1399 برچسب‌ها:, ,

در مقاله قبلی اپلیکیشن Node.js خود را به Heroku ریختیم. میخواهیم در این مقاله به جزئیات کدهای همین ریپوسیتوری بپردازیم. فایل اصلی app.js است. بنابراین کدهای همین برگه را تشریح میکنیم. در حقیقت ما از داده های سایت اطلاع رسانی قیمت سکه و طلا استفاده کردیم تا در سایت خود آن را نمایش دهیم. معمولا این کار با بهره گیری از Api ها صورت میگیرد اما اگر Api وجود نداشت بعنوان آخرین راه از Web Scraping استفاده میکنیم.

خراش دادن وبسایت یا Web Scraping

به استخراج داده های سایت های دیگر وب اسکرپینگ می گویند. Web scraping یک web service است که در سمت سرور BackEnd انجام میشود. میتواند با هر زبانی انجام شود. مانند python, Node.js, php اما با php کار کمی نیاز به کدهای بیشتری دارد. شاید بخاطر اینکه این زبان قدیمی شده است. اینجا با Node.js و کتابخانه هایش این کار را انجام میدهیم.

پیشنیاز: نصب و راه اندازی

گام اول: نصب Node.js 

 به سایت Node.js بروید و آن را نصب کنید. کافیست مانند نصب هر نرم افزار ساده دیگری در ویندوز این کار را انجام دهید.

گام دوم: دانلود ریپوسیتوری

از این لینک کد ها را دانلود کنید. و اکسترکت کنید. وارد فولدر server شوید و app.js را ببینید.

گام سوم: دانلود پکیج ها

کافیست ترمینال را باز کنید و کامند npm install را بزنید و کمی صبر کنید تا پکیج های پروژه بصورت کامل نصب شوند. این پکیج های در پروژه import میشوند و مورد استفاده قرار میگیرند.

راه اندازی پروژه

گام اول: به ترمینال بروید و npm start را بزنید. به این ترتیب سرور راه اندازی میشود.

گام دوم: بروزر خود را باز کنید و به ترمینال به آدرس localhost:5000 زیر بروید.

تشریح پکیج های import شده

همانطور که در app.js میبینید. فریمورک مشهور Node.js به نام Express.js وارد کردیم تا بتوانیم سرور و route ها را با آن راه اندازی کنیم.

const express = require('express');
const app = express();

پکیج request به ما کمک میکند تا از درخواست http به وبسایت های مختلف بفرستیم و پاسخ را دریافت کنیم. این درخواست میتواند GET باشد و پاسخ آن میتواند یک صفحه وبسایت باشد. منظور همان کدهای html است.

const request = require('request')

برای اینکه بتوانیم پاسخ درخواستی که به واسطه پکیج request میفرستیم را راحت تر دریافت کنیم، پکیج مکمل ان به نام request-promise را هم نصب میکنیم.

const rp = require('request-promise')

از پکیج cheerio استفاده میکنیم تا پاسخ گرفته شده از پکیج request را لود کنیم. بدین منظور از متد load در پکیج استفاده کردیم تا html دریافت کنیم.

const cheerio = require('cheerio')

حالا به راحتی اطلاعات مورد نظرتان را درخواست کنید!

این بخش جذاب ترین بخش کد است. زیرا از پکیج ها استفاده میکنیم تا اطلاعات را درخواست کنیم. سپس اطلاعات را به فرمت html در می آوریم و نهایتا همان داده مورد نظر خود را از درون html انتخاب میکنیم و استخراج میکنیم تا در وبسایت خود از ان داده بهره ببریم.

نوشتن تابعی که اطلاعات را درخواست میکند!

اینجا کدهای مربوط به تعریف تابع webScrap را مشاهده میکنید. که یک مقدار ورودی دارد. این ورودی یک آبجکت است که شامل url وبسایتی که میخواهیم اطلاعات را از انجا بیاوریم و دو query برای دریافت دو داده مورد نظر ماست. اینجا میخواهیم دو چیز را بگیریم. یکی عنوان و دیگری قیمت. عنوان میتواند چیزی مثل “سکه گرمی هجده عیار” باشد و قیمت روز سکه را هم داشته باشیم. برای اینکار از سایت https://www.tgju.org/ استفاده کردیم.

async function webScrap(x) {

  var options = {
    uri: x.url,
    transform: function (body) {
      return cheerio.load(body);
    }
  };

  let $ = await rp(options)

  let obj = {
    title: $(x.q1).text(),
    price: $(x.q2).text()
  }

  return obj

}

فراخوانی تابع تعریف شده با مقدار دهی اولیه (دو بار)

به محتویات داخل app.get توجه کنید. یک روت دارد و یک فانکشن! داخل این فانکشن ما دو بار تابع webScrap را با دو مقدار دهی اولیه فراخوانی کردیم.

// mesghal 
  var mesghaletala = await webScrap({
    url: 'https://www.tgju.org/',
    q1: 'body.homepage #l-mesghal h3',
    q2: 'body.homepage #l-mesghal .info-price'
  }).catch(err => console.log(err))
  // gram18  
  var gram18 = await webScrap({
    url: 'https://www.tgju.org/profile/geram18',
    q1: 'h1',
    q2: '.fs-cell:nth-of-type(3) span.value > span[data-col="info.last_trade.PDrCotVal"]'
  }).catch(err => console.log(err))

استفاده از خروجی برای نمایش در سایت

به داخل res.send توجه کنید. کدهای جدول html با تگ های body و td و tr را مشاهده میکنید. داخل جدول دو مقدار داینامیک قرار داده شده است. دو ردیف از جدول در بروزر دارای عنوان و قیمت هستند. این اطلاعات اینگونه آمده اند.

res.send(` 
    <div style="direction:rtl; margin:3em"> 
      <table style="width:400px;text-align:right">
          <tbody>
              <tr> <th>عنوان</th> <th>قیمت</th> </tr>
          </tbody>
          <tbody>
              <tr> <td>${mesghaletala.title}</td><td>${mesghaletala.price}</td></tr>
              <tr> <td>${gram18.title}</td><td>${gram18.price}</td></tr>
          </tbody>
      </table>
    </div>
    `)

راه اندازی سرور

در بروزر در ادرس localhost:5000 میتوانید اپلیکیشن خود را ببینید که این پورت 5000 دقیقا اینجا تعریف شده است.

app.listen(process.env.PORT || 5000);

از اینکه این مقاله را خواندید متشکرم!