تطوير virtual assistant باستخدام python لااتمتة المهام

تطوير Virtual Assistant باستخدام Python لااتمتة المهام

سنقوم في هذا التمرين بتتطوير virtual assistant RAFO ب Python. يمكن أن يساعدك على أتمتة مهامك ، مثل البحث عن مقاطع الفيديو في YouTube وتشغيلها ، وإرسال رسائل البريد الإلكتروني ، وفتح مواقع الويب ، ومواد البحث في ويكيبيديا وقراءتها ، و توقعات الطقس ، والتحية والمزيد. من خلال تتطوير المساعد ، ستزيد من معرفتك ببايثون وتتعلم العديد من المكتبات / الأدوات المفيدة. سأقوم برفع الكود إلى مستودع github الخاص بي ، لذا لا تتردد في المساهمة وتحسين وظائفه

لنبدأ بإنشاء بيئة افتراضية وبناء نظام الصوت الأساسي لنظام RAFO.

mkdir RAFO cd RAFO virtualenv venv

لتفعيل البيئة الافتراضية قم بتشغيل الامر ادناه

. venv/bin/activate

بمجرد تنشيط venv ، نحتاج إلى تثبيت المكتبات الرئيسية باتباع الأوامر التالية:

pip3 install gTTS pip3 install SpeechRecognition pip3 install PyAudio pip3 install pygame
(gTTS (Google Text-to-Speech

ال gTTS هي مكتبة Python وأداة CLI للتفاعل مع API تحويل النص إلى كلام من Google Translate. تساعد هذه الوحدة في تحويل نص السلسلة إلى نص منطوق ويمكن حفظه بتنسيق mp3

SpeechRecognition

تعد Speech Recognition ميزة مهمة في العديد من التطبيقات المستخدمة مثل التشغيل الآلي للمنزل ، والذكاء الاصطناعي ، وما إلى ذلك. Speech Recognition يحتاج إلى إدخال صوتي ، وتسهل SpeechRecognition حقًا استرداد هذا الإدخال. بدلاً من إنشاء نصوص برمجية من نقطة الصفر للوصول إلى الميكروفونات ومعالجة ملفات الصوت ، سوف تجعلك SpeechRecognition جاهز للعمل في بضع دقائق فقط.

للوصول إلى الميكروفون باستخدام SpeechRecognizer ، سيتعين عليك تثبيت حزمة PyAudio

Pygame

مكتبة Pygame عبارة عن مجموعة من الأنظمة الأساسية من وحدات Python المصممة لكتابة ألعاب الفيديو. ويشمل رسومات الكمبيوتر والمكتبات الصوتية المصممة لاستخدامها مع لغة برمجة بيثون.

الآن ، لنقم ببناء نظام صوتي

from gtts import gTTS import speech_recognition as sr from pygame import mixer def talk(audio): print(audio) for line in audio.splitlines(): text_to_speech = gTTS(text=audio, lang='en-uk') text_to_speech.save('audio.mp3') mixer.init() mixer.music.load("audio.mp3") mixer.music.play()
Code language: JavaScript (javascript)

كما ترون نحن نمرر الصوت كargument للسماح لـRAFO بالتحدث. على سبيل المثال ، سيتحدث برنامج

talk('Hey I am RAF! How can I help you?')
Code language: JavaScript (javascript)

البرنامج سيقوم بتكرار هذه الاسطر بمساعدة الدالة Splitlines (). يتم استخدام هذه الدالة لتقسيم السلسلة النصية إلى قائمة من الأسطر . تحقق من Splitlines () للمزيد. بعد ذلك ، ستتعامل gTTS مع تحويل كل هذه النصوص إلى كلام. يحدد parameter النص النص المراد قراءته ، وتعرف lang اللغة (علامة لغة IETF) لقراءة النص بها. بمجرد الانتهاء من الحلقة ، تقوم الدالة save() بكتابة النتيجة إلى الملف.

الpygame.mixer عبارة عن وحدة لتحميل الأصوات وتشغيلها ويجب تهيئتها قبل استخدامها.حسنا! الآن ، دعنا ننشئ وظيفة تستمع للأوامر.

def myCommand(): #Initialize the recognizer r = sr.Recognizer() with sr.Microphone() as source: print('RAFO is Ready...') r.pause_threshold = 1 #wait for a second to let the recognizer adjust the #energy threshold based on the surrounding noise level r.adjust_for_ambient_noise(source, duration=1) #listens for the user's input audio = r.listen(source) try: command = r.recognize_google(audio).lower() print('You said: ' + command + 'n') #loop back to continue to listen for commands if unrecognizable speech is received except sr.UnknownValueError: print('Your last command could not be heard') command = myCommand(); return command
Code language: PHP (php)

في هذه الدالة نستخدم مكتبة SpeechRecognition. يعمل كمجمّع للعديد من speech APIs الشائعة وبالتالي فهو مرن للغاية.

واحد من هذه — Google Web Speech API — يدعم API key الافتراضي الذي تم ترميزه بشكل ثابت في مكتبة SpeechRecognition. هذا يعني أنه يمكنك استخدامه دون الحاجة إلى الاشتراك في الخدمة.

لتتمكن من العمل بصوتك مع SpeechRecognition ، تحتاج إلى حزمة PyAudio. مثل أداة التعرف على الملفات الصوتية ، سنحتاج إلى ميكروفون لبيانات الكلام في الوقت الفعلي.

يمكنك التقاط الإدخال من الميكروفون باستخدام الدالة listen() لفئة أداة التعرف داخل الكتلة.

تأخذ هذه الدالة مصدرًا صوتيًا كأول وسيطة لها وتسجل الإدخال من المصدر حتى يتم التوقف عن الكلام.

حاول أن تقول أوامرك في مكان صامت (بدون ضوضاء ) وإلا يمكن أن تشوش RAFO .

ألق نظرة على https://realpython.com/python-speech-recognition/

import random def rafo(command): errors=[ "I don't know what you mean!", "Excuse me?", "Can you repeat it please?", ] if 'Hello' in command: talk('Hello! I am RAFO. How can I help you?') else: error = random.choice(errors) talk(error) talk('RAFO is ready!') while True: assistant(myCommand())
Code language: PHP (php)

بمجرد تشغيل البرنامج ، سيبدأ RAFO في التحدث معك بقول “RAFO is ready!” ويستمر في الاستماع إلى أوامرك حتى توقف البرنامج. ابدأ بقول “Hello” :)عندما لم يحصل RAFO على الأمر ، سنتعامل مع الخطأ من خلال جمل عشوائية.

هنا الكود الكامل للهيكل الرئيسي:
from gtts import gTTS import speech_recognition as sr from pygame import mixer import random def talk(audio): print(audio) for line in audio.splitlines(): text_to_speech = gTTS(text=audio, lang='en-uk') text_to_speech.save('audio.mp3') mixer.init() mixer.music.load("audio.mp3") mixer.music.play() def myCommand(): #Initialize the recognizer #The primary purpose of a Recognizer instance is, of course, to recognize speech. r = sr.Recognizer() with sr.Microphone() as source: print('RAFO is Ready...') r.pause_threshold = 2 #wait for a second to let the recognizer adjust the #energy threshold based on the surrounding noise level r.adjust_for_ambient_noise(source, duration=1) #listens for the user's input audio = r.listen(source) try: command = r.recognize_google(audio).lower() print('You said: ' + command + 'n') #loop back to continue to listen for commands if unrecognizable speech is received except sr.UnknownValueError: print('Your last command could not be heard') command = myCommand(); return command def rafo(command): errors=[ "I don't know what you mean", "Did you mean astronaut?", "Can you repeat it please?", ] if 'hello' in command: talk('Hello! I am RAFO. How can I help you?') else: error = random.choice(errors) talk(error) talk('RAFO is ready!') #loop to continue executing multiple commands while True: rafo(myCommand())
Code language: PHP (php)

حسنًا .. هل الذكاء الاصطناعي ليس أكثر من مجرد عبارات IF؟

إذا كنت تتحدث عن الذكاء الاصطناعي (AL) “الحقيقي” ، فبالتأكيد إنه أكثر بكثير من مجرد عبارات If. تم تقسيم تطور الذكاء الاصطناعي تاريخياً إلى مجالين ؛ symbolic AI, و machine learning.

الذكاء الاصطناعي (symbolic AI) هو المجال الذي تم فيه تصميم الأنظمة الذكية بشكل مصطنع بمنطق من نوع آخر. سيحاول المبرمجون تحديد كل سيناريو ممكن للنظام للتعامل معه. حتى أواخر السبعينيات ، كان هذا هو الشكل السائد لتطوير نظام الذكاء الاصطناعي. جادل الخبراء في هذا المجال بقوة بأن machine learning لن يستمر أبدًا وأن الذكاء الاصطناعي يمكن كتابته بهذه الطريقة فقط.

نحن نعلم الآن أن المحاسبة عن كل سيناريو ممكن في نظام ذكي أمر غير عملي إلى حد كبير ونستخدم machine learning بدلاً من ذلك.

يستخدم machine learning إحصائيات للبحث عن الأنماط في البيانات وتحديدها حتى يتمكن الجهاز من التعرف على المهام التي صُممت لأدائها وتحسينها. هذا أكثر مرونة بكثير.نحن نستخدم مجموعة من عبارات IF لفهم أساسيات الذكاء الاصطناعي. لكننا سننفذ بعض خوارزميات ML الرائعة لاحقًا.

آمل أن تكون قد تعلمت أشياء جديدة حتى الآن ، حان الوقت لتعليم RAFO كيفية أتمتة الأشياء.

Open Google and search for something

سنقوم باستيراد webbrowser module في Python التي توفر واجهة لعرض المستندات المستندة إلى الويب.بينما نقول أوامر ، يجب على RAFO اكتشاف مدى توفر هذه الأوامر من خلال مطابقتها. تحتوي Python على حزمة مدمجة تسمى re ، والتي يمكن استخدامها للعمل مع التعبيرات العادية.

import re import webbrowser if 'open google' in command: #matching command to check it is available reg_ex = re.search('open google (.*)', command) url = 'https://www.google.com/' if reg_ex: subgoogle = reg_ex.group(1) url = url + 'r/' + subreddit webbrowser.open(url) print('Done!')
Code language: PHP (php)

تأخذ الدالة re.search () نobject تعبير عادي وسلسلة وتبحث عن هذا object داخل السلسلة. إذا كان البحث ناجحًا ، فإن الدالة search () ترجع object مطابق أو لا شيء خلاف ذلك.

لذلك ، عادةً ما يتبع البحث مباشرة عبارة if-statement لاختبار ما إذا نجح البحث

يخزن الكود reg_ex = re.search (‘open google (. *)’، command) نتيجة البحث في متغير باسم “reg_ex”. ثم تختبر if-statement المطابقة — إذا كان true ، نجح البحث وتكون اgroup() هي النص المطابق. وبخلاف ذلك ، إذا كانت المطابقة false (لا يوجد ما هو أكثر تحديدًا) ، فلن ينجح البحث ، ولا يوجد نص مطابق.

يمثل الرقم 1 بين قوسين في (reg_ex.group (1 أول مجموعة فرعية .

يمكنك تثبيت Selenium لإجراء البحث في Google بواسطة RAFO. لتثبيت السيلينيوم ، قم بتشغيل الأمر التالي:

pip3 install selenium

الSelenium WebDriver عبارة عن مجموعة من APIs مفتوحة المصدر والتي تستخدم لأتمتة اختبار تطبيقات الويب. تُستخدم هذه الأداة لأتمتة اختبار تطبيق الويب للتحقق من أنها تعمل كما هو متوقع. وتدعم العديد من المتصفحات مثل Safari و Firefox و IE و Chrome.

يمكنك البحث عن كيفية استخدام Selenium WebDriver مع Python ، فهناك الكثير من المصادر على الإنترنت ومن السهل تعلمها.

دعنا نضيف هذه الميزة إلى RAFO

from selenium import webdriver from selenium.webdriver.common.keys import Keys if 'open google and search' in command: reg_ex = re.search('open google and search (.*)', command) search_for = command.split("search",1)[1] url = 'https://www.google.com/' if reg_ex: subgoogle = reg_ex.group(1) url = url + 'r/' + subgoogle talk('Okay!') driver = webdriver.Firefox(executable_path='/path/to/geckodriver') #depends which web browser you are using driver.get('http://www.google.com') search = driver.find_element_by_name('q') # finds search search.send_keys(str(search_for)) #sends search keys search.send_keys(Keys.RETURN) #hits enter
Code language: PHP (php)

سوف ينظر RAFO في السلاسل بعد أمر “open google and search” ويأخذ جميع الكلمات كمفاتيح بحث. أنا أستخدم Firefox ، لذلك قمت بتثبيت geckodriver ، ولكن إذا كنت تستخدم Chrome ، فراجع سؤال StackOverflow التالي.

https://stackoverflow.com/questions/42478591/python-selenium-chrome-webdriver

Send Email

سنقوم باستيراد smtplib لإرسال رسائل البريد الإلكتروني مع Python. يرمز بروتوكول SMTP إلى بروتوكول نقل البريد البسيط وهو مفيد للتواصل مع خوادم البريد لإرسال البريد.

import smtplib elif 'email' or 'gmail' in command: talk('What is the subject?') time.sleep(3) subject = myCommand() talk('What should I say?') time.sleep(3) message = myCommand() content = 'Subject: {}nn{}'.format(subject, message) #init gmail SMTP mail = smtplib.SMTP('smtp.gmail.com', 587) #identify to server mail.ehlo() #encrypt session mail.starttls() #login mail.login('your_gmail', 'your_gmail_password') #send message mail.sendmail('FROM', 'TO', content) #end mail connection mail.close() talk('Email sent.')
Code language: PHP (php)

لاحظ أنه باختصار ، لا تسمح لك Google بتسجيل الدخول عبر smtplib لأنه وضع علامة على هذا النوع من تسجيل الدخول على أنه “أقل أمانًا” ، لذا ما عليك فعله هو الانتقال إلى هذا الرابط أثناء تسجيل الدخول إلى حساب جوجل ، والسماح بالوصول.

تفعيل

أما زلت لا تعمل؟ تحقق من سؤال StackOverflow هذا

https://stackoverflow.com/questions/16512592/login-credentials-not-working-with-gmail-smtp

Crawl Data

نحن نقوم بعمل رائع حتى الآن! يمكن لـ RAFO إرسال رسائل البريد والبحث عما تريد على جوجل. الآن ، دعنا ننفذ وظيفة أكثر تعقيدًا لجعل RAFO يزحف إلى بعض بيانات ويكيبيديا ويقرأها لنا.

الBeautiful Soup هي مكتبة Python لسحب البيانات من ملفات HTML و XML. يعمل مع المحلل اللغوي المفضل لديك لتوفير طرق اصطلاحية للتنقل والبحث وتعديل parse tree. عادة ما يوفر ساعات أو أيام عمل للمبرمجين.

شغّل الأمر التالي في جهازك الطرفي لتثبيت beautifulsoup:

pip install beautifulsoup4

سنحتاج أيضًا إلى مكتبة requests لإجراء طلبات HTTP في Python. يلخص تعقيدات عمل الطلبات من خلال API بسيط بحيث يمكنك التركيز على التفاعل مع الخدمات واستهلاك البيانات في تطبيقك. حسنا! دعنا نرى الكود:

import bs4 import requests elif 'wikipedia' in command: reg_ex = re.search('search in wikipedia (.+)', command) if reg_ex: query = command.split() response = requests.get("https://en.wikipedia.org/wiki/" + query[3]) if response is not None: html = bs4.BeautifulSoup(response.text, 'html.parser') title = html.select("#firstHeading")[0].text paragraphs = html.select("p") for para in paragraphs: print (para.text) intro = 'n'.join([ para.text for para in paragraphs[0:5]]) print (intro) mp3name = 'speech.mp3' language = 'en' myobj = gTTS(text=intro, lang=language, slow=False) myobj.save(mp3name) mixer.init() mixer.music.load("speech.mp3") mixer.music.play() elif 'stop' in command: mixer.music.stop()
Code language: PHP (php)

ا”search in wikipedia python” و RAFO سيأخذ “python” ككلمة رئيسية للبحث في ويكيبيديا. إذا بحثت عن شيء ما على Wikipedia ، فسترى عنوان URL سيبدو مثل https://en.wikipedia.org/wiki/Keyword ، لذلك نرسل طلب الحصول على كلمة رئيسية (ما الذي يجب البحث عنه) للوصول إلى البيانات. بمجرد نجاح الطلب ، ستقوم beautifulsoup بتحليل المحتوى داخل ويكيبيديا. الدالة join () هي دالة لسلاسل وتعيد سلسلة تم ضم فيها عناصر التسلسل بواسطة فاصل str ونستخدمها لفصل الفقرات.

أنت على دراية بـ gTTS وmixer ، لذا فأنا ساتخطى هذا الجزء.

سيعرض RAFO البيانات التي يتم الزحف إليها على console ويبدأ في قراءتها لك.

Search videos on YouTube and play

تشبه هذه الوظيفة Open Google and search ولكن هذه المرة من الأفضل استخدام urllib. الهدف الرئيسي هو تعلم أشياء جديدة باستخدام Python ، لذلك لا أريد تضمين السيلينيوم في هذه الوظيفة. هذا هو الكود:

import urllib.request #used to make requests import urllib.parse #used to parse values into the url elif 'youtube' in command: talk('Ok!') reg_ex = re.search('youtube (.+)', command) if reg_ex: domain = command.split("youtube",1)[1] query_string = urllib.parse.urlencode({"search_query" : domain}) html_content = urllib.request.urlopen("http://www.youtube.com/results?" + query_string) search_results = re.findall(r'href="/watch?v=(.{11})', html_content.read().decode()) # finds all links in search result webbrowser.open("http://www.youtube.com/watch?v={}".format(search_results[0])) pass
Code language: PHP (php)

تتيح لك وحدة urllib في Python 3 الوصول إلى مواقع الويب عبر برنامجك. urllib في Python 3 يختلف قليلاً عن urllib2 في Python 2 ، لكنها في الغالب هي نفسها. من خلال urllib ، يمكنك الوصول إلى مواقع الويب وتنزيل البيانات وتحليل البيانات وتعديل headers والقيام بأي طلبات GET و POST قد تحتاج إلى القيام بها.

القي نظرة على هذا البرنامج التعليمي لمزيد من المعلومات حول urllib

يجب ترميز مفتاح البحث قبل التحليل في عنوان url. إذا بحثت عن شيء ما على YouTube ، يمكنك رؤيته بعد http://www.youtube.com/results؟ “، فهناك مفاتيح بحث مشفرة.بمجرد ترميز مفاتيح البحث هذه يمكن للبرنامج الوصول بنجاح إلى نتائج البحث.

يعيد التعبير re.findall() جميع التطابقات غير المتداخلة للأنماط في سلسلة كقائمة من السلاسل

يحتوي كل مقطع فيديو على youtube على معرف مكون من 11 حرفًا (https://www.youtube.com/watch؟v=gEPmA3USJdI) و re.findall () سيجد جميع التطابقات في html_content الذي تم فك ترميزه (في صفحة نتائج البحث). يتم استخدام decode()للتحويل من جزء واحد إلى مخطط الترميز ، حيث يتم ترميز سلسلة الوسيطة إلى نظام الترميز المطلوب. يعمل هذا عكس التشفير. يقبل ترميز سلسلة الترميز لفك تشفيرها وإرجاع السلسلة الأصلية.

أخيرًا ، يتم تشغيل الفيديو الأول في نتائج البحث لأنه عادةً ما يكون الفيديو الأول هو الأقرب لمفاتيح البحث.

الكود كامل
from gtts import gTTS import speech_recognition as sr import re import time import webbrowser import random from selenium import webdriver from selenium.webdriver.common.keys import Keys import smtplib import requests from pygame import mixer import urllib.request import urllib.parse import bs4 def talk(audio): "speaks audio passed as argument" print(audio) for line in audio.splitlines(): text_to_speech = gTTS(text=audio, lang='en-uk') text_to_speech.save('audio.mp3') mixer.init() mixer.music.load("audio.mp3") mixer.music.play() def myCommand(): "listens for commands" #Initialize the recognizer #The primary purpose of a Recognizer instance is, of course, to recognize speech. r = sr.Recognizer() with sr.Microphone() as source: print('RAFO is Ready...') r.pause_threshold = 1 #wait for a second to let the recognizer adjust the #energy threshold based on the surrounding noise level r.adjust_for_ambient_noise(source, duration=1) #listens for the user's input audio = r.listen(source) print('analyzing...') try: command = r.recognize_google(audio).lower() print('You said: ' + command + 'n') time.sleep(2) #loop back to continue to listen for commands if unrecognizable speech is received except sr.UnknownValueError: print('Your last command couldn't be heard') command = myCommand(); return command def rafo(command): errors=[ "I don't know what you mean", "Excuse me?", "Can you repeat it please?", ] "if statements for executing commands" # Search on Google if 'open google and search' in command: reg_ex = re.search('open google and search (.*)', command) search_for = command.split("search",1)[1] print(search_for) url = 'https://www.google.com/' if reg_ex: subgoogle = reg_ex.group(1) url = url + 'r/' + subgoogle talk('Okay!') driver = webdriver.Firefox(executable_path='/home/ubai/Desktop/geckodriver') driver.get('http://www.google.com') search = driver.find_element_by_name('q') search.send_keys(str(search_for)) search.send_keys(Keys.RETURN) # hit return after you enter search text #Send Email elif 'email' in command: talk('What is the subject?') time.sleep(3) subject = myCommand() talk('What should I say?') message = myCommand() content = 'Subject: {}nn{}'.format(subject, message) #init gmail SMTP mail = smtplib.SMTP('smtp.gmail.com', 587) #identify to server mail.ehlo() #encrypt session mail.starttls() #login mail.login('your_mail', 'your_mail_password') #send message mail.sendmail('FROM', 'TO', content) #end mail connection mail.close() talk('Email sent.') # search in wikipedia (e.g. Can you search in wikipedia apples) elif 'wikipedia' in command: reg_ex = re.search('wikipedia (.+)', command) if reg_ex: query = command.split("wikipedia",1)[1] response = requests.get("https://en.wikipedia.org/wiki/" + query) if response is not None: html = bs4.BeautifulSoup(response.text, 'html.parser') title = html.select("#firstHeading")[0].text paragraphs = html.select("p") for para in paragraphs: print (para.text) intro = 'n'.join([ para.text for para in paragraphs[0:3]]) print (intro) mp3name = 'speech.mp3' language = 'en' myobj = gTTS(text=intro, lang=language, slow=False) myobj.save(mp3name) mixer.init() mixer.music.load("speech.mp3") mixer.music.play() elif 'stop' in command: mixer.music.stop() # Search videos on Youtube and play (e.g. Search in youtube believer) elif 'youtube' in command: talk('Ok!') reg_ex = re.search('youtube (.+)', command) if reg_ex: domain = command.split("youtube",1)[1] query_string = urllib.parse.urlencode({"search_query" : domain}) html_content = urllib.request.urlopen("http://www.youtube.com/results?" + query_string) search_results = re.findall(r'href="/watch?v=(.{11})', html_content.read().decode()) #print("http://www.youtube.com/watch?v=" + search_results[0]) webbrowser.open("http://www.youtube.com/watch?v={}".format(search_results[0])) pass elif 'hello' in command: talk('Hello! I am RAFO. How can I help you?') time.sleep(3) elif 'who are you' in command: talk('I am rafo your assistant') time.sleep(3) else: error = random.choice(errors) talk(error) time.sleep(3) talk('RAFO activated!') #loop to continue executing multiple commands while True: time.sleep(4) rafo(myCommand())
Code language: PHP (php)

رائع! لقد أنشأنا للتو RAFO التجريبي ، وآمل أن تكون قد تعلمت أشياء كثيرة من هذا التمرين. لا تتردد في المساهمة في هذا المشروع على GitHub ، ستنتظر التحسينات.

الكتاب الذين اعجبو بهذا المقال

مقالات مشابهة