A. Faruk

learn –recursive –force <something>

General

Python ile Telegram Bot

Bu yazıda Python dilini kullanarak Telegram Bot yazacağız. Teknik bölüme geçmeden önce kavramları inceleyelim.

Telegram : Telegram, çoklu platform desteği sunan bir anlık mesajlaşma servisidir. Telegram istemcileri hem mobil (Android, iOS, Windows Phone, Ubuntu Touch) hem de masaüstü sistemleri (Windows, OS X, Linux) için mevcuttur.[1]

Bot: Bilişim dünyasında “robot” anlamında kullanılan yaygın bir terimdir. Pek çok bilgisayar işlemini yarı-otomatik olarak yapabilen robotlar bilişimin tüm alanlarında kullanılır.[2]

Kavramlardan temel olarak bahsettik, şimdi yapacağımız uygulama hakkında konuşalım:

AMAÇ: Telefonumuza düzenli aralıklarla istediğimiz dinamik verileri mesaj atmak. Örn: Her gün hava durumunu mesaj olarak almak, her hafta okul sayfasındaki duyuruları mesaj olarak almak vs.

GEREKSİNİMLER: Python 3.x, BeatifulSoup 4, Telegram hesabı ve temel python bilgisi(paket kurulumu dahil).

Kodun tamamı: GİTHUB


Vereceğim örnekte, “http://guzelsozlerblog.com/gunun-sozu” sayfasından konulara göre günün sözlerini sırayla çekip bu sözleri telegram üzerinden telefonuma mesaj olarak göndereceğim. Elimden geldiğince en açık şekilde ve adım adım anlatmaya çalışacağım, bu sebeple yazı uzun olabilir. Uzun yazıyı görüp motivasyonunuzu kaybetmeyin hemen, yüzeysel olarak göz attığınızda kolay olduğunu siz de göreceksiniz.

Adım 1: Boş bir python dosyası açalım (Örn: sozBotu.py). İlk önce veri çekmek istediğimiz web sitesine erişelim ve sayfanın tamamını elde etmeye çalışalım. Bunun için requests kütüphanesini kullanacağız.

import requests #requests kütühanemizi dahil ettik
url="http://guzelsozlerblog.com/gunun-sozu" #web sayfası URL sini atadık
response=requests.get(url) #kütüphane yardımıyla web sayfasına gittik
print(response.text) #web sayfasının çıktısını yazdırdık

Çıktı aşağıdaki görüntüye benzeyecektir.

bvnndm

Adım 2: Elde ettiğimiz web sayfası çıktısından almak istediğimiz kısımları filtreleyeceğiz. Benim örneğimde almak istediği bilgiler “div id=”PageContent” etiketlerinin arasındaydı. Bu sebeple sadece bu etiketler ve içerikleri lazım. Bu filtrelemeyi yapmak için BeatifulSoup kütüphanesinden faydalanıyoruz. Bu kısımda dönen verinin bir dizi olduğunu göreceğiz.

import requests
from bs4 import BeautifulSoup
url="http://guzelsozlerblog.com/gunun-sozu"
response=requests.get(url)
print(response.text)
AnalizEdilecekIcerik=response.text #Sayfadan gelen HTML kodunu atadık
icerigiAl=BeautifulSoup(AnalizEdilecekIcerik,"lxml") #BS4 HTML kodunu analiz ediyor
#"lxml" parametresini kütüphanenin bize verdiği uyarı gereği kullandık. Parametresiz veya diğer parametreler ile kullanabilirsiniz. Bu parametre hakkında daha fazla bilgi için--&gt; https://www.crummy.com/software/BeautifulSoup/bs4/doc/#installing-a-parser 
filtre=icerigiAl.find_all(id="PageContent") #id değeriyle filtreleme yaptık
print(filtre) #tüm filtreyi yazdırdık
print(filtre[0]) #filtreden gelen verinin sadece 0.indexine ait içeriği yazdırdık. Bu arada print fonksiyonunu gelen veriyi kontrol etmek için kullanıyorum.

Adım 3: Çektiğimiz veriyi istediğimiz şekilde yazdırmak için gerekli algoritmayı oluşturacağız.

import requests
from bs4 import BeautifulSoup
url="http://guzelsozlerblog.com/gunun-sozu"
response=requests.get(url)
<span style="color:#ff0000;">response.encoding= "iso-8859-9"</span> #Bu kod ile çektiğimiz verideki "ş,ç,i" gibi karakterlerde çıkabilecek problemleri önlüyoruz.
AnalizEdilecekIcerik=response.text
icerigiAl=BeautifulSoup(AnalizEdilecekIcerik,"lxml")
#CSS ile de filtreleyebiliriz, ben bunu tercih ediyorum.
sozler=icerigiAl.select("div#PageContent")
for i in range(0,len(sozler)): #döngüyü, aldığımız dönütün uzunluğu ile sınırlandırıyoruz.
print(sozler[i].contents[0].text +": "+sozler[i].contents[2]+"\n") #Etiket içeriklerini çekip yazdırıyoruz.

Adım 4: Şimdi, Telegram uygulamasında yapmamız gereken ayarları yapacağız.

4.1. BotFather adlı ön tanımlı ayarlama kullanıcısını çağıralım. Bunun için masaüstü bilgisayarından https://telegram.me/BotFather bağlantısını kullanabilirsiniz.

4.2. Aşağıdaki yönergeleri izleyiniz. gununSozu ve GununSozuBot gibi ifadeleri kendinize göre değiştirebilirsiniz. Bot Babamızın da dediği gibi dikkat etmeniz gereken yer: İkinci ismin “bot” ile bitmek zorunda olması. Babanın size verdiği tek satırlık token kodunu kaydedin bir yere.

m4bgep

4.3. Bu defa babaya “/mybots” komutunu verin. Botunuz – botlarınız listelenecektir. Benim daha önce bir botum olduğu için o da göründü, siz ilk defa yapıyor olduğunuz için sadece bir bot olarak listelenecektir. Botunuzu seçin.

6rbp9k

4.4. Ekran görüntüsünde işaretlenen yere tıklayarak, botun sohbet penceresine erişin.

2ndwav

4.5. “Start” butonu ile botu aktif edin. Ekran görüntüsünde gördüğünüz “Günün sözlerini her gün ileten bir bot.” yazısını BotFather üzerinden “/setdescription” komutunu kullanarak oluşturabilirsiniz.

1vba6p

2ndwoj

4.6. https://api.telegram.org/bot{token}/getMe

kullanarak bota erişim olup olmadığını kontrol edin. Buradaki {token} 4.2. de not aldığımız token kodu.

x9g8j3

4.7. Botun sohbet penceresinden bota herhangi bir mesaj atın.

x9g8g3

4.8. https://api.telegram.org/bot{0}/getupdates

kullanarak gelen verilerin json çıktısını elde edelim. Bu çıktıda bizim için önemli olan id parametresi. Bu paramtrenin değerini de not alalım. Şu an elimizde token ve id parametreleri var. Artık bu iki parametre ile botumuzu kontrol edeceğiz.

3v5wg9

Artık kodumuza devam edebiliriz.

Adım 5: Kodumuza son halini vereceğiz. Aldığımız çıktıyı bot aracılığıyla kendimize göndereceğiz. Telegramın bize sunduğu URL yapısı sayesinde mesajımızı ileteceğiz. Bu URL yapısı,

https://api.telegram.org/bot{0}/sendMessage?chat_id={1}&text={2}

import requests
from bs4 import BeautifulSoup
url="http://guzelsozlerblog.com/gunun-sozu"
response=requests.get(url)
response.encoding= "iso-8859-9"
AnalizEdilecekIcerik=response.text
icerigiAl=BeautifulSoup(AnalizEdilecekIcerik,"lxml")
sozler=icerigiAl.select("div#PageContent")
gonderilecekYazi="" #her iterasyonda aldığımız veriyi bu değişkenin üzerine ekleyeceğiz
for i in range(0,len(sozler)):
gonderilecekYazi+=sozler[i].contents[0].text +": "+sozler[i].contents[2]+"\n\n"
token = "309--441:AAG------------r6n97cz_Y" #telegram token
chat_id = "253529798" #telegram id
requests.post(url='https://api.telegram.org/bot{0}/sendMessage'.format(token), data={'chat_id': 253529798, 'text': gonderilecekYazi}).json()
#telegram sendMessage url, daha fazla bilgi için --&gt; https://core.telegram.org/bots

Kodu çalıştırdığınızda eğer herhangi bir yerde hata yapmadıysanız, Telegram hesabınıza bildirim gelecektir.

erlnjg

Bu mesajın istediğimiz zamanlarda bize gelmesini istiyorsak, bir sunucuya bu python dosyasını atıp Görev Zamanlayıcı(Cron Jobs) ile istediğiniz zaman çalıştırabiliriz. Bu yazı yeterince uzun olduğu için sadece yöntemi söylemekle yetiniyorum şimdilik. Daha sonra bu aşamaları da anlatacağım.


Kaynakça

1.^Telegram (yazılım). 21 Ocak 2017.

2.^Bot (robot). 21 Ocak 2017.

8 Comments

  1. bulent

    merhaba iyi bayramlar …
    ben python da yeniyim öncelikle belirtmek isterim çok kolay gibi gözüksede kullanamayınca zor ben api ve secret girerek bir siteden veri almaya çalışıyorum gerçi api ve secret olmadan da alsam olur ama vermiyor sanırım cekemedim. api ve secret mantığını anlamaya çalışıyorum fakat anlayamadım. parayla yaptırayım dedim adam bulamadım. buldum param kalmadı geldim buraya… python 3 window çalışıyorum ve pycharm üzerinde çalışıyorum kısaca api ve secret ile giriş yapılan bi kod yazabilirmisiniz örnek olması açısından bi sürü şey okudum seyrettim allak bullak oldum. requests ve bs4 ile denedim ama sanırım olmuyor. sadece api ve secret girerek online nasıl olabilirim onu bile başaramadım şimdiden teşekkür ederim. en azından bu konuyu anlatabilirmisin

    • unalfaruk

      Merhaba Bülent,

      Sana da iyi bayramlar, öncelikle API olayını anlatan eğlenceli bir yazıya buradan ulaşabilirsin. “Secret” terimiyle kastetmek istediğini tam olarak anlayamadığım için şimdilik tavsiye veremeyeceğim, yapmak istediğin şeyi daha açık bir şekilde e-posta adresime gönderirsen veya yorum olarak buraya yazarsan yardımcı olmaya çalışırım. BS4 ile Google gibi bazı sitelerin dinamik kısımlarını çekemezsin. Çekmek istediğin veri, benzersiz bir veri değil ise başka bir siteyi kaynak olarak kullanmayı deneyebilirsin.

  2. mLara

    merhaba ben her şeyi yaptım fakat https://api.telegram.org/bot{0}/sendMessage?chat_id={1]6text={2}
    bu kısımda kafam karıştı 2 yerine ne yazıcam ?

    • unalfaruk

      Öncelikle hatayı düzeltmek isterim, 6 yerine & karakterini kullanınız.

      https://api.telegram.org/bot{0}/sendMessage?chat_id={1}&text={2}

      Yukarıdaki ifade, manuel olarak web tarayıcıdan bu işi el ile yapmak istediğinizde yapmamız gereken istek bağlantısı. {0} token, {1} chat_id, {2} mesaj olarak parametrelendirilmiş. Aşağıdaki request örneği de yukarıdaki bağlantıyı otomatize eden kod satırı. {2} yerine elinizle bir değer girmek istiyorsanız string herhangi bir değer girebilirsiniz. Aşağıdaki örnekte {2} parametresine karşılık gelen ‘text’: “örnek mesaj” kısmıdır.

      requests.post(url=’https://api.telegram.org/bot{0}/sendMessage’.format(token), data={‘chat_id’: 253529798, ‘text’: “örnek mesaj”}).json()

  3. merhaba
    bu dediğiniz yöntem ile 2 farklı siteden yeni içerik (bildirim) geldikçe bazı anahtar kelimeleri filtreleyerek mesaj atmasını sağlayabilirmiyim .

    • unalfaruk

      Merhaba,

      Tabii ki yapabilirsin; aynı şey aslında, tek fark birden fazla web sayfasına request atman olacak. İki farklı web sayfasından dönen yanıtları filtreledikten sonra istediğin sonucu veriyorsa Telegram API ile bildirim gönderirsin.

  4. Oğuzkaan

    İyi günler. Bu yazınızı çok faydalı ve yeni başlayanlar için çok işe yarar olacağını düşünüyorum. Yazınızı son kısmına kadar anlayıp çalıştırdım lakin son paragraftan bir şey anlayamadım. Sunucuya atmak derken kastınız nedir ve bu Görev Zamanlayıcı (Cron Jobs) bir kütüphane mi yoksa dosyayı atmamız gereken sunucu ile alakalı bir şey mi ?
    İlgi ve alakanız için şimdiden teşekkürler.

    • unalfaruk

      Merhaba,

      Son paragrafa kadar kodu elimizle manuel olarak çalıştırıyoruz. Ancak kodun kendi kendine çalışmasını istiyorsak(mesela her gün 10.00’da), sürekli açık olan bir bilgisayar(genelde sunucular olur) üzerindeki “görev zamanlayıcı (task scheduler – Windows için)(cron jobs – Linux için)” kullanılarak bu isteğimizi yapabiliriz. Görev zamanlayıcılar işletim sistemiyle gelen bir araç, bazı görevleri otomatize etmek için kullanılıyor.

Leave a Reply

Theme by Anders Norén