KefenGroup / turistomer-server

Server part of the 2023-2024 Spring Computer Science Final Project TOBB University of Economics and Technologies
0 stars 0 forks source link

Restoran Data Scraping #13

Closed TunaOzk closed 8 months ago

TunaOzk commented 8 months ago

Görev Açıklaması

Kullanıcılara isterleri kapsamında restoran önermeleri yapılacaktır. Bu önermelerin gerçekleştirilebilimesi adına restoran verisi toplanmalıdır.

Görev Gereksinimleri ve Yapılacaklar

Restoran verilerinin TripAdvisor sitesi üzerinden çekilmesi planlanmaktadır. Çekilecek olan restoran verilerinin özellikleri aşağıda belirtilmiştir:

Restoran

Çekilen bu verilerle birlikte kullanıcıların isterlerine şehir, ucuzluk/pahalılık, bir restoranın diğer insanlar tarafından beğenilme durumu, yol tarifi için konum bilgisi ,restoranın sunduğu yemeklerin genel kategorileri gibi faktörlerle cevap verebilir hale gelinmektedir.

Yapılacaklar

Yazılım Tasarımı

Data Scraping için Beautiful Soup ve Selenium kullanılacaktır. Beautiful Soup raw HTML scraping yapılırken, Selenium ise JS tabanlı HTML scraping (interaktif elementlerle (buton, form submission vb.) etkileşime geçmek için) yapılırken kullanılacaktır.

Beautiful Soup

Beautiful Soup kullanımında, istenilen URL bağlıntılarına request atılmalı. Bahsedilen bu request atılma işlemi python kütüphanesi olan request ile yapılacaktır. Atılan request'in sonucunda gelen response ile, ilgili URL bağlantısının raw HTML'ine erişebilir hale geliniyor. Sonrasında Beautiful Soup içerisinde oluşturulan bir arama objesi ile istenilen veriler çekiliyor. Aşağıda proje kapsamında yapılmış Beautiful Soup'un kullanımını göstermek amacıyla bir kod dizini yer alıyor:

for div in bsobj.find_all('div', {'class': 'VDEXx u Ff K'}):
    is_sponsored = div.find('div', {'class': 'ngpKT d WywIO'})
    if is_sponsored == None:
        name = div.find('div', {'class': 'biGQs _P fiohW alXOW NwcxK GzNcM ytVPx UTQMg RnEEZ ngXxk'})
        link = name.find('a')['href']

Selenium

Selenium kullanımı daha zor ve karmaşık iken Beautiful Soup'a göre daha güçlü bir ver toplama aracıdır. Selenium ile veri toplanırken veriyi çekecek olan bir script (crawler) yazılacaktır. Bu script, arka planda bir chromium tabanlı tarayıcıyı gerçek zamanlı açıp veriyi oradan çekecektir. Aşağıda proje kapsamında yapılmış Selenium'un kullanımını göstermek amacıyla bir kod dizini yer alıyor:

    def selenium_click(self, class_name ,last_page=None, last_checkbox_index=0):
        with open(self.path, "a", encoding="utf-8") as file:
            try:
                #region OPTIONS
                software_names = [SoftwareName.CHROME.value]
                operating_systems = [OperatingSystem.WINDOWS.value,
                                    OperatingSystem.LINUX.value]
                user_agent_rotater = UserAgent(software_names=software_names,
                                            operating_systems=operating_systems,
                                            limit=100)
                user_agent = user_agent_rotater.get_random_user_agent()

                chrome_options = Options()
                # chrome_options.add_argument("--headless")
                chrome_options.add_argument("--no-sandbox")
                chrome_options.add_argument("--window-size=1420,1080")
                chrome_options.add_argument("--disable-gpu")
                chrome_options.add_argument(f'user-agent={user_agent}')
                #endregion

                browser = uc.Chrome(driver_executable_path=latestchromedriver ,options=chrome_options)

                if last_page:
                    browser.get(last_page)
                else:
                    browser.get(self.url)

                sleep(3)
                cookie = WebDriverWait(browser, 20).until(
                    EC.presence_of_element_located((By.ID, "onetrust-cookie-btn-container"))
                )
                cookie.click()
                sleep(1)
                denied = WebDriverWait(browser, 20).until(
                    EC.presence_of_element_located((By.CSS_SELECTOR, ".ot-pc-refuse-all-handler"))
                )
                denied.click()

                skip = False
                prev_checkbox = None
                if last_checkbox_index != 0:
                    skip = True
                for index in range(last_checkbox_index, len(checkbox_dict)):
                    checkbox, checkbox_value = checkbox_dict[index]
                    checkbox = f"[for='{checkbox}']"
                    if not skip:
                        skip = False
                        try:
                            if prev_checkbox:
                                prev_checkbox_ele = WebDriverWait(browser, 10).until(
                                    EC.element_to_be_clickable((By.CSS_SELECTOR, prev_checkbox))
                                )
                                browser.execute_script("arguments[0].scrollIntoView(true);", prev_checkbox_ele)
                                browser.execute_script("window.scrollBy(0,-100);")
                                prev_checkbox_ele.click()
                                sleep(3)

                            try:
                                expand_styles = WebDriverWait(browser, 4).until(
                                    EC.element_to_be_clickable((By.CSS_SELECTOR, "[aria-controls='filter-expando-styles']"))
                                )
                                browser.execute_script("arguments[0].scrollIntoView(true);", expand_styles)
                                browser.execute_script("window.scrollBy(0,-100);")
                                if expand_styles.get_attribute("aria-expanded") == "false":
                                    expand_styles.click()
                            except (TimeoutException) as e:
                                print("Expand more is not available for styles filters.")

                            checkbox_ele = WebDriverWait(browser, 10).until(
                                EC.element_to_be_clickable((By.CSS_SELECTOR, checkbox))
                            )
                            browser.execute_script("arguments[0].scrollIntoView(true);", checkbox_ele)
                            browser.execute_script("window.scrollBy(0,-100);")
                            checkbox_ele.click()

Görev Çıktısı

Görev sonucunda kullanıcılar arayüz üzerinden isterlerini backend'e taşıdıktan sonra ilgli restoranların bilgileri kullancılara sunulması beklenmektedir.