Yazılım geliştirme maceramda yeni bir projemi tamamladım ve paylaşmaktan gurur duyuyorum!
Türkiye'deki altın fiyatlarını altin.in sitesinden 1 Ocak 2005 tarihinden günümüze kadar toplayan ve CSV formatında dışa aktaran açık kaynaklı bir araç geliştirdim.
? Bu projenin özelliği:
18 yıldırki tüm tarihsel altın fiyat verilerine tek tıklamayla erişim
Gram altın, çeyrek altın, tam altın, reşat altın ve diğer tüm altın türleri
Verileri CSV formatında dışa aktararak Excel'de analiz imkanı
? Kullanılan teknolojiler:
Object Pascal (Delphi)
Indy HTTP bileşenleri
HTML parsing ve web scraping
Veri işleme ve dışa aktarma
Bu proje hem kişisel gelişimim açısından önemli bir adım oldu, hem de finansal veri analizi yapmak isteyenler için değerli bir araç sunuyor. 2005 yılından beri olan tüm altın fiyat hareketlerini tek bir tıklamayla indirebilirsiniz!
GitHub reposunda tüm kaynak koda ulaşabilirsiniz. İşbirliği, danışmanlık veya yeni projeler konusunda görüşlerinizi memnuniyetle karşılarım. ?
https://github.com/mesutde/Altin-Fiyat-Arsivi
Güzel çalışma.
- Kodunuzu inceledim HTML parse temelli olmuş.
- Olumsuzluklar konusundaki soru işaretlerimi paylaşayım. Sonra da çözümü paylaşayım.
? Her gün verisi için 500 milisaniye (sleep) beklemeli ve birer gün arttırımlı yapılan çoklu sorgu, kaynak site tarafından saldırı olarak nitelendirilebilir.
? Sayfa tasarımındaki oynamalar projenizi / fonksiyonlarınızı çalışmaz hale getirebilir.
- Kaynak aldığınız sitenin verileri nasıl çektiğini incelediğimde aslında text bazlı cevap verdiğini de gördüm.
- Şu aşağıdaki link formatını denemek isteyebilirsiniz.
- Aynı siteden bir kerede geriye dönük kaç günlük veri isterseniz o kadar veri çekebildiğinizi göreceksiniz. Böylece gün gün döngüden de ardışık sorgudan da kaçınmış olacaksınız.
Kod:
aşağıdaki şekilde örnekleyebiliriz....
https://altin.in/grafikur.asp?did=flash_grafik&ca=1&islem=gunluk&sa=sat&kur=GA&banka=altin&k=&gun=1
https://altin.in/grafikur.asp?did=flash_grafik&ca=1&islem=gunluk&sa=sat&kur=GA&banka=altin&k=&gun=10
https://altin.in/grafikur.asp?did=flash_grafik&ca=1&islem=gunluk&sa=sat&kur=GA&banka=altin&k=&gun=1000
https://altin.in/grafikur.asp?did=flash_grafik&ca=1&islem=gunluk&sa=sat&kur=GA&banka=altin&k=&gun=3000
gibi gun parametresi gelecek verinin gün sayısını girmenize müsaade ediyor.
sondaki gun = 1 olan kısmı gun=3000 derseniz 3000 günlük veriyi bir defada çekebilir hız ve performansı zirveye taşıyabilirsiniz.
Not: 7040'a kadar denedim 1 Mayıs 2006'ya kadar geriye uzandı.
Çalışmalarınızda başarılar.
(08-08-2025, Saat: 09:01)mrmarman Adlı Kullanıcıdan Alıntı: [ -> ]Güzel çalışma.
- Kodunuzu inceledim HTML parse temelli olmuş.
- Olumsuzluklar konusundaki soru işaretlerimi paylaşayım. Sonra da çözümü paylaşayım.
? Her gün verisi için 500 milisaniye (sleep) beklemeli ve birer gün arttırımlı yapılan çoklu sorgu, kaynak site tarafından saldırı olarak nitelendirilebilir.
? Sayfa tasarımındaki oynamalar projenizi / fonksiyonlarınızı çalışmaz hale getirebilir.
- Kaynak aldığınız sitenin verileri nasıl çektiğini incelediğimde aslında text bazlı cevap verdiğini de gördüm.
- Şu aşağıdaki link formatını denemek isteyebilirsiniz.
- Aynı siteden bir kerede geriye dönük kaç günlük veri isterseniz o kadar veri çekebildiğinizi göreceksiniz. Böylece gün gün döngüden de ardışık sorgudan da kaçınmış olacaksınız.
Kod:
aşağıdaki şekilde örnekleyebiliriz....
https://altin.in/grafikur.asp?did=flash_grafik&ca=1&islem=gunluk&sa=sat&kur=GA&banka=altin&k=&gun=1
https://altin.in/grafikur.asp?did=flash_grafik&ca=1&islem=gunluk&sa=sat&kur=GA&banka=altin&k=&gun=10
https://altin.in/grafikur.asp?did=flash_grafik&ca=1&islem=gunluk&sa=sat&kur=GA&banka=altin&k=&gun=1000
https://altin.in/grafikur.asp?did=flash_grafik&ca=1&islem=gunluk&sa=sat&kur=GA&banka=altin&k=&gun=3000
gibi gun parametresi gelecek verinin gün sayısını girmenize müsaade ediyor.
sondaki gun = 1 olan kısmı gun=3000 derseniz 3000 günlük veriyi bir defada çekebilir hız ve performansı zirveye taşıyabilirsiniz.
Not: 7040'a kadar denedim 1 Mayıs 2006'ya kadar geriye uzandı.
Çalışmalarınızda başarılar.
Kıyymetli geri bildiriminiz için ayrı zaman ayırıp öneri yazdığınız için ayrı Teşekkür ederim..
IndirVeParse fonksiyonunda 500 milisaniye yapmıştım ama sizin bulduğunuz text dönen veri daha iyiymiş..
iyi çalışmalar kolay gelsin.sağlıklı huzurlu günler haftalar dilerim.
Size aşağıdaki şekilde bir örnek hazırladım.
Deneyip içerik kontrolünden sonra (
altın fiyatları mayıs 2006'da garip seyretmiş ya da veride sorun var) kodlarınızda revizyona gitmek de isteyebilirsiniz memnunum kalsın de diyebilirsiniz, tercih sizin.
uses System.Net.HttpClientComponent,
System.Net.HttpClient,
System.JSON,
System.Generics.Collections;
type
tGoldInfo = record
kur : currency;
date : string;
end;
tGoldArray = array of tGoldInfo;
function FetchGoldExchange( aDay:Integer = 1 ): tGoldArray;
const
LUrlFmt = 'https://altin.in/grafikur.asp?did=flash_grafik'
+ '&ca=1&islem=gunluk&sa=sat&kur=GA&banka=altin&k=&gun=%d';
var
LResponse : IHTTPResponse;
LText : String;
LJSONObject : TJSONObject;
LKurObject : TJSONObject;
LSatisArray : TJSONArray;
LTarihArray : TJSONArray;
i : Integer;
begin
finalize(result);
with TNetHTTPClient.Create(nil) do
try
LResponse := Get( format(LUrlFmt, [aDay]) );
if LResponse.StatusCode = 200 then
begin
LText := LResponse.ContentAsString;
if ( pos('{kur:', LText) > 0 ) then
begin
System.Delete(LText, 1, pos('{kur:', LText)-1 );
if pos( ';graf.yarat', LText ) > 0 then
begin
LText := Copy(LText, 1, pos(';graf.yarat', LText)-1 );
// JSON Format düzeltme... (başlıklar çift tırnak içine alınmalı...)
LText := StringReplace( LText, 'kur', '"kur"', [] );
LText := StringReplace( LText, 'satis', '"satis"', [] );
LText := StringReplace( LText, 'tarih', '"tarih"', [] );
// JSON parse et
LJSONObject := TJSONObject.ParseJSONValue(trim(LText)) as TJSONObject;
if LJSONObject <> nil then
try
LKurObject := LJSONObject.FindValue('kur') as TJSONObject;
if LKurObject <> nil then
begin
LSatisArray := LKurObject.FindValue('satis') as TJSONArray;
LTarihArray := LKurObject.FindValue('tarih') as TJSONArray;
for i := 0 to LTarihArray.Count-1 do
begin
SetLength(result, length(result)+1);
With Result[ high(result) ] do
begin
kur := TJSONNumber( LSatisArray.items[i] ).AsDouble;
date := LTarihArray.items[i].Value;
end;
end;
end;
finally
LJSONObject.Free;
end;
end
else
ShowMessage('Geçerli bir JSON bölümü bulunamadı.');
end;
end else
begin
MessageDlg('Failed...' + sLineBreak + LResponse.ContentAsString,
TMsgDlgType.mtError, [mbAbort], 0 );
end;
finally
free;
end;
end;
// Örnek kullanım
procedure TForm1.BitBtn1Click(Sender: TObject);
var
LResult : tGoldArray;
i : Integer;
begin
LResult := FetchGoldExchange( 7040 );
// Memo'yu dolduralım...
if Length(LResult) > 0 then
begin
Memo1.Lines.Clear;
Memo1.Lines.BeginUpdate;
for i := Low(LResult) to High(LResult)
do
Memo1.Lines.Add(
format( '%20s : %10s', [ LResult[i].date,
format('%0.4f', [LResult[i].kur]) ]) );
Memo1.Lines.EndUpdate;
end;
Finalize( LResult ); // Array boşalt..
end;
Denemek için forma bir memo ve bir button koymanız kafi..

Merhaba,
Benzer bir yapıyla uğraşıyordum, bu fiyat bilgilerini günü gününe doğrulamak üzere başka bir platform var mıdır ya da mümkün müdür ?
IdHTTP ssl iletişiminde hata veriyordu farklı versiyonlarda dll dosyaları denedim ama olmadı (libeay32.dll, ssleay32.dll).
Sonunda pes ettim bilgisayarda kurulu başka programların kurulum dizinlerindeki bu iki dll dosyasını atınca hata vermeden https link üzerinden veri çekebildim.
Fabrikada çalışmaktan vakit kalmıyor, uzun zamandır da uğraşmıyordum kodlarla hata verdikce moralim bozuldu açıkcası.
Kablosuz elektronik moduller ve bina otomasyonunu beraber çalıştırıp takip etmeye çalıştığımız bir proje var ama hobiden öteye gidemedik henüz , bu JSOn yapısı iletişim için epey hızlı olacak gibi görünüyor.
Kodlar çok faydalı oldu, teşekkürler.
@
mrmarman Projeyi derleme şansım yok, sana zahmet vermeyeceksem, başlangıç tarihi minimum olan datayı her hangi bir formatta verme şansın var mı?
@
Hayati
link kodda var
7040 rakamı vermiştim gözünden kaçmış olabilir tam halini veriyorum
Kod:
https://altin.in/grafikur.asp?did=flash_grafik&ca=1&islem=gunluk&sa=sat&kur=GA&banka=altin&k=&gun=7040
@
mrmarman Projeyi derleme şansım yok, sana zahmet vermeyeceksem, başlangıç tarihi minimum olan datayı her hangi bir formatta verme şansın var mı?
[/quote]
@
mrmarman O kadar da her hangi bir format demek istemedim ama hallettim abi sağ olasın var olasın, teşekkür ederim
def fix_turkish_chars(text):
replacements = {
'ÄŸ': 'ğ',
'İ': 'İ',
'ı': 'ı',
'ç': 'ç',
'ö': 'ö',
'ÅŸ': 'ş',
'ü': 'ü',
'Ç': 'Ç',
'Ö': 'Ö',
'Åž': 'Ş',
'Ü': 'Ü'
}
for wrong, correct in replacements.items():
text = text.replace(wrong, correct)
return text
def extract_data(content, start_date='"02 Mayıs 2006"', end_date='"09 Ağustos 2025"'):
price_start = content.find('satis:[') + 7
price_end = content.find(']', price_start)
prices = [float(x.strip()) for x in content[price_start:price_end].split(',')]
date_part = content[content.find(start_date):]
dates = []
current_pos = 0
while True:
quote1 = date_part.find('"', current_pos)
if quote1 == -1:
break
quote2 = date_part.find('"', quote1 + 1)
if quote2 == -1:
break
date_str = date_part[quote1 + 1:quote2]
if not any(char.isdigit() for char in date_str):
current_pos = quote2 + 1
continue
date_str = fix_turkish_chars(date_str)
dates.append(date_str)
current_pos = quote2 + 1
if end_date.strip('"') in date_str:
break
return prices[:len(dates)], dates
def create_csv(prices, dates, filename):
with open(filename, 'w', encoding='utf-8-sig') as f: # UTF-8 BOM
f.write("Tarih,Altın Fiyatı (TL)\n")
for date, price in zip(dates, prices):
f.write(f'"{date}",{price}\n')
def main():
try:
with open('data.txt', 'r', encoding='utf-8') as f:
content = f.read()
content = fix_turkish_chars(content)
prices, dates = extract_data(content,
start_date='"02 Mayıs 2006"',
end_date='"09 Ağustos 2025"')
if len(prices) != len(dates):
min_len = min(len(prices), len(dates))
prices = prices[:min_len]
dates = dates[:min_len]
print(f"Uyarı: {len(prices)} fiyat, {len(dates)} tarih bulundu. İlk {min_len} kayıt kullanıldı.")
create_csv(prices, dates, 'altin_fiyatlari.csv')
print(f"Başarılı: {len(dates)} günlük kayıt oluşturuldu.")
except FileNotFoundError:
print("Hata: data.txt dosyası bulunamadı!")
except Exception as e:
print(f"Beklenmeyen hata: {str(e)}")
if __name__ == "__main__":
main()