23 Mart 2016 Çarşamba

RASPBERRY PI 2 ile WEB SİTESİNDEN VERİ ÇEKME

     Merhaba arkadaşlar, yeni bir yayınla tekrar birlikteyiz. Bu yayınımızda Python 3 de geliştirdiğimiz programımızla web sitesinden veri çekmeyi öğreneceğiz. Uygulamamızda Meteroloji Genel Müdürlüğü web sayfasından Malatya'nın hava durumu, sıcaklık ve nem bilgilerini alıp terminal ekranına ve 16x2 LCD ye bastıracağız.
   Python 3 programımızda 'urllib.request' ve 're' modüllerini kullanacağız. 'urllib.request' modülü web sayfasının html kaynak kodunu çekmemizi sağlayacaktır. Python ve bazı dillerde düzenli ifadeler (regular expressions) adı verilen bir yapı vardır. Bu yapının kullanımını bir örnekle anlatacak olursak; düzenli ifadeler uzun bir metin içinde, yazılımcının tarif ettiği özellikte ki bir kelimeyi veya bir sayıyı ayıklamayı sağlar. Bizde, web sayfasının html kaynak kodlarını çektikden sonra 're' modülünün bazı metotlarını kullanarak kaynak kod içinden gerekli veriyi ayıklayacağız.
   Düzenli ifadeler ve metakarakterler geniş kapsamlı konulardır. Python 3 için bu konuları istihza.com'dan daha detaylı bir şekilde öğrenebilirsiniz.

   Uygulamamızın devre şeması bir önceki yayınımızda da kullandığımız aşağıdaki şemadır.
























    Programımız aşağıda yer almaktadır. Programı inceleyebilirsiniz. Anlaşılamayan bir kısım olursa yardımcı olurum.
# -*- coding: utf-8 -*-
#import
import RPi.GPIO as GPIO
import time
import urllib.request
import re

from html.parser import HTMLParser
parser = HTMLParser()
site = "http://www.mgm.gov.tr/tahmin/il-ve-ilceler.aspx?m=MALATYA"

# GPIO pin numaralarının sabitlere atanması
LCD_RS = 7
LCD_E  = 8
LCD_D4 = 25
LCD_D5 = 24
LCD_D6 = 23
LCD_D7 = 18

# Sabitlerin tanımlanması

LCD_CHR = True
LCD_CMD = False

def main():
  
  GPIO.setwarnings(False)
  GPIO.setmode(GPIO.BCM)       # BCM sırasına göre GPIO
  GPIO.setup(LCD_E, GPIO.OUT)  # E
  GPIO.setup(LCD_RS, GPIO.OUT) # RS
  GPIO.setup(LCD_D4, GPIO.OUT) # DB4
  GPIO.setup(LCD_D5, GPIO.OUT) # DB5
  GPIO.setup(LCD_D6, GPIO.OUT) # DB6
  GPIO.setup(LCD_D7, GPIO.OUT) # DB7

  lcd_sartla()
 
  satirXsutun(1,2)
  lcd_yaz("Raspberry Pi 2")
  time.sleep(3)
  
  lcd_temizle()
  satirXsutun(1,3)
  lcd_yaz("MALATYA HAVA")
  satirXsutun(2,6)
  lcd_yaz("DURUMU")
  time.sleep(3) 


  z=0
  
  while z<2:
    z+=1
    
    lcd_temizle()
    satirXsutun(1,1)
    lcd_yaz("tarih "+time.strftime("%d-%m-%Y"))
    print("tarih "+time.strftime("%d-%m-%Y"))
    satirXsutun(2,1)
    lcd_yaz("saat    "+time.strftime("%H:%M"))
    print("saat    "+time.strftime("%H:%M"))
    time.sleep(3) # 3 second delay
    
    regex1 = '<td><em class="renk.+?">(.+?)</em></td>'
    comp1 = re.compile(regex1)

    htmlkod = urllib.request.urlopen(site).read().decode('utf8')
    titles = comp1.findall(htmlkod)
    
    for title in titles:
        arasonuc1 =  re.match("[0-9]+,*[0-9]{0,2}",title)
        sonuc1 =  arasonuc1.group()   
        print("SICAKLIK: ",sonuc1)

    regex2 = '<td><em>(.+?)</em></td>'
    comp2 = re.compile(regex2)

    #htmlkod = urllib.request.urlopen(site).read().decode('utf8')
    titles = comp2.findall(htmlkod)

    for title in titles:
        print("nem: ",title)
        sonuc2 = title
        break
   
    
    lcd_temizle()
    satirXsutun(1,1)
    lcd_yaz('SICAKLIK: '+sonuc1)
    veri_gonder(223, LCD_CHR)
    lcd_yaz('C')
    satirXsutun(2,1)
    lcd_yaz('NEM     : '+sonuc2)
    time.sleep(3) 
    
    regex3 = '<td.*?>(.+?)> </td>'
    comp3 = re.compile(regex3)

    #htmlkod = urllib.request.urlopen(site).read().decode('utf8')
    titles = comp3.findall(htmlkod)

    for title in titles:
        durum0 = parser.unescape(title)
        #print sonuc0
        durum1 = re.search("alt=\".*\"",durum0)
        durum2 = re.search("\".*\"",durum1.group())
        durum3=durum2.group()[1:len(durum2.group())-1]
        print(durum3)
        
    sondurum = durum3.split()
    lcd_temizle()
    if len(sondurum)==4:
      satirXsutun(1,1)
      lcd_yaz(sondurum[0]+' '+sondurum[1])
      satirXsutun(2,1)
      lcd_yaz(sondurum[2]+' '+sondurum[3])
    elif len(sondurum)==3:
      satirXsutun(1,1)
      lcd_yaz(sondurum[0]+' '+sondurum[1])
      satirXsutun(2,1)
      lcd_yaz(sondurum[2])
    elif len(sondurum)==2:
      if len(sondurum[0]+sondurum[1])>15:
        satirXsutun(1,4)
        lcd_yaz(sondurum[0])
        satirXsutun(2,4)
        lcd_yaz(sondurum[1])
      else:
        satirXsutun(1,1)
        lcd_yaz(sondurum[0]+' '+sondurum[1])
    else:
      satirXsutun(1,1)
      lcd_yaz(durum3)
    time.sleep(3)

    

def lcd_sartla():
  veri_gonder(0x33,LCD_CMD) # init
  veri_gonder(0x32,LCD_CMD) # init
  veri_gonder(0x28,LCD_CMD) # 4bit, 2 satır, 5x8 dots
  veri_gonder(0x0C,LCD_CMD) # Display açık, Cursor gizli
  veri_gonder(0x06,LCD_CMD) # Kursor her karakterden sonra sağa kayar 
  veri_gonder(0x01,LCD_CMD) # Displayi temizle 
  time.sleep(0.0005)
  LCD_turkce_karakter()
  time.sleep(0.0005)

def veri_gonder(veri, mode):
  # Verinin önce üst 4 biti,
  # daha sonrada alt 4 biti gönderilir.
  # karakter yazmak için mode true
  # komut yazmak için ise mode false
  
  ikilik_veri = bin(veri)[2:].zfill(8)

  # RS
  GPIO.output(LCD_RS, mode) 
  
  
  # Üst 4 bit
  GPIO.output(LCD_D4, int(ikilik_veri[3]))
  GPIO.output(LCD_D5, int(ikilik_veri[2]))
  GPIO.output(LCD_D6, int(ikilik_veri[1]))
  GPIO.output(LCD_D7, int(ikilik_veri[0]))
  
 

  # Düşen kenar clock
  enable_clk()
  
  #GPIO.output(LCD_RS, mode) # RS
  # Alt 4 bit
  GPIO.output(LCD_D4, int(ikilik_veri[7]))
  GPIO.output(LCD_D5, int(ikilik_veri[6]))
  GPIO.output(LCD_D6, int(ikilik_veri[5]))
  GPIO.output(LCD_D7, int(ikilik_veri[4]))

  # Düşen kenar clock
  enable_clk()

def LCD_turkce_karakter():
  harf_1 = [0, 14, 16, 14, 1, 30, 4, 0]  #Ş - ş 
  harf_2 = [0, 14, 17, 16, 17, 14, 4, 0] #Ç - ç
  harf_3 = [0, 0, 12, 4, 4, 4, 14, 0]  #ı
  harf_4 = [4, 0, 14, 4, 4, 4, 14, 0]    #İ
  harf_5 = [0, 10, 0, 17, 17, 17, 14, 0] #Ü - ü
  harf_6 = [10, 0, 14, 17, 17, 17, 14, 0]#Ö- ö
  harf_7 = [14, 0, 14, 18, 14, 2, 28, 0] #ğ
  harf_8 = [14, 0, 14, 16, 22, 18, 14, 0]#Ğ
  
  veri_gonder(64 , LCD_CMD)
 
  for i in range(8):
    veri_gonder(harf_1[i] , LCD_CHR)
 
  for i in range(8):
    veri_gonder(harf_2[i] , LCD_CHR)

  for i in range(8):
    veri_gonder(harf_3[i] , LCD_CHR)

  for i in range(8):
    veri_gonder(harf_4[i] , LCD_CHR) 
 
  for i in range(8):
    veri_gonder(harf_5[i] , LCD_CHR)
 
  for i in range(8):
    veri_gonder(harf_6[i] , LCD_CHR) 

  for i in range(8):
    veri_gonder(harf_7[i] , LCD_CHR)
 
  for i in range(8):
    veri_gonder(harf_8[i] , LCD_CHR)
    
def enable_clk():
  GPIO.output(LCD_E, True)
  time.sleep(0.0005)
  GPIO.output(LCD_E, False)
  time.sleep(0.0005)

def satirXsutun( satir, sutun):
  if satir==1:
    sutun -=1
    veri_gonder(0x80 + sutun , LCD_CMD)
  elif satir==2:
    sutun -=1
    veri_gonder(0xC0 + sutun , LCD_CMD)
def lcd_temizle():
  veri_gonder(0x01 , LCD_CMD)
  time.sleep(0.0005)

def lcd_yaz(mesaj):
  #print (mesaj)
  for i in range(len( mesaj)):
    if mesaj[i]=='Ş' or mesaj[i]=='ş':
      veri_gonder(0 , LCD_CHR)
      
    elif mesaj[i]=='Ç' or mesaj[i]=='ç':
      veri_gonder(1 , LCD_CHR)

    elif mesaj[i]=='ı': 
      veri_gonder(2 , LCD_CHR)

    elif mesaj[i]=='İ':
      veri_gonder(3 , LCD_CHR)

    elif mesaj[i]=='Ü' or mesaj[i]=='ü':
      veri_gonder(4 , LCD_CHR)
      
    elif mesaj[i]=='Ö' or mesaj[i]=='ö':
      veri_gonder(5 , LCD_CHR)

    elif mesaj[i]=='ğ':
      veri_gonder(6 , LCD_CHR)

    elif mesaj[i]=='Ğ':
      veri_gonder(7 , LCD_CHR)   
 
    else:
      veri_gonder(ord(mesaj[i]) , LCD_CHR)
if __name__ == '__main__':

  try:
    main()
  except KeyboardInterrupt:
    pass
  finally:
    lcd_temizle()
    satirXsutun(1,6)
    lcd_yaz('son...')
    GPIO.cleanup()
   Aşağıda uygulamamızın videosu yer almaktadır. Video da Raspberry Pi'nin masaüstü ortamına VNC server ile uzaktan erişim sağlanmıştır. VNC (Virtual Network Computing) server'ın kurulumu bu link de anlatılmaktadır.


    Uygulamamızın birkaç fotoğrafı:




    İlgili arkadaşlara kolay gelsin. 
    Farklı bir çalışmada görüşmek üzere...
    Başarılar...

6 yorum:

  1. kod derlemede hata veriyor 5. satır

    YanıtlaSil
  2. Size de merhaba Gökhan Dökmetaş. Hata mesajında ne yazdığını da yorumda belirtseydiniz keşke size daha iyi yardımcı olabilirdim.

    5. satırda urllib.request modülü import edilmiştir. Eğer python 2 kullanıyorsanız hata verir. Çünkü urllib.request modülü python 3 e aitdir. Muhtemelen programı sudo python havadurumu.py şeklinde çalıştırmayı denediniz. Bu şekilde çalıştırırsanız hata alırsınız.
    sudo python3 havadurumu.py şeklinde çalıştırınız.

    Sonucu bildirirseniz sevinirim.

    YanıtlaSil
  3. Merhaba ben foursquare api den bilgi çeken bir uygulama yapmak istiyorum bu konuda bana yardımcı olabilirmisiniz ?

    YanıtlaSil
  4. Merhaba benim yaptığım bu projede web sitesinin kaynak html kodundan veri çekmektedir. bu şekilde Foursquare apiden veri çekebilirmisiniz bilmiyorum.

    YanıtlaSil
  5. Bu yorum yazar tarafından silindi.

    YanıtlaSil
  6. Eser bey merhaba. Oncelikle elinize saglik.
    Pi zero w modelinde deniyorum. Saat tarihi aliyor ancak sicaklik ve hava durumunu cekemiyor siteden. Ne onerirsiniz saygilarimla.

    YanıtlaSil