وقتی api نداره، api میسازیم! (nodeJS - cheerio)

استخراج داده از صفحات وب یا web scraping
استخراج داده از صفحات وب یا web scraping


خب. به عنوان اولین پست میخواستم از خود ویرگول شروع کنم. چون ای پی آیی که لازم داشتم ازش رو پیدا نکردم
تصمیم گرفتم بسازمش و مراحل ساخت رو با شما به اشتراک بذارم.

خب ابزارایی که لازم داریم رو نصب میکنیم

npm install express cheerio axios --save

خب پیش از هر چیزی نیازه که سرورمون راه بیفته، برای این کار از express استفاده میکنیم.

const express = require(&quotexpress&quot); 
const app = express(); 
// روتینگ و ادامه ماجرا اینجا قرار میگیره 
app.listen(3000, () => console.log(&quotServer run at port 3000&quot));

حالا کافیه مشخص کنیم که تو چه آدرسی چه چیزی قرار بگیره فرض کنید ما میخوایم توی localhost:3000 مشخصات کاربر رو به صورت JSON بگیریم و در localhost:3000/activity پست هایی که گذاشته توی ویرگول رو به حالت استاندارد مخصوص خودمون تبدیل کنیم.

پس آدرس دهی هامونو اینطوری اضافه میکنیم.

const express = require(&quotexpress&quot);
const app = express();
app.get('/', async (req, res) => {
    res.send('profile')
})
app.get('/activity', async (req, res) => {
    res.send('posts page')
})
app.listen(3000, () => console.log(&quotServer run at port 3000&quot));

حالا یه نگاهی به صفحه هر کاربر توی ویرگول میندازیم. قسمتایی که برای ما مهمه ایناس:

اسم / عکس پروفایل / بایو / تعداد فالور ها / تعداد فالوینگ ها

کافیه خیلی سریع روشون راست کلیک کنید و inspect element بزنین تا با کلاس یا آی دی خاصی نمایش داده میشن یا نه که میبینیم به ترتیب:

اسم: توی یک کلاسی با تگ a و به اسم module--name نمایش داده میشه.

عکس پروفایل: یک تگ div داریم با کلاس module--avatar که داخل اون یک تگ a هست و بعدش داخل تگ img اتریبیوت src اون عکس رو به ما برمیگردونه.

بایو: یک تگ p با کلاس module--bio.

فالور و فالوینگ ها: توی یه تگ a با کلاس followers یا followings داخل تگ span عددش به صورت فارسی نوشته شده.

حالا کدی که اینارو دریافت میکنه به صورت زیره و میتونیم با همدیگه قدم به قدم پیش ببریم توی حالت های مختلف استفاده از cheerio.

app.get('/', async (req, res) => {
    const id = 'HosseinDotLink';
    const url = 'https://virgool.io/@' + id;
    const html = await axios.get(url);
    const $ = cheerio.load(html.data);
    const imageURL = $('div[class=module--avatar] a').find('img').attr('src');
    const name = $('a[class=module--name]').text();
    const bio = $('.module--bio').text();
    const follower = $('.followers span').html().replace(/[٠-٩]/g, d => &quot٠١٢٣٤٥٦٧٨٩&quot.indexOf(d)).replace(/[۰-۹]/g, d => &quot۰۱۲۳۴۵۶۷۸۹&quot.indexOf(d));
    const following = $('.following  span').html().replace(/[٠-٩]/g, d => &quot٠١٢٣٤٥٦٧٨٩&quot.indexOf(d)).replace(/[۰-۹]/g, d => &quot۰۱۲۳۴۵۶۷۸۹&quot.indexOf(d));

    res.json({
        id: id,
        url: url,
        social: &quotvirgool&quot,
        image: imageURL,
        name: name,
        bio: bio,
        followers: Number(follower),
        followings: Number(following)
    });
})

ابتدا id مورد نظرمونو وارد میکنیم، مثلا من آی دی خودمو وارد کردم.

بعد از اون url رو میسازیم و با axios محتویات صفحه اون آدرس رو میگیریم و داخل html ذخیره میکنیم. (توجه داشته باشین مواردی که میخوایم توی html.data قرار میگیره)

حالا اطلاعات دیتا رو توی cheerio لود میکنیم

ضمنا من تصمیم گرفتم تا با حالت های این ابزار کار کنیم تا آشنا تر بشیم.

برای دریافت آدرس عکس کافیه به مقدار لود شده بگیم ابتدا تگ div با کلاس مورد نظرمونو پیدا کنه و بعد از اون تگ a داخلش رو به ما برگردونه حالا با تابع find دوباره تگ img رو ازش میگیریم (این رو می شد همون اول هم گرفت فقط خواستم با find هم آشنا بشیم). سپس با استفاده از attr میتونیم اتریبیوت های مختلف تعریف شده برای هر تگ رو پیدا کنیم مثلا می دونیم که آدرس عکس های توی src قرار میگیره.

برای گرفتم اسم هم با استفاده از تگ a با کلاسش مقدارش رو به text تبدیل میکنیم و میریزم تو متغیرمون.

بایو رو هم مستقیما با کلاس دریافت میکنیم.

تو فالور و فالوینگ یه نکته ای هست اونم اینکه اعداد اینجا به صورت فارسی نوشته شده و نمیتونید به Number تبدیل کنید برای همین اول رشته مربوط به این اعداد رو به روش بالا در صورت عربی یا فارسی بودن به انگلیسی تبدیل میکنیم.

آخر کار هم به صورت JSON توی ریسپانس برمیگردونیم.

فکر میکنم این پست داره طولانی میشه
برای همین نحوه استخراج پست هارو توی یه آموزش دیگه خدمتتون عرض میکنم ::))))))
شما هم میتونید توی ادامه دادن این استخراج اطلاعات از شبکه های اجتماعی توی گیت زیر منو همراهی کنید

https://github.com/HosseinDotLink/on-social-media

یا اگه فکر میکنید شبکه جذاب دیگه ای برای این کار هست بهم معرفی کنید.

آزاد و پیروز باشید.