Pyhton Web Scrapping' de Thread Kullanımı

Merhabalar, şu anda bir siteden bir milyon küsür veriyi çekecek bir proje yazdım. Ancak proje çok yavaş çalışıyor. Bu işlemi link toplayarak 3 partta yapıyorum. Kodlarım çok uzun olduğu için ne yazık ki paylaşamıyorum. Sadece fikir almak istedim. Bu işlemi aynı anda birden fazla tarayıcı çalıştırarak yapmak sanıyorum mümkün. Bu işlemi nasıl yapabilirim, yani multiple driver işlemini nasıl yapabilirim? Thread gibi birkaç yöntem buldum. En güzel çözüm hangisi olur? Desteklerinizi rica ediyorum.

ne yazık ki çok fazla driver çalıştırıldığında cpu’ya ve ramlere aşırı yüklenme olduğundan 10 browser ya da tab çalıştırdığınızda 3 tanesi veriyi getirirken diğer 7 tanesi beklemede kalıyor. api scraping mümkünse bunu denemekte fayda var.

1 Beğeni

yukarıda yazdığım sizin için geçerli değilse (güçlü bir bilgisayarınız varsa) aşağıdaki kaynakları araştırabilirsiniz.

https://splash.readthedocs.io/en/stable/

1 Beğeni

Teşekkür ediyorum, deneyeceğim.

kodlari inceleyebilirsiniz, bir arkadasin istegi dogrultusunda hazirlamistim. mantigi kisaca ozetliyim; sizinle paylastigim kodlar client kodlari, sunucudan gelen komutlar dogrultusunda hareket ediyor,
sunucudan aldigi komut dogrultusunda thread kullanarak tarayici pencerelerini aciyor(chrome_1.exe, chrome_2.exe, vs.), her tarayici penceresinin farkli ip adresinden cikmasi icin de proxifier uygulamasi ile her exe icin kural olusturuyoruz.

from time import sleep
from socket import socket
from threading import Thread

def getNumberOfClients():
    c = socket()
    ip = "localhost"
    port = 1234
    c.connect((ip, port))
    c.send(bytes("main", 'utf-8'))
    while True:
        msg = c.recv(1024).decode()
        c.close()
        return int(msg)

numberOfClients = getNumberOfClients()
chromeDir = "C:\\Program Files\\Google\\Chrome\\Application\\"

def cloneDriver(numberOfClients, chromeDir):
    from shutil import copyfile
    from os.path import exists
    from os import remove

    for i in range(1, numberOfClients+1):
        src = chromeDir + "chrome.exe"
        newExe = "chrome_" + str(i) + ".exe"
        dst = chromeDir + newExe
        if(exists(dst)):
            remove(dst)
            print(newExe + " silindi..")
            copyfile(src, dst)
            print(newExe + " olusturuldu")
        else:
            copyfile(src, dst)

cloneDriver(numberOfClients, chromeDir)


def Starter(nickName, counter):
    from selenium import webdriver
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver.chrome.options import Options
    from selenium.webdriver.common.keys import Keys

    options = Options()
    options.add_experimental_option("excludeSwitches", ["enable-logging"])
    options.binary_location = chromeDir + "chrome_" + str(counter) + ".exe"
    #options.add_extension('AdBlock.crx')
    #options.add_argument('--headless')

    driver = webdriver.Chrome(options=options)

    def changeTab(tabID):
        tabID = int(tabID)
        try:
            driver.switch_to.window(driver.window_handles[tabID])
            print("tab degisti")
            print(driver.title)
        except:
            print("tab bulunamadi")

    def login(nickName, counter):
        try:
            driver.get("xxx")

            try:
                username = WebDriverWait(driver, 10).until(
                    EC.presence_of_element_located((By.NAME, "username"))
                )
                username.clear()
                sleep(.2)
                username.send_keys(nickName)
            except:
                print("uyeler username input bulunamadi")
        
            try:
                password = WebDriverWait(driver, 10).until(
                    EC.presence_of_element_located((By.NAME, "password"))
                )
                password.clear()
                sleep(.2)
                password.send_keys("xx123xx")
            except:
                print("uyeler password input bulunamadi")
            
            try:
                loginButton = WebDriverWait(driver, 10).until(
                    EC.presence_of_element_located((By.XPATH, "/html/body/div[1]/div/form/input[8]"))
                )
                sleep(.2)
                loginButton.click()
            except:
                print("uyeler login button bulunamadi")

            print(str(counter) + " - " + nickName + " login oldu")

        except:
            print(nickName + " login olamadi")
    
    def changeFrame(frameName):
        driver.switch_to.frame(frameName)
    
    def tryAgain():
        driver.refresh()
        sleep(1)
        try:
            fcConsent = WebDriverWait(driver, 20).until(
                EC.presence_of_element_located(By.CSS_SELECTOR, "body > div.fc-consent-root")
            )

            if(fcConsent):
                driver.execute_script('document.querySelector("body > div.fc-consent-root").remove()')
        except:
            pass
        
        try:
            sleep(.2)
            changeFrame("gameFrame")
            createTableBtn = WebDriverWait(driver, 10).until(
                EC.element_to_be_clickable((By.CSS_SELECTOR, "#viewport > div.toppanel > ul.top_left_bar > li.create_table_button"))
                )
        
            if(createTableBtn):
                print("odaya girildi")
                print(driver.title)
        except:
            print("odaya girilemedi, tekrar deneniyor..")
            tryAgain()

    def joinRoom(roomURL):
        driver.execute_script('''window.open("''' + roomURL + '''","_blank");''')
        sleep(.2)
        current = driver.window_handles.index(driver.current_window_handle)
        driver.switch_to.window(driver.window_handles[current + 1])

        try:
            fcConsent = WebDriverWait(driver, 20).until(
                EC.presence_of_element_located(By.CSS_SELECTOR, "body > div.fc-consent-root")
            )

            if(fcConsent):
                driver.execute_script('document.querySelector("body > div.fc-consent-root").remove()')
        except:
            pass
        
        try:
            sleep(.2)
            changeFrame("gameFrame")
            createTableBtn = WebDriverWait(driver, 10).until(
                EC.element_to_be_clickable((By.CSS_SELECTOR, "#viewport > div.toppanel > ul.top_left_bar > li.create_table_button"))
                )
        
            if(createTableBtn):
                print("odaya girildi")
                print(driver.title)
        except:
            print("odaya girilemedi, tekrar deneniyor..")
            tryAgain()
    
    def joinTable(arg):
        try:
            driver.execute_script(arg + '.click()')
        except:
            print("masaya girilemedi")

    def createTable():
        try:
            createTableBtn = WebDriverWait(driver, 10).until(
                    EC.presence_of_element_located((By.CSS_SELECTOR, "#viewport > div.toppanel > ul.top_left_bar > li.create_table_button"))
                    )
            if(createTableBtn):
                createTableBtn.click()
                print("masa olusturuldu")
        except:
            print("masa olusturulamadi")
    
    def exitTable():
        try:
            driver.execute_script('document.querySelector("#viewport > div.toppanel > ul.top_left_bar > li.exit_from_table_button").click()')
        except:
            print("cikis butonu bulunamadi")
    
    def writeTable(swear):
        try:
            chatInput = WebDriverWait(driver, 5).until(
                EC.presence_of_element_located((By.CSS_SELECTOR, "input#user_chat_input.input_bar"))
                )
            for i in range(1, 3):
                chatInput.clear()
                sleep(.2)
                chatInput.send_keys(swear)
                sleep(.2)
                chatInput.send_keys(Keys.ENTER)
        except:
            print("masaya yazilamadi")

    def createClient(nickName, counter):
        c = socket()
        ip = "localhost"
        port = 1234
        c.connect((ip, port))
        c.send(bytes(nickName, 'utf-8'))
        login(nickName, counter)
        while True:
            msg = c.recv(1024).decode()
            msg = msg.split(",")
            
            if(len(msg) > 1):
                cmd = int(msg[0])
                arg = msg[1]
            elif(len(msg) == 1):
                cmd = int(msg[0])
            else:
                print("gecersiz komut")

            # 0 CLOSE DRIVER WINDOW
            if(cmd == 0):
                driver.close()
            
            # 1 CHANGE TAB
            elif(cmd == 1):
                changeTab(arg)
            
            # 2 JOIN ROOM
            elif(cmd == 2):
                joinRoom(arg)
            
            # 3 JOIN TABLE
            elif(cmd == 3):
                joinTable(arg)
            
            # 4 EXIT TABLE
            elif(cmd == 4):
                exitTable()
            
            # 5 CREATE TABLE
            elif(cmd == 5):
                createTable()
            
            # 6 CHAT INPUT
            elif(cmd == 6):
                writeTable(arg)
            
            # 9 CLOSE SOCKET
            elif(cmd == 9):
                c.close()

            else:
                print("geçersiz komut")
    
    createClient(nickName, counter)


def nickSelector(counter):
    nicklist = open("nicklist.txt", "r")
    nickListLines = nicklist.readlines()
    nickName = nickListLines[counter]
    nicklist.close()
    return nickName.strip()

counter = 1

while(counter <= numberOfClients):
    nickName = nickSelector(counter-1)
    t = Thread(target=Starter, args=(nickName, counter))
    t.start()
    counter += 1
    sleep(.2)

Merhabalar, ben pool kullanarak aynı anda tarayıcıyı birden fazla kez çalıştırarak verileri çekiyorum, yani eş zamanlılık prosedürü ile. Sizin bahsettiğiniz bu durum ile aynı mıdır? Yanlış ilerlememek adına teyit etmek istedim.

tasarim deseni olarak thread pool kastediyorsaniz hayir.

evet ayni anda birden fazla kez calisiyor

evet es zamanli olarak

Evet, tarayıcıyı eş zamanlı olarak birkaç defa çalıştırıyor. Örneğin pc çekirdeğine bağlı olarak 8 defa açıyor şu anda. Bundan bahsediyorsak şu an için yapıldı evet farkedilir bir hızlanma var ancak yine günler sürüyor, Bunu nasıl daha hızlı hale getirebilirim bilemiyorum. Scrapy öneriliyor, ancak şu an öğrenip projeyi baştan yazacak vaktim yok. :woman_shrugging:t3: