Użyj Selenium, aby pobrać plik, klikając „javascript: __ doPostBack ('LeaderBoard1 $ cmdCSV', '')”

Sep 12 2020

Jest kilka plików CSV ze statystykami gry w baseball, które chcę pobrać za pomocą automatyzacji, które można znaleźć pod adresem: https://www.fangraphs.com/leaders.aspx?pos=all&stats=bat&lg=all&qual=0&type=0&season=2020&month=0&season1=2020&ind=0&team=0&rost=0&age=0&filter=&players=0&startdate=2020-01-01&enddate=2020-12-31. Przycisk pobierania tabeli jako pliku CSV jest oznaczony jako „Eksportuj dane”.

HTML:

<div class="br_dby">
    <span style="float: left">
        <a href="javascript:ShowHide();">Show Filters</a>  
            |  
        <a href="#custom">Custom Reports</a>
    </span>
    <a href="javascript:__doPostBack('LeaderBoard1$cmdCSV','')" id="LeaderBoard1_cmdCSV">Export Data</a>
</div>

Jak widać, przycisk nie jest przekierowaniem do strony pobierania (w takim przypadku requestsmożna go użyć do pobrania pliku), ale jest procesem.

Kod:

from selenium import webdriver
from selenium.webdriver.firefox.options import Options
binary = r'C:\Program Files\Mozilla Firefox\firefox.exe'
options = Options()
options.headless = True
options.binary = binary
options.set_preference("browser.download.folderList",2)
options.set_preference("browser.download.manager.showWhenStarting", True)
options.set_preference("browser.download.dir", r"C:\Users\jlpyt\Downloads")
driver = webdriver.Firefox(options=options, executable_path=r"C:\Users\jlpyt\geckodriver-v0.27.0-win32\geckodriver.exe")
driver.get('https://www.fangraphs.com/leaders.aspx?pos=all&stats=bat&lg=all&qual=0&type=0&season=2020&month=0&season1=2020&ind=0&team=0&rost=0&age=0&filter=&players=0&startdate=2020-01-01&enddate=2020-12-31')
elem = driver.find_element_by_id('LeaderBoard1_cmdCSV')
elem.click()

Używając tego kodu, Selenium może kliknąć przycisk, ale pobieranie nie jest inicjowane. Czy istnieje sposób, w jaki mogę użyć Selenium, aby kliknąć przycisk i pobrać plik? A może jest jakaś alternatywna metoda, o której nie pomyślałem?

Odpowiedzi

1 DebanjanB Sep 12 2020 at 21:01

Element jest __doPostBackelementem aktywnym , więc aby kliknąć element, który chcesz wywołać WebDriverWait for the element_to_be_clickable(), możesz użyć jednej z następujących strategii lokalizacji :

  • Używając ID:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.ID, "LeaderBoard1_cmdCSV"))).click()
    
  • Używając LINK_TEXT:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.LINK_TEXT, "Export Data"))).click()
    
  • Używając CSS_SELECTOR:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a#LeaderBoard1_cmdCSV"))).click()
    
  • Używając XPATH:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[@id='LeaderBoard1_cmdCSV']"))).click()
    
  • Uwaga : musisz dodać następujące importy:

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    
  • Migawka przeglądarki:


Bibliografia

Możesz znaleźć kilka odpowiednich dyskusji w:

  • web scrapping dla javascript __doPostBack zawiera herf w td
  • Jak przeglądać numery stron, gdy href zawiera javascript: __ doPostBack ()