Penguen

Üstün
Katılım
23 Ocak 2024
Mesajlar
642
Makaleler
5
Çözümler
11
Beğeniler
996
Yer
Orion Arm
Python ve BeautifulSoup4 kütüphanesini kullanarak basit bir web scraping projesi denedim. Sizce nasıl? Kodda iyileştirilebilecek yerler var mı?
Program çalıştırıldıktan sonra sadece akşam 22:00'a kadar veri almak üzere kodlandı.

Python:
import os
import requests
from bs4 import BeautifulSoup
import schedule
import time
from datetime import datetime, timedelta

current_dir = os.path.dirname(os.path.abspath(__file__))
csv_file_path = os.path.join(current_dir, "online_members_data.csv")

def save_data(member_count, guest_count, total_count):
    with open(csv_file_path, "a") as file:
        now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        file.write(f"{now},{member_count},{guest_count},{total_count}\n")

def fetch_data():
    url = "https://techolay.net/sosyal/"
    response = requests.get(url)
    if response.status_code == 200:
        soup = BeautifulSoup(response.content, "html.parser")
        online_info = soup.find("span", class_="block-footer-counter")
        if online_info:
            text = online_info.get_text()
            total, member, guest = parse_online_info(text)
            save_data(member, guest, total)
        else:
            print("Çevrimiçi üye sayısı bilgisi bulunamadı.")
    else:
        print(f"Veri alınamadı. {response.status_code}")

def parse_online_info(text):
    total = int(text.split("Toplam:")[1].split("(")[0].strip())
    member = int(text.split("üye:")[1].split(",")[0].strip())
    guest = int(text.split("misafir:")[1].split(")")[0].strip())
    return total, member, guest

def schedule_jobs():
    fetch_data()

    now = datetime.now()
    next_hour = (now + timedelta(hours=1)).replace(minute=0, second=0, microsecond=0)
    next_run_time = next_hour.strftime("%H:%M")
    
    schedule.every().day.at(next_run_time).do(fetch_data)
    for hour in range(next_hour.hour + 1, 22):
        schedule.every().day.at(f"{hour:02d}:00").do(fetch_data)

if __name__ == "__main__":
    if not os.path.exists(csv_file_path):
        with open(csv_file_path, "w") as file:
            file.write("timestamp,member_count,guest_count,total_count\n")
    
    schedule_jobs()
    
    while True:
        schedule.run_pending()
        time.sleep(1)

Not: Program sadece eğitim amaçlıdır, kötü bir amacım yoktur. Program sitede yoğunluk yapmasın diye veriyi her saat başı çekmesi için ayarladım ve sürekli olarak kullanmadım, sadece testler için çalıştırdım ve sürekli açık tutmadım. Böyle bir kodun paylaşımı yasaksa moderatörler konuyu onaylamazsa mutlu olurum.
 
Son düzenleyen: Moderatör:
Çalışmaya başladıktan sonra ilk veriyi alıyor, sonra her saat başı (Kağıt üzerinde yani. Uzun süre test edemedim.) bir veri daha ekleniyor.
Kod:
timestamp,member_count,guest_count,total_count
2024-06-22 17:05:55,162,147,309
CSV formatında kaydediyor.
 
Sizce nasıl? Kodda iyileştirilebilecek yerler var mı?

Elinize sağlık, gayet hoş olmuş. İyileştirmeden ziyade yalnızca birkaç nokta üzerinde durmak isterim:
  1. Programı durdurup tekrar çalıştırınca CSV dosyasındaki önceki verileri silip üstüne yazıyor. Bunun için sütun isimlerini yazmadan önce dosyanın varlığını kontrol etmenin iyi olabileceğini düşündüm:
    Python:
    if not os.path.exists(csv_file_path):
        with open(csv_file_path, "w") as file:
            file.write("timestamp,member_count,guest_count,total_count\n")

  2. schedule_jobs, program hangi saatte çalıştırıldıysa -h diyelim- her gün [h, 21] saatleri arasında zamanlama yapıyor. Örneğin bugün saat 17'de çalıştırılan program, yarın da 17'den 21'e kadar görevi çalıştırır. Böyle olmasını istemiyorsanız next_hour mantığı yerine direkt for hour in range(0, 22) yapılabilir gibi geldi. schedule.every().day.at(next_run_time).do(fetch_data) satırına da gerek yok gibi, o da döngüye dahil edilebilir. Tabii bir de saat 22:00 dahil edilmiyor galiba.

  3. schedule_jobs'ta direkt schedule.every().hour.do(fetch_data) yapıp fetch_data'da datetime.now().hour'u kullanıp görevin çalışıp çalışmaması gerektiğine karar veresim geldi:
    Python:
    def schedule_jobs():
        fetch_data()
        schedule.every().hour.do(fetch_data)

    Python:
    def fetch_data():    
        if datetime.now().hour > 22:
            return
        ...

    Sırf kodu kısaltmak için. Bu biraz tercihe bağlı.
 
Programı durdurup tekrar çalıştırınca CSV dosyasındaki önceki verileri silip üstüne yazıyor. Bunun için sütun isimlerini yazmadan önce dosyanın varlığını kontrol etmenin iyi olabileceğini düşündüm:
Öneriniz için teşekkürler hocam, kodu düzenleyip ekleyeceğim. Mantıklıymış.
Tabii bir de saat 22:00 dahil edilmiyor galiba.
Evet, 22:00 ve sonrası dahil edilmiyor.
SQLite database'ine kaydetse çok iyi olur. Techolay'ın gelişimini veritabanına kaydetmiş oluruz, vds'de 7/24 çalıştıririm kodu.
Kodun temelini alıp geliştirmeye devam edebilirsiniz hocam. SQLite veritabanları hakkında bilgim yok. Forumun gelişimini takip etmek için güzel bir fikir.