<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های Danial Moafi</title>
        <link>https://virgool.io/feed/@danialmoafi</link>
        <description></description>
        <language>fa</language>
        <pubDate>2026-04-15 04:37:25</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/1091977/avatar/avatar.png?height=120&amp;width=120</url>
            <title>Danial Moafi</title>
            <link>https://virgool.io/@danialmoafi</link>
        </image>

                    <item>
                <title>خواندن کتاب‌های فیدیبو و طاقچه روی کیندل</title>
                <link>https://virgool.io/@danialmoafi/%D8%AE%D9%88%D8%A7%D9%86%D8%AF%D9%86-%DA%A9%D8%AA%D8%A7%D8%A8-%D9%87%D8%A7%DB%8C-%D9%81%DB%8C%D8%AF%DB%8C%D8%A8%D9%88-%D9%88-%D8%B7%D8%A7%D9%82%DA%86%D9%87-%D8%B1%D9%88%DB%8C-%DA%A9%DB%8C%D9%86%D8%AF%D9%84-khl4kghqcqcy</link>
                <description>بعد از این که کتاب‌خوان کیندل رو  گرفتم، فهمیدم که کتاب‌های فیدیبو و طاقچه رو نمی‌شه روی کیندل خوند و صرفا بیشتر برای مطالعه کتاب‌های انگلیسی می‌شه استفاده کرد. اما از اون جایی که کلی کتاب تو لیست کتاب‌هایی که می‌خوام بخونم تو فیدیبو و طاقچه بود تصمیم گرفتم یه روشی رو برای مطالعه کتاب‌ها پیدا کنم.بهترین روش که به ذهنم رسید عکس گرفتن از تک تک صفحه‌ها و تبدیل کردن عکس‌ها به فرمت PDF یا فرمت‌های دیگه‌ای که کیندل ساپورت می‌کنه بود. ولی به دلیل این که داریم عکس میگیریم دیگه آپشن‌هایی مثل هایلایت کردن رو از دست میدیم، ولی خوب باز بهتر از هیچی بود (البته روش‌هایی وجود داره برای این که عکس رو می‌گیرید، خط‌ها رو شناسایی کنه و بعد تبدیل به pdf کنه ولی یکم زحمتش زیادتر بود). فقط برای این که حق ناشر و اینا هم رعایت بشه، کتاب‌هایی که از این روش استفاده می‌کنید رو فقط خودتون استفاده کنید. طاقچه اول رفتم سراغ طاقچه به خاطر این که وب اپلیکیشن داره و کار راحت تره. یعنی می‌تونستم روی فایرفاکس کتاب رو باز کنم. به صورت کلی کاری که قرار انجام بدیم به این صورتاست، که از صفحات عکس بگیریم و ورق زده بشه. برای این کار از python و پکیج selenium استفاده کردم. که با استفاده از pip میتونید اون را نصب کنید. پس از نصب پکیج‌ برای کار با سلنیوم باید درایور بروزر مورد نظرتون رو نصب کنید. برای این مقاله از فایرفاکس استفاده شد که برای دانلود کردن درایور آن می‌تونید به اینجا برید.from selenium import webdriver
driver = webdriver.Firefox()
driver.set_window_size(500, 800)با استفاده از کد بالا فایرفاکس رو باز می‌کنم، خوب بعد از اون به سایت طاقچه میریم و کتابی که خریدیم رو باز می‌کنیم. اندازه صفحه رو هم با توجه به اندازه دستگاه تنظیم می‌کنیم که خیلی ریز یا درشت نشه، برای kindle paperwhite اندازه بالا مناسب بود.  عکس پایین کتاب ۱۲ قانون زندگی رو میبینید که توی طاقچه باز کردم.  ۱۲ قانون زندگی کاری که باید انجام بدیم عکس گرفتن از هر صفحه و رفتن به صفحه‌ی بعد هست.from selenium import webdriver
def screenshot_all_page(name_book):
    for this_p in range(int(driver.find_element_by_xpath(&#039;//*[@id=&amp;quottotalPages&amp;quot]&#039;).text)):
        driver.save_screenshot(f&#039;/PATH_FILE/{name_book}/{this_p}.png&#039;)
        driver.find_element_by_xpath(&#039;/html/body/div[3]/div[2]/div[3]/div[2]/div[1]/i&#039;).click()
screenshot_all_page(&#039;12_ghanon_zendegi&#039;)کد زده شده دارای ۳ تا قسمت هست،‌اول از همه تعداد صفحات را بدست میاریم که بدونیم حلقه for چقدر باید اجرا بشه،‌ بعد از اون با دستور save_screenshot از صفحه عکس می‌گیریم و با خط بعدی به صفحه بعد می‌رویم. این قسمت با توجه به تعداد صفحه کتاب ممکن زمان‌بر بشه. برای تبدیل کردن عکس‌های گرفته شده با pdf هم میتوان از سایت هایی مثل pdf.online استفاده کرد که فقط نیاز به آپلود کردن همه‌ی عکس‌ها داخل آن است، هم از کد پایین می‌توانیم استفاده کنیم. که نیاز به دو پکیج PIL و fpdf دارد. from fpdf import FPDF
from PIL import Imagepdf = FPDF()
imagelist=[]
total_num_page = int(driver.find_element_by_xpath(&#039;//*[@id=&amp;quottotalPages&amp;quot]&#039;).text)
for page_num in range(1, total_num_page):
    image = Image.open(f&#039;/PATH_FILE/12_ghanon_zendegi/{page_num}.png&#039;)
    imagelist.append(image).convert(&#039;RGB&#039;))imagelist[0].save(&#039;/PATH_FILE/12_ghanon_zendegi/12_ghanon_zendegi.pdf&#039;, save_all=True, append_images=imagelist)فیدیبوفیدیبو مثل  طاقچه دارای وب اپلیکیشن نیست و باید اون رو روی یک گوشی نصب کنیم. برای این کار از Android Emulator استفاده کردم. از برنامه Android studio برای شبیه‌سازی اندروید استفاده کردم،‌ البته برنامه‌های سبک‌تری هم برای این کار است. Android studio رو هم می‌تونید از اینجا دانلود کنید. بعد از نصب کردن برنامه و اجرا کردن آن به دنبال AVD Manager بگردید که معمولا در سمت راست بالا قرار داره، پس از کلیک کردن یک پنجره باز می‌شه که می‌توانید virtual device  بسازید. برای این کار بر روی Create Virtual Device کلیک کنید، بعد از آن صفحه‌ای که باز می‌شود برای انتخاب دستگاه و مشخصات آن است. بهتر است دستگاهی رو انتخاب کنید که از نظر اندازه نزدیک‌تر به کیندل باشد، البته می‌تونید خودتون هم با استفاده New Hardware profile دستگاه کیندل خود را تعریف کنید، بعد از این قسمت نیاز هست اندروید موردنظرتون نصب بشه، برای این کار نیاز هست که فیلترشکن را روشن کنید،‌ بعد از اون آخرین اندروید که هست را نصب کنید. با توجه به سرعت اینترنت این قسمت زمان‌بر است. بعد از این که تموم شد، دستگاه رو راه‌اندازی کنید. در قسمت بعدی نیاز داریم اپلیکیشن فیدیبو رو نصب کنیم. برای این کار فایل apk آن را نیاز داریم که از سایت‌های مختلفی می‌شه دانلود کرد، بعد از دانلود کردن فایل را به فولدر /home/{NAME}/Android/Sdk/platform-tools/ منتقل می‌کنیم. سپس، با استفاده از کد زیر فیدیبو رو نصب می‌کنیم../adb install Fidibo.apk        خوب اگر همه چی درست انجام شده باشه، الان اپلیکیشن فیدیبو رو باید روی گوشی ببینید. پس از باز کردن آن و وارد شدن به حسابتون، کتابی که می‌خواهید رو خریداری کرده و وارد آن بشید. از این جا به بعد مثل قبل باید یک کدی داشته باشیم که اسکرین شات بگیره و به صفحه بعد بره. برای این کار از پکیج  pure-python-adb استفاده شد. که از آن برای وصل شدن به گوشی توسط پایتون استفاده می‌شود.from ppadb.client import Client
class fidibo:
    def __init__(self, book_name, page_num_total):
        adb = Client()
        self.device = adb.devices()[0]
        self.book_name = book_name
        self.page_num_total = page_num_total
        self.path_file = &#039;PATH_FILE/BOOK/&#039;    
    def screen_shot(self):
        for page_num in range(self.page_num_total):
            image = devices[0].screencap()
            with open(self.path_file + f&#039;{self.book_name}/{page_num}.png&#039;, &#039;wb&#039;) as f:
                f.write(image)
            self.device.shell(f&#039;input keyevent 25&#039;)        def to_pdf(self):
        pdf = FPDF()
        imagelist=[]
        for page_num in range(self.page_num_total):
            imagelist.append(Image.open(self.path_file + f&#039;{self.book_name}/{page_num}.png&#039;).convert(&#039;RGB&#039;))
        imagelist[0].save(self.path_file + f&#039;{self.book_name}/{self.book_name}.pdf&#039;,save_all=True, append_images=imagelist) 

this_book = fidibo(&#039;Radical_market&#039;).screen_shot()
this_book.to_pdf()کد بالا از ۲ تا تابع تشکیل شده،‌ یکی برای اسکرین شات گرفتن و رفتن به صفحه‌ی بعد و قسمت دوم آن هم مثل بالا برای تبدیل کردن به PDF می‌باشد. در تابع اسکرین شات برای رفتن به صفحه بعد از دکمه صدا استفاده شده است که  آن را باید در اپلیکیشن فیدیبو فعال کنید (داخل تنظیمات فونت و صفحه دنبال آن بگردید) قبل از اجرا کردن فقط فونت رو تنظیم کنید که خیلی درشت یا ریز نباشد برای خواندن در کیندل.بعد از تبدیل کردن فایل‌ها به PDF دیگه فقط باید به کیندل منتقل کنید و با خیال راحت کتابتون رو مطالعه کنید. در این مقاله، روش مطالعه کتاب‌های فیدیبو و طاقچه روی کیندل رو  توضیح دادم،‌ البته اپلیکیشن‌‌های دیگه کتاب‌خوان هم به یکی از دو روش بالا قابل استفاده است. در روش بالا همان طور که توضیح داده شد،‌کتاب باید خریداری شود و سپس آن را به کیندل منتقل می‌کنیم که حقوق ناشر را  نیز نقص نکرده باشیم، لطفا از این روش فقط استفاده شخصی کنید و کتاب‌ها رو پخش نکنید. </description>
                <category>Danial Moafi</category>
                <author>Danial Moafi</author>
                <pubDate>Wed, 01 Sep 2021 11:59:52 +0430</pubDate>
            </item>
                    <item>
                <title>آنالیز کردن اکانت های اینستاگرام (بات برای اینستاگرام)</title>
                <link>https://virgool.io/hamyar-instagram/%D8%A2%D9%86%D8%A7%D9%84%DB%8C%D8%B2-%DA%A9%D8%B1%D8%AF%D9%86-%D8%A7%DA%A9%D8%A7%D9%86%D8%AA-%D9%87%D8%A7%DB%8C-%D8%A7%DB%8C%D9%86%D8%B3%D8%AA%D8%A7%DA%AF%D8%B1%D8%A7%D9%85-%D8%A8%D8%A7%D8%AA-%D8%A8%D8%B1%D8%A7%DB%8C-%D8%A7%DB%8C%D9%86%D8%B3%D8%AA%D8%A7%DA%AF%D8%B1%D8%A7%D9%85-b6babhg7evsi</link>
                <description>ربات‌های زیادی برای اینستاگرام ساخته شده که کارهایی مثل لایک کردن، ریکوست دادن و ... انجام می‌دهد.  برای این کارها سایت‌هایی هست که خدمات رو ارائه میده هم کلی مطلب هست که چجوری برای خودتون رو بسازید. البته که کلا اینستاگرام استفاده از این ربات‌ها رو ممنوع کرده و باهاش سعی کرده مقابله‌هایی انجام بده ولی به صورت گسترده هنوز استفاده میشه. هدف این مقاله ولی یکم متفاوت‌تر از ساخت ربات برای کار‌های بالا هست.هدف اصلی اینه که بتونیم اسکریپتی با پایتون بنویسیم که اکانت‌های مختلف اینستاگرام رو آنلایز کنه. مثلا تعداد پست‌ها، تعداد لایک‌ها هر پست، روند پست گذاشتن پیج‌های مختلف و ... را آنلایز کرد. تو چند مقاله‌ای که بعدا همین جا لینکشو اضافه میکنم نتایجی که از آنلایز شرکت‌های بزرگ استارت‌آپی ایران انجام دادم رو می‌نویسم. خوب اول از همه پکیج هایی که لازم هست رو نصب کنیم. برای شروع کار نیاز به selenium برای رفتن به اکانت اینستاگرام و خارج کردن دیتا داریم و برای تحلیل کردن دیتا و جمع کردن دیتا به pandas نیاز داریم، که با استفاده از pip میتونیم هر دوی آن ها رو نصب کنیم. from selenium import webdriver
import pandas as pdپس از نصب پکیج‌ها برای کار با سلنیوم باید درایور بروزر مورد نظرتون نصب کنید. برای این مقاله از فایرفاکس استفاده شد که برای دانلود کردن درایور آن می‌تونید به اینجا برید. قدم بعدی ساختن اکانت اینستاگرام است،‌ که از این لینک می‌تونید استفاده کنید. سپس، با استفاده از تابع زیر وارد اینستاگرام می‌شوید. ( بهتر است از اکانت شخصی خودتون استفاده نکنید)def login_instagram(username, password):
    driver = webdriver.Firefox() 
    driver.get(&amp;quothttps://instagram.com&amp;quot)
    time.sleep(4)
    driver.find_element_by_xpath(&amp;quot//input[@name=\&amp;quotusername\&amp;quot]&amp;quot).send_keys(username) 
    driver.find_element_by_xpath(&amp;quot//input[@name=\&amp;quotpassword\&amp;quot]&amp;quot).send_keys(password)
    driver.find_element_by_xpath(&#039;//button[@type=&amp;quotsubmit&amp;quot]&#039;).click()
    time.sleep(10)
    driver.find_element_by_xpath(&amp;quot//button[contains(text(), &#039;Not Now&#039;)]&amp;quot).click()
    return driver

driver = login_instagram(username, passrword)در تابع ۲ قسمت  اسلیپ اسلیپ وجود دارد که برای لود شدن کامل صفحه استفاده شده‌است. اگر سرعت اینترنتون پایین تر بود این تایم‌ها رو می‌توانید بیشتر کنید، البته کار‌های بهتری هم می‌شد انجام داد که مطمئن بشیم صفحه کامل لود شده باشد ولی پیچیدگی کار رو بیشتر می‌کرد.در ادامه با استفاده از کلاسی که تعریف می‌کنیم به پیج‌های مختلف می‌ریم و تعداد پست‌ها، تعداد دنبال‌کننده و تعداد دنبال‌شونده هر پیج رو بدست میاریم. بعد هم با لود کردن کل پست‌ها لینک هر پست رو بدست میاریم. در قسمت اول پارامتر هایی که لازم داریم بدست بیاریم رو تعیین می‌کنیم. برای هر پیج همان‌طور که بالا گفتیم ۴ تا پارامتر بدست میاوریم، ۳ تای آن ها عددی و یکی از آن ها دیتابیس است. num_post نشان دهنده تعداد پست‌ها، num_follwors و num_following  نشان دهنده دنبال شوندگان و دنبال کنندگان است. برای بدست آوردن این اعداد از ۳ تابع n_followrs ،n_post و n_following استفاده شده‌است. که در هر ۳ تابع برای پیدا کردن عدد از آدرس xpath استفاده شده‌. نمیش اینستاگرام در دو سایز صفحه
تغییر سایز صفحه‌ای که در init نیز انجام شد برای این است که نمایش پست در اندازه صفحه‌های مختلف اینستاگرام نمایش مختلفی دارد. برای این که xpath های تکرار پذیری بتوانیم استفاده کنیم گفتیم یک اندازه صفحه را به عنوان مبنا در نظر بگیریم. class anayles_post:
    def __init__(self, driver, page_name):
        self.driver = driver
        self.page_name = page_name
        self.num_posts = None
        self.num_followrs = None
        self.num_following = None
        self.data_set = pd.DataFrame(columns=[&#039;url&#039;])
        self.driver.get(f&amp;quothttps://instagram.com/{page_name}&amp;quot) # go to page
        self.driver.set_window_size(800, 500)

    def get_header_data(self, xpath):
        elemnt_find = self.driver.find_elements_by_xpath(xpath=xpath)[0]
        data_inheader = elemnt_find.get_attribute(&amp;quottitle&amp;quot)
        if len(data_inheader) == 0:
            data_inheader = elemnt_find.text
        return int(data_inheader.replace(&#039;,&#039;,&#039;&#039;))
    def n_posts(self):
            posts_xpath = &amp;quot/html/body/div[1]/section/main/div/header/section/ul/li[1]/span/span&amp;quot
            self.num_posts = self.get_header_data(num_posts_xpath)
            return self.num_posts    def n_followrs(self):
        num_followrs_xpath = 
         &amp;quot/html/body/div[1]/section/main/div/header/section/ul/li[2]/a/span&amp;quot
        self.num_followrs = self.get_header_data(num_followrs_xpath)
        return self.num_followrs    def n_following(self):
        following_xpath =  &amp;quot/html/body/div[1]/section/main/div/header/section/ul/li[3]/a/span&amp;quot
        self.num_following = self.get_header_data(num_following_xpath)
        return self.num_following    def url_all_posts(self):
        page_height = 0
        self.driver.execute_script(f&amp;quotwindow.scrollTo(0, {page_height})&amp;quot)
        if self.n_posts() &gt; 0:         # Check hilight
            xpath = &#039;/html/body/div[1]/section/main/div/div[3]/article/div[1]/div/div/div&#039;
            list_post = self.driver.find_elements_by_xpath(xpath=xpath)
            if len(list_post) == 0:
                xpath = &#039;/html/body/div[1]/section/main/div/div[2]/article/div[1]/div/div/div&#039;          
        while len(self.data_set) &lt; self.n_posts() :
            xpath = xpath
            list_post = self.driver.find_elements_by_xpath(xpath=xpath)
            for this_post in list_post:
                herf_this_post = this_post.find_elements_by_xpath(&#039;a&#039;)
                if len(herf_this_post) &gt; 0:
                    herf_this_post = herf_this_post[0].get_attribute(&#039;href&#039;)
                    check_this_link = self.data_set[self.data_set[&#039;url&#039;] == herf_this_post]
                    if check_this_link.empty:
                        self.data_set = self.data_set.append(pd.DataFrame(data={&#039;url&#039;:[herf_this_post]}))
            page_height += 1000
            self.driver.execute_script(f&amp;quotwindow.scrollTo(0, {page_height})&amp;quot)
            time.sleep(1)
        self.data_set.reset_index(inplace=True)
        return self.data_set
در ادامه کد تابع url_all_posts لینک تمامی پست‌های گذاشته شده رو به یک دیتابیس اضافه می‌کند، برای این کار نیاز داریم صفحه رو اسکرول کنیم به سمت پایین تا پست‌های قدیمی‌تر لود شوند. هر بار که صفحه لود می‌شود قسمتی از پست‌های قبلی هم باقی می‌ماند برای همین چک می‌کنیم که لینک تکراری در دیتابیس نریخته باشیم. برای اجرای تابع‌های بالا نیاز به اجرای آن‌ها است.username = &amp;quotYOUR_USERNAME&amp;quot
password = &amp;quotYOUR_PASSWORD&amp;quot
driver = login_instagram(username, password)
page_name = &amp;quotPAGE_NAME&amp;quot
page_instagram = anayles_post(driver=driver, page_name=page_name)
print(&#039;Number of Posts : &#039;, page_instagram.n_posts())
print(&#039;Number of Following : &#039;, page_instagram.n_following())
print(&#039;Number of Followers :&#039;, page_instagram.n_followers())
data_set_page = page_instagram.url_all_posts()که خروجی آن تعداد پست‌ها، دنبال‌کنندگان و دنبال شوندگان را می‌دهد. همین قسمت کد را می‌توان به صورت روزانه یا ساعاتی برای  پیج‌هایی که می‌خواهید دیتای آن ها را بررسی کنید اجرا کنید و خروجی را بر روی دیتابیسی بریزید. (مثلا برای قرار داد بستن با پیج اینفلوئنسر مورد نظرتون نیاز دارید نرخ افزایش دنبال‌کنندگان آن‌ها را بررسی کنید.)خوب تا اینجای کار می‌تونیم تعداد این عدد‌ها رو برای هر پیجی بدست بیاوریم، به عنوان مثال در تاریخ ۲۷ مرداد ۱۴۰۰ برای صفحه digikala.life این اعداد به این صورت است :پس از این که لینک همه‌ی پست‌ها رو بدست آوردیم نیاز داریم که لینک‌ها رو باز کنیم و اعدادی مثل تعداد کامنت و تاریخ اشتراک گذاری را بدست آوریم.برای این کار یک کلاس تعریف می‌کنیم که به صورت زیر است، همان طور که پیش‌بینی می‌شود این قسمت از کار برای این که نیاز هست تک‌ تک صفحات باز شود زمان‌بر است ( البته در ادامه میگیم چجوری می‌شه کل این پروسه رو سریع‌تر انجام داد.)from selenium.common import exceptions
from datetime import datetime, timedeltaclass post_analyse:
    def __init__(self, url, driver):
        self.driver = driver
        self.driver.get(f&amp;quot{url}&amp;quot)
        time.sleep(1)    def post_content(self):
        try:
            self.driver.find_element(By.TAG_NAME, &#039;video&#039;)
            content = &#039;video&#039;
        except exceptions.NoSuchElementException:
            content = &#039;photo&#039;
        return content    def post_action(self):
        page_source = self.driver.page_source 
        if &#039;views&#039; in page_source:
            action = &#039;views&#039;
        else:
            action = &#039;likes&#039;
        return action    def xpath_action(self, action):
        if action == &#039;views&#039;:
            xpath = &#039;/html/body/div[1]/section/main/div/div[1]/article/div[3]/section[2]/div/span/span&#039;
        else:
            xpath = &#039;/html/body/div[1]/section/main/div/div[1]/article/div[3]/section[2]/div/div/a/span&#039;
        return xpath        def post_time(self):
        xpath_date = &#039;/html/body/div[1]/section/main/div/div[1]/article/div[3]/div[2]/a/time&#039;
        time_posted = self.driver.find_elements_by_xpath(xpath=xpath_date)[0].text
        if &#039;AGO&#039; in time_posted:
            if &#039;DAYS&#039; in time_posted:
                days_ago = int(time_posted.split(&#039; &#039;)[0])
                time_posted = datetime.now().date() - timedelta(days=days_ago)
            else:
                # else means (x hours ago, x seconds ago, ...)
                time_posted = datetime.now()
        else:
            try:
                time_posted = datetime.strptime(time_posted, &#039;%B %d, %Y&#039;).date()
            except ValueError:
                time_posted = datetime.strptime(time_posted, &#039;%B %d&#039;).date()
                time_posted = time_posted.replace(year=datetime.now().year)
        return time_posted        def post_action_count(self, action):
        self.driver.set_window_size(1000, 500)
        xpath = self.xpath_action(action)
        n_action = self.driver.find_elements_by_xpath(xpath=xpath)
        if len(n_action) &gt; 0:
            n_action = int(n_action[0].text.replace(&#039;,&#039;,&#039;&#039;))
        else:
            n_action = 0
        return n_action    خوب اول از همه بررسی می‌کنیم که پست گذاشته شده دارای چه محتوایی است (ویدیو یا تصویر). این کار رو با تابع post_content انجام‌ می‌دهیم. روش کار هم به این صورت است که  سورس کد صفحه باز شده دارای المنت video است یا خیر. در تابع بعدی اکشنی که انجام شده‌است را پیدا می‌کنیم. معمولا برای پست‌های تصویر تعداد لایک‌های زده شده گزارش می‌شود و برای فیلم‌ها تعداد دیده شدن ( البته برای فیلم‌هایی که در چند صفحه گذاشته می‌شوند تعداد لایک‌ها زده می‌شود). برای پیدا کردن اکشن انجام شده از تابع post_action  استفاده می‌کنیم. مانند تابع قبلی در سورس کد دنبال آن می‌گردیم. تابع بعدی xpath_action است که برای بدست آوردن xpath محلی که تعداد لایک یا ویوو زده شده است تعریف کردیم، که در  post_action_count  استفاده شده‌. یک تابع هم برای بدست آوردن تایم گذاشتن پست تعریف کردیم (post_time) که ۲ قسمت بودن آن به دلیل نمایش تاریخ زیر پست‌ها می‌باشد. اگر پست در ۷ روز اخیر گذاشته شده باشد به صورت DAYS AGO زده می‌شود و اگر قدیمی‌تر باشد تاریخ آن را می‌زند. برای این که همه‌ی فرمت‌ها به یک شکل شود همه را به صورت yyyy-mm-dd تبدیل کردیم. قسمت بعدی لازمه دیتابیس url ها رو توی یک لوپ قرار بدیم که برای هر پست این دیتا‌ها رو بدست بیاوریم. برای قرار دادن پانداس داخل لوپ از روش‌های مختلفی میشه  استفاده کرد ( یه مقاله خیلی خوب اینجاست) ولی از اون‌جایی که تعداد پست‌های هر پیج عدد خیلی زیادی نیست از یک for  استفاده می‌کنیم. data_set_page = pd.concat([data_set_page,pd.DataFrame(columns=[&#039;content&#039;, &#039;action&#039;, &#039;num_action&#039;, &#039;time&#039;])])
for this_num_post in range(len(data_set_page)):
    this_post = post_analyse(data_set_page[&#039;url&#039;][this_num_post], driver)
    data_set_page[&#039;content&#039;][this_num_post] = this_post.post_content()
    data_set_page[&#039;action&#039;][this_num_post] = this_post.post_action()
    data_set_page[&#039;num_action&#039;] = this_post.post_action_count(data_set_page[&#039;action&#039;][this_num_post])
    data_set_page[&#039;time&#039;] = this_post.post_time()برای همون صفحه digikala.life که بالا بررسی کرده‌بودیم به این صورت است. این مرحله از کار همونجوری که گفتیم زمان‌بر ترین بخش است، برای این که سریع‌تر انجام بدیم می‌تونیم تنظیمات driver را به گونه‌ای تنظیم کنیم که عکس‌ها و ویدیو‌ها لود نشود. (البته میتوان به صورت کلی headless هم اجرا کرد driver را) برای این کار این قسمت کد را به تابع login_instagram اضافه می‌کنیم.firefox_profile = webdriver.FirefoxProfile&#40;&#41;
firefox_profile.set_preference(&#039;permissions.default.image&#039;, 2)
firefox_profile.set_preference(&#039;dom.ipc.plugins.enabled.libflashplayer.so&#039;, &#039;false&#039;)    firefox_profile.set_preference(&#039;media.mp4.enabled&#039;, False)    
driver = webdriver.Firefox(firefox_profile=firefox_profile)خوب چند تا پارامتر را به عنوان مثال تحلیل کنیم : نسبت تعداد محتوای منتشر شده به صورت فیلم یا عکس:تعداد لایک‌ها یا وییو‌ها برای پست‌ها:برای پست‌های عکسیبرای پست‌های فیلم4 پستی که بیشترین تعداد لایک را داشتند:۲ تا از محبوب ترین پست‌های گذاشته شده در مورد کار بانوان است.محبوب ترین پست‌هاتعداد پست‌های گذاشته شده در سال‌ها:تعداد پست‌ها در سالخوب مختصر استفاده‌ای که می‌شد از این قسمت انجام داد را با چند مثال توضیح دادیم، در مقاله بعدی ادامه‌ی دیتاهایی که می‌توانیم بدست بیاریم رو می‌بینیم ( مثل تعداد کامنت‌های گذاشته شده، هشتگ‌های زده شده، بار مثبت‌ یا منفی کامنت‌ها و ...). بعد از این که دیتا‌ها تکمیل شد به سراغ بررسی اینستاگرام چند شرکت بزرگ میریم. </description>
                <category>Danial Moafi</category>
                <author>Danial Moafi</author>
                <pubDate>Sat, 21 Aug 2021 10:42:27 +0430</pubDate>
            </item>
                    <item>
                <title>درست کردن ربات اسکایپ برای اتومات کردن کارها</title>
                <link>https://virgool.io/@danialmoafi/%D8%AF%D8%B1%D8%B3%D8%AA-%DA%A9%D8%B1%D8%AF%D9%86-%D8%A8%D8%A7%D8%AA-%D8%A7%D8%B3%DA%A9%D8%A7%DB%8C%D9%BE-%D8%A8%D8%B1%D8%A7%DB%8C-%DA%86%D9%86%D8%AF-%D8%AA%D8%A7-%DA%A9%D8%A7%D8%B1-%DA%A9%D9%88%DA%86%DA%A9-p7suw6xrariw</link>
                <description>  هدفمون تو این مقاله اینه که ببینیم یک بات چجوری میشه با استفاده از پایتون برای اسکایپ ساخت که یک سری کارامون رو اتومات انجام بده (مثل فرستادن گزارش روزانه و ... ) برای اپلیکیشن‌های دیگه هم به زودی مینویسم. اول از همه این که اگر تو کشور ایران نبودیم میتونستیم از Azure یک ماشین گرفت و اونجا خیلی راحت می‌تونستیم بات رو بسازیم. اما به دلیل محدودیت‌هایی که همیشه داریم محبوریم بریم خودمون کار‌ها رو انجام بدیم. پس کلا اگر می‌تونید و براتون میصرفه خیلی بهتره که با استفاده از Azure بات رو ساخت که کلی امکانات بیشتری دارد.برای شروع نیاز به پکیج Skpy داریم که می‌توانید با استفاده از pip آن را نصب کنید.pip install Skpyپس از نصب شدن نیاز هست که یک اکانت اسکایپ داشته باشید، که  می‌تویند به سایت اسکایپ برید و ثبت‌نام کنید. از اونجایی که نسخه وب هم داره نیاز به نصب اپلیکشن برای ثبت‌نام نیست. خوب در قدم اول باید با استفاده از پایتون وارد اسکایپی که ساختید شوید، from skpy import Skypeuser = &#039;YOUR_USERNAME&#039;password = &#039;YOUR_PASSWORD&#039;sk = Skype(user, password)اگر user و password  را درست وارد کرده باشید برای وارد شدن به اکانتتون چند ثانیه زمان می‌برد. اگر هم اشتباه هم وارد کرده باشید بهتون error می‌ده. برای شروع نیاز است که یک گروه بسازیم و کارهایی که مد نظرمون هست را داخل آن انجام دهیم. به دلیل این که نمی‌شه تنهایی یک گروه را ساخت باید با یک اکانت دیگه این کار رو انجام داد. اگر اکانت دیگه‌ای خودتون دارید می‌توانید از آن استفاده کنید یا از اکانت کسانی که می‌خواهید  آن ها داخل گروه باشند استفاده کنید.ch = sk.chats.create([&amp;quotUSER_ID_ANOTHER_ACCOUNT&amp;quot])فقط برای اضافه کردن باید id اکانت کسی که می‌خواهید اضافه کنید  را داشته باشید که می‌توانید به اکانت  موردنظرتون بروید و قسمت Skype Name  را کپی کنید. در همین جا می‌توان داخل لیست کسانی که قرار است در گروه باشند را اضافه کنید، البته راه راحت‌تر این است که با استفاده از اپلیکیشن (یا وب اپ) بقیه رو به گروه اضافه کنید.  اگر ch را پرینت کنید، چند تا دیتا نشان می‌دهد که یکی از آن‌ها id چت است که از آن برای رفتن داخل آن چت نیاز داریم، بقیه دیتا ها افراد در گروه، ادمین‌ها  و ... را نشان می‌دهد. chat_id = ch.idهمچنین، اگر بات رو می‌خواهید به یکی از گروه‌هایی که دارید اضافه کنید نیاز به id آن چت دارید که با استفاده از کد زیر می‌توانید چت‌های اخیری که در اسکایپتان وجود را ببندید و با استفاده از تاپیک چت id آن را پیدا کنید. البته قبل از آن باید اکانتی که برای بات هست را به گروه اضافه کنید. sk.chats.recent()بعد این که id رو پیدا کردید نیاز دارید وارد آن بشید که با کد زیر این کار رو انجام می‌دیم:ch = sk.chats.chat(chat_id)خوب پس تا این‌جا یک گروه داریم که id آن را داریم و می‌توانیم پیام یا فایل دریافت یا ارسال کنیم. کار رو به دو قسمت تقسیم می‌کنیم. ۱) دریافت پیام یا فایل ۲) فرستادن پیام یا فایل۱) دریافت پیام یا فایلدریافت پیام برای این که بخواهیم چت های یک گروه را ببینیم ۲ روش وجود دارد، اگر بخواهید آنالیزی روی چت های قدیمی انجام دهید و نیاز به لایو بودن ندارید. از کد زیر می‌توانید استفاده کنید:ch.getMsgs()اگر آن را پرینت کنید بهتون یک لیست از ۳۰ چت آخر نشان می‌دهد و اگر آن را داخل یک لوپ تکرار کنید تا اولین چتی که در گروه قرار دارد می‌بینید و پس از آن دیگه لیست خالی بهتون جواب می‌ده. پس اگر نیاز هست کل چت‌های یک گروه را آنالیز کنید آن را داخل یک لوپ while قرار بدید و وقتی که جواب list خالی شد break کنید.all_msg = []
while True:    this_series = ch.getMsgs()    all_msg += this_series    if len(this_series) == 0:        break اگر یکی از پیام‌ها رو بررسی کنیم چند تا دیتا داخل آن ها وجود دارد، با time می‌توانید تایمی که پیام فرستاده شده (برحسب utc)، با userID می‌توانید id کسی که پیام رو فرستاده ببینید و با content هم نوشته پیام رو می‌شه دید. (در کد زیر فرض شده‌ است که حداقل یک پیام وجود داشته باشد)all_msg[0].timeall_msg[0].userIDall_msg[0].contentدر روش بالا همان طور که گفتم برای آنالیز کردن پیام‌ها است. اما استفاده دیگه‌ای که میشه کرد اینه که اگر پیغامی داخل گروه آمد اکشنی داشته باشید ( جوابی بدید یا فایلی بفرستید) برای این کار می‌توانید از کد زیر استفاده کنید: while True:    for event in sk.getEvents():
        if (isinstance(this_event, SkypeNewMessageEvent) and                  this_event.msg.chat.id == ch.id):            return (&#039;New message received&#039;, this_event.msg)کد بالا رو تو یکه while گذاشتیم که به صورت پیوسته چک کند که پیامی آمده است یا نه، در قسمت sk.getEvents تمامی ایونت هایی که در اکانت اتفاق می‌افتد را بهتون می‌دهد ( از ایونت منظور هر اتفاقی که تو اسکایپتون می‌افته،‌ هر گروهی اگر پیام بیاد یا هر چیزه دیگه) خوب پس اول نیاز داریم که مطمئن بشیم که این ایونت که اومده پیام باشه که با isinstance(event, SkypeNewMessageEvent) چک می‌کنیم و قسمت بعدی چک می‌کنیم که پیام اومده تو گروه مد نظر ما باشه. داخل this_event.msg مثل بالا time, id, content و ... وجود دارد که می‌توانید ریکشن مورد نظرتون را برای هر پیام نشان دهید. این روش در مقایسه با روش بالا ریسپانس تایم کم‌تر و استیبل‌تر است.دریافت فایلدریافت کردن فایل هم به روش بالا می‌باشد، تنها تفاوتی که وجود دارد فایل‌های فرستاده شده به بایتس تبدیل شده است و برای هر فایلی نیاز به تبدیل کردن آن است، در مثال زیر یک فایل عکس را مشاهده می‌کنیم:from PIL import Image
import io
picture_msg = all_msg[0].fileContent
stream = io.BytesIO(picture_msg)
Image.open(stream)برای این کار از ۲ تا پکیج استفاده کردیم،‌ که یکی برای تبدیل کردن بایت هست و دیگری هم برای نمایش عکس می‌باشد. با استفاده از getMsgs که در بالا توضیح داده‌شد پیام ها رو گرفته و فرض شده که اولین پیام که وجود دارد عکس است (تایپ آن SkypeImageMsg) که با استفاده از fileContent محتوای آن فایل رو ‌می‌خونیم و بعد آن را به عکس تبدیل می‌کنیم.اگر فایل دریافت شده csv باشد، می‌توانیم از کد زیر استفاده کنیمimport pandas as pd
csv_msg = all_msg[0].fileContent)
data = io.BytesIO(csv_msg)
pd.read_csv(data)به همین ترتیب تمامی فایل‌هایی که فرستاده می‌شود را می‌توانیم باز کنیم و بررسی کنیم.۲) فرستادن پیام یا فایلدر این قسمت می‌خواهیم نحوه فرستادن پیام یا یک فایلی مثل عکس یا اکسل رو ببینیم.فرستادن پیام  برای فرستادن یک پیام می‌توان از کد زیر استفاده کرد:ch.sendMsg(&#039;ِSend text massege&#039;)فرستادن فایلبرای فرستادن فایل‌ها می‌توان از sendFile استفاده کرد که در آن انواع فایل‌ها رو می‌توانیم بفرستیم، اگر بخواهیم یک عکس را به طور مثال بفرسیتم و آن عکس به صورت عکس فرستاده شود ( نه فایل، تفاوت آن این است که عکس اگر فرستاده شود یک پریویو نشان می‌دهد از عکس) به این صورت است :ch.sendFile&#40; open(path_file, &#039;rb&#039;&#41;,  &amp;quotname_file.png&amp;quot, image=True)در این مقاله پیش نیاز نوشتن یک بات رو توضیح دادم و کلی کار میشه رو این اجرا کرد از بررسی پیام‌‌های آمده در گروه‌های مختلف تا فرستادن فایل و عکس به صورت روزانه و فرستادن دیتا یا فایلی در ازای هر پیام. اگر به gitHub این پکیج برید کلی کار دیگه هم می‌توان به باتی که مینویسید اضافه کرد. </description>
                <category>Danial Moafi</category>
                <author>Danial Moafi</author>
                <pubDate>Wed, 04 Aug 2021 12:53:51 +0430</pubDate>
            </item>
            </channel>
</rss>