urllib?

Başlatan utopyada, 04 Eylül 2012 - 10:36:59

« önceki - sonraki »

0 Üyeler ve 1 Ziyaretçi konuyu incelemekte.

utopyada

merhabalar..
urllib.urlopen ile bir internet sitesinin kaynak kodlarını görüntülüyoruz..Ama ben internet sayfasındaki kaynak kodları değil ,belli bir alanı görüntülemek istiyorum..Örneğin sitede yazan modelleri..
bunu nasıl yapabilirim?

furkankalkan

Bu iş XML ile daha kolay olur ama forumda bir film sitesinden veri çeken program yazılmıştı (program adını hatırlamıyorum :()
Bulamazsanız site  size aitse XML Parse (Türkçesi ne olabilir bunun ?) ile uğraşırsınız.
Lover
twitter.com/furkan_kalkan1

utopyada

Oww hocam o kadar kompleks bir konuya mı girdim haberim yok..Ben sadece mesela örnek veriyorum..."http://www.kitapyurdu.com/" sitesindeki  anasayfada bulunan 5 kitabın adını ve fiyatını yazdırmak istiyorum..Tabi bilgiler siteden gelecek..Bilgiler değiştiği zaman program da otomatik verilerini değiştirecek..
??

furkankalkan

Hmm. Bunu kodları ayrıştırarak halledebiliriz (kitap bilgileri ayrı bi div içindeyse işimiz kolay)
Lover
twitter.com/furkan_kalkan1

hitokiri

Sağ tıkla örneğin firefoxtan kaynak kodununa bak , yazılanların içinde bulunduğu tagları görmeye çalış,
Sonra re ile o tagları ayır , splitlines ile satır satır alarak ayıklamada yapabilirsin işleri biraz daha kolaylaştırmak için yazılmış bir kütüphanede var,
bağlantı'dan detaylı bilgilere ulaşabilirsin sadece sitedeki metinleri görüntülemek istiyorsan,
bash tarafında da html2text kaynak dosyası şeklinde görüntüleyebilir/ ayıralabilirsin, gerçi aynı şeyleri bahsettiğim kütüphanede yapıyordu sanırım XD

utopyada

Teşekkür ederim hemen deniyorum..

hitokiri

Kolay gelsin sana şu re'ye hiç bir zaman tam olarak hakim olamadım o yüzden biraz absürdte olsa basit bir örnekte geçeyim başlangıç için şuan için toparlayabildiğim kadarıyla;

>>> from urllib import urlopen
>>> import re
>>> x = urlopen("http://www.kitapyurdu.com/").read().splitlines()
>>> for i in x:
...     if "href" in i:
...             name = re.findall("title=..*..?",i)[0:]
...             if name:
...                     print name
...
['title="internet kitap\xe7\xfdn\xfdzda yeni \xe7\xfdkanlar" href="http://www.kitapyurdu.com/xml/yenicikanlar.xml" />']
['title="internet kitap\xe7\xfdn\xfdzda \xe7ok satanlar" href="http://www.kitapyurdu.com/xml/coksatanlar.xml" />']
['title="Yarat\xfdl\xfd\xfe S\xfdrr\xfd & Meryem Suresi (1-15. Ayet), Cemalnur Sargut"></a>']

utopyada

#7
düzenli ifadelerin çetrefilli olduğunu söylerler zaten..dün akşam re ile baya haşır neşir olmuştum..Benim yapmam braz uzun sürebilir,yapınca buraya yazıcam :)Tekrar teşekkürler..





Mesaj tekrarı yüzünden mesajınız birleştirildi. Bu mesajın gönderim tarihi : 04 Eylül 2012 - 14:38:22

Şöyle bir durum var...Kodlar arasında bir tablo var ve bu tablo içindekileri ekrana yazdırmak istiyorum..
sanırım <tablo> </tablo> gibi bir kod kullancam ama içindekileri nasıl alıcam acaba?

hitokiri

#8
from urllib import urlopen
import re

info = urlopen("http://www.kitapyurdu.com/").read().splitlines()
isimler =[]
yazarlar = []
for i in info:
    if "table" in i:
        name = re.findall('<span class="kitapismikucuk">(.*?)</span>',i)
        author =  re.findall('<a href=".*?">(.*?)</a>',i)
        if name:
            isimler.append(name)
        if author:
            yazarlar.append(author)
print "Kitap İsimleri:\n"
print isimler[0:]
print "\nYazarlar:\n"
print  yazarlar[0:]







Unicode ile düzeltme gerek gibi sorun çözüldü artık sanırım?
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# vim: ts=4:sw=4

from urllib import urlopen
import re



from HTMLParser import HTMLParser
from re import sub
from sys import stderr
from traceback import print_exc

class _DeHTMLParser(HTMLParser):
    def __init__(self):
        HTMLParser.__init__(self)
        self.__text = []

    def handle_data(self, data):
        text = data.strip()
        if len(text) > 0:
            text = sub('[ \t\r\n]+', ' ', text)
            self.__text.append(text + ' ')

    def handle_starttag(self, tag, attrs):
        if tag == 'p':
            self.__text.append('\n\n')
        elif tag == 'br':
            self.__text.append('\n')

    def handle_startendtag(self, tag, attrs):
        if tag == 'br':
            self.__text.append('\n\n')

    def text(self):
        return ''.join(self.__text).strip()


def dehtml(text):
    try:
        parser = _DeHTMLParser()
        parser.feed(text)
        parser.close()
        return parser.text()
    except:
        print_exc(file=stderr)
        return text


def main(text):

    print(dehtml(text))
info = urlopen("http://www.kitapyurdu.com/").read().splitlines()
buf=""
for i in info:
    if "table" in i:
        buf = buf + "\n" + i

buf =  unicode(buf,"ISO-8859-9")
main(buf)

Kaynak
Kaynakta başka bir kütüphaneden de bahsedilmiş bu şekildede olabilir , hatta daha rahat gibi..

sem

Alıntı yapılan: dewilman - 04 Eylül 2012 - 11:00:13
Bu iş XML ile daha kolay olur ama forumda bir film sitesinden veri çeken program yazılmıştı (program adını hatırlamıyorum :()
Bulamazsanız site  size aitse XML Parse (Türkçesi ne olabilir bunun ?) ile uğraşırsınız.

Film sitesinden film çeken bir uygulama vardı MLM (Movie List Manager)

Yalnız http isteği gönderip XML ayrıştırma (parse) işlemine giremezsiniz, eğer girecek olursanız sunucu da sizin elinizde olmalı. Yani HTTP cevabı (response) olarak HTML döndüren sayfayı XML ile ayrıştırma gibi bir durum söz konusu değil.

Alıntı yapılan: utopyada - 04 Eylül 2012 - 11:03:34
Oww hocam o kadar kompleks bir konuya mı girdim haberim yok..Ben sadece mesela örnek veriyorum..."http://www.kitapyurdu.com/" sitesindeki  anasayfada bulunan 5 kitabın adını ve fiyatını yazdırmak istiyorum..Tabi bilgiler siteden gelecek..Bilgiler değiştiği zaman program da otomatik verilerini değiştirecek..
??

Sizin ilacınızın düzenli ifadeler hitokirinin yardımcı olduğu gibi. Yalnız eğer bildiğmiz internet sitesinden bahsediyorsak otomatik güncelleme gibi bir durum söz konusu olamaz. Çünkü HTTP bir protokoldür ve protool tanımı belli ve basittir; istek (request) & cevap (respose)... Yani HTTP protkolü ile çalışan bir sunucudaki internet sitesi, baştan aşağı yenilense de siz istek göndermeden (request) herhangi bir değişiklik size yansımaz.

Ama kendi yazacağınız bir protokol ile HTTP'yi genişleterek belkli böyle bir şey yapabilirsiniz. Örneğin çevirim için (online) olan istemciler (client) de ayrıca bir port dinleyerek sunucu gibi davranarak, asıl sunucudan gelebilecek bazı istekleri dinleyebilir vs.... Bir çok yöntem var bunu yapmak için ama dediğim gibi kendiniz yapmalısınız. Yoksa  bir istemciye sunucudan bilgi gönderilmesi (otomatik olarak dediğiniz kısım) HTTP protokolünce tanımlı değildir.

Bu durumda yapılacan olan bellidir =)

İnternet sitesinin html kodlarını edin; düzenli ifadelere göre ya da kendinizce (manual ) olarak HTML kodlarından istenilen verilerin ayıklanması ve belirli bir süre içerisinde kontrol edilmesi (pull).

NOT: Bu arada Python'da ciddi iseniz yani belirli bir iş için değil de öğrenmek ve geliştirici olarak kodlamak istiyorsanız urllib yerine urllib2 kullanmanızı öneririm. Daha doğrusu Python dökümatasyonu Python 3 geçişi nedeni ile önerir. =)

Kolay gelsin...
".NET çemberinden geçen lirisist etkisi bir 'Volcano', bir yüzüm Java bir yüzüm Badalamenti Don Tano"
----------------------------------------------------------------------------------------------------------------------
"Her yer ölüm yine, burası dünya
Derken ölüm bile bu nasıl dünya?
Benden ölüm dile, batıyor gün yine
Burası dünya?

utopyada

zamanınızı alıyorum çok afedersiniz ama ben işin içinden çıkamadım..asıl yapmak istediğim şey şuydu:
http://www.honda.com.tr/SeriesPrices.aspx?series=civic-hb   bu sayfada fiyat bölümünü ekrana yazdırmak..
bu da sadece bir tabloya ait kodlar..


import urllib
import re

f=urllib.urlopen("http://www.honda.com.tr/SeriesPrices.aspx?series=civic-hb")
for i in f.readlines():
b=re.findall('<td  align="left" bgcolor="#666666" height="25" class="fiyatlar_baslik">(.*?)</td>',i)
if b:
    print b.group()


şöyle bir şeyle başladım ama hem çok uzun sürüyor ekrana gelmesi hem de sonuç vermiyor :/

hitokiri

Aynen td içindekileri ayırmada sorun yaşamış re ,kimbilir neden ancak kendi sorunlarına kendin çözümler üretmen gerek, biraz kendine zaman tanısan daha rahat edersin;
# -*- coding: utf-8 -*-
# vim: ts=4:sw=4
from urllib import urlopen
import re

f= urlopen("http://www.honda.com.tr/SeriesPrices.aspx?series=civic-hb").read()
i =0
for x in f.splitlines():

    baslik = re.findall('<span class="fiyatlar_baslik">(.*?)</span>',x )
    bilgi = re.findall('<span class="textbaslik_12px_fume">(.*?)</span>',x)

    if baslik  :
        print baslik[0] + "\n"
    if bilgi and not   "-" in bilgi:
        i +=1
        print bilgi[0].replace("\n","")  + "\t",
        if  i == 5 :
            i = 0
            print "\n"


monthy_python

shebang'deki üçüncü satırı
# vim: ts=4:sw=4
ilk kez görüyorum. nedir, ne işe yarar?

hitokiri

Tab girintilemesini belirtmek amaçlı.. Nerden gördüm hatırlamıyorum ancak gedit ile 8 boşluk basıyor ilk ayarlarında girintilemede sorun olmasın diye ekliyorum..

monthy_python

çeşitli yerlerden indirip denediğim bir çok kodda küçük bir değişiklik yapınca, girintileme hizası aynı görünse bile (yazan 4 boşluk, ben 1 tab kullandığım için) girintileme hatası veriyor. en başından girintiliyorum çalışması için kodun.
eğer bu satır buna engel olabilirse şahaneymiş  :) . deniycem.

@utopyada konuyu böldüğüm için özür dilerim bu arada.

hitokiri

Düzeltebiliyordur herhalde ancak gedit tercihlerde "sekme yerine boşluk ekle" 'de senin sorununa çözüm olabilir.

monthy_python

onu da denerim, teşekkürler.

utopyada

Hocam süper ötesisiniz hemen analiz ediyorum..Tama evet haklısınız çözümleri kendim üretmeliyim...:(

utopyada

Hitokiri;şöyle bir sorum olacak..ben PyQuery ile istediğim sonucu alabildim,tam bir tablo şeklinde yazdırdım ancak toplam  15 satır kod yazmak zorunda kaldım ve bunların 11 tanesi "print" ile başlıyor..
1-Döngü ve list comprehensionla bu kodlar azaltılabiliyor ancak istediğim düzeni veremiyorum..sizin yazdığınız ekran çıktısı da düzenli tablo şeklinde değil..Mesela arayüz kullansak herşey daha basit..
Arayüz kullanmadan kodları döngü içinde düzenlemenin bir yolu var mı?
Ya da siz kendi kodlarınızı nasıl düzene sokabilirsiiniz?
Bir de rica etsem kısaca şurayı özetler misiniz?

if baslik  :
        print baslik[0] + "\n"
    if bilgi and not   "-" in bilgi:
        i +=1
        print bilgi[0].replace("\n","")  + "\t",
        if  i == 5 :
            i = 0
            print "\n"


Teşekkür ederim..

hitokiri

Arayüzle her şey elbette daha kolay olurdur, Qt ve Gtk'nın ham html kodlarını ve web sayfalarını okuyabilen "Widget"'leri var ancak senin durumunda,
Eğer tablo içeriği çok yüklüyle liste ve sozluklerden yararlanmak daha faydalı olur,
kodlara gelecek olursak,
"\n" yeni satıra işaret ediyor,
eğer tablo üzerinden gelen argümanlar "-" içermiyorsa,
print "," ile kullanıldığında yeni satıra geçmiyor,
ve yeniden gelecek argümanlar için değeri bir arttırıyor,
eğer i değeri 5 ' eşitse i değeri yeniden sıfırlanıyor ve yeni bir satıra geçiyor..



Arayüz meselesine gelecek olursak gtk kısmında bu iş için WebKit var,
onu şu şekilde kullanabilirsin;
import webkit,gtk
from urllib import urlopen

class Browser:


    def __init__(self):
        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.window.connect("delete_event", gtk.main_quit)

        self.web_view = webkit.WebView()       
        #self.web_view.load_html_string(bilgi,"file:///")
        sw = gtk.ScrolledWindow()
        sw.set_policy(True,True)
        self.web_view.open("http://www.honda.com.tr/SeriesPrices.aspx?series=civic-hb")
        sw.add(self.web_wiew)
       
        self.window.add(sw)
        self.window.show_all()

browser = Browser()
gtk.main()

tabii google dahada yardımcı olur..

utopyada

#20
Tamam ben braz daha düzenleme yapmaya çalışayım,takıldğım yerde kodlarla beraber sorucam..
İyi çalışmalar


Mesaj tekrarı yüzünden mesajınız birleştirildi. Bu mesajın gönderim tarihi : 07 Eylül 2012 - 23:05:35

bir de arayüz istemiyorum şuan..
istediğim komut satırında tablo görünümünü vermek..
ama döngüyle kodları kısaltmaya çalıştığımda olmuyor o iş.