Webscrapping - Селен - Питон - PullRequest
       9

Webscrapping - Селен - Питон

0 голосов
/ 25 января 2019

Я хочу извлечь все фантазийные команды, которые были введены для прошлых конкурсов.Чтобы перебрать даты, я просто изменяю небольшую часть URL, как показано в моем коде ниже:

#Packages:

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
import pandas as pd


# Driver
chromedriver =("C:/Users/Michel/Desktop/python/package/chromedriver_win32/chromedriver.exe")
driver = webdriver.Chrome(chromedriver)

# Dataframe that will be use later 
results = pd.DataFrame()
best_lineups=pd.DataFrame()
opti_lineups=pd.DataFrame()

#For loop over all DATES:

calendar=[]
calendar.append("2019-01-10")
calendar.append("2019-01-11")

for d in calendar:
    driver.get("https://rotogrinders.com/resultsdb/date/"+d+"/sport/4/")

Затем, чтобы получить доступ к различным конкурсам того дня, вам нужно нажать на contest таб.Я использую следующий код, чтобы найти и нажать на него.

 # Find "Contest" tab   
    contest= driver.find_element_by_xpath("//*[@id='root']/div/main/main/div[2]/div[3]/div/div/div[1]/div/div/div/div/div[3]")
    contest.click()

Я просто проверяю и копирую xpath вкладки.Тем не менее, в большинстве случаев это работает, но иногда я получаю сообщение об ошибке «Не удается найти элемент ...».Более того, кажется, что это работает только для первого свидания в моем цикле календаря и всегда терпит неудачу в следующей итерации ... Я не знаю почему.Я пытаюсь найти его по-другому, но я чувствую, что мне не хватает чего-то, например:

contests=driver.find_element_by_xpath("//*[@role='tab']

После того, как вкладка конкурса успешно нажата, все конкурсы в этот день есть, и вы можете нажать на ссылку, чтобыполучить доступ ко всем записям этого конкурса.Я сохранил конкурсы, чтобы выполнить итерацию всех следующим образом:

    list_links = driver.find_elements_by_tag_name('a')
    hlink=[]
    for ii in list_links:
        hlink.append(ii.get_attribute("href"))
    sub="https://rotogrinders.com/resultsdb"
    con= "contest"
    contest_list=[]
    for text in hlink:
        if sub in text:
            if con in text:
                contest_list.append(text)
# Iterate through all the entries(user) of a contest and extract the information of the team entered by the user 

    for c in contest_list:
        driver.get(c)

Затем я хочу извлечь команду всех участников, участвовавших в конкурсе, и сохранить ее в информационном кадре.Я могу сделать это успешно на первой странице конкурса.

# Waits until tables are loaded and has text. Timeouts after 60 seconds
        while WebDriverWait(driver, 60).until(ec.presence_of_element_located((By.XPATH, './/tbody//tr//td//span//a[text() != ""]'))):

# while ????: 

# Get tables to get the user names
            tables = pd.read_html(driver.page_source)
            users_df  = tables[0][['Rank','User']]
            users_df['User'] = users_df['User'].str.replace(' Member', '')

# Initialize results dataframe and iterate through users

            for i, row in users_df.iterrows():

                rank = row['Rank']
                user = row['User']

    # Find the user name and click on the name
                user_link = driver.find_elements(By.XPATH, "//a[text()='%s']" %(user))[0]
                user_link.click()

    # Get the lineup table after clicking on the user name
                tables = pd.read_html(driver.page_source)
                lineup = tables[1]

    #print (user)
    #print (lineup)

    # Restructure to put into resutls dataframe
                lineup.loc[9, 'Name'] = lineup.iloc[9]['Salary']
                lineup.loc[10, 'Name'] = lineup.iloc[9]['Pts']

                temp_df = pd.DataFrame(lineup['Name'].values.reshape(-1, 11), 
                columns=lineup['Pos'].iloc[:9].tolist() + ['Total_$', 'Total_Pts'] )

                temp_df.insert(loc=0, column = 'User', value = user)
                temp_df.insert(loc=0, column = 'Rank', value = rank)
                temp_df["Date"]=d
                results = results.append(temp_df)
            #next_button = driver.find_elements_by_xpath("//button[@type='button']")
            #next_button[2].click()



            results = results.reset_index(drop=True)



driver.close()

Однако есть и другие страницы, и для доступа к ним вам нужно нажать на маленькую стрелку next button внизу.Более того, вы можете бесконечно нажимать на эту кнопку;даже если нет больше записей.Поэтому я хотел бы иметь возможность просматривать все страницы с записями и останавливаться, когда больше нет записей, и менять конкурс.Я пытаюсь реализовать цикл while для этого, но мой код не работает ...

1 Ответ

0 голосов
/ 25 января 2019

Вы должны действительно убедиться, что страница полностью загружается, прежде чем что-либо делать на этой странице.

Более того, кажется, что это работает только для первого свидания в моем календаре и всегда терпит неудачу в следующей итерации

Обычно, когда selenium загружает страницу браузера, он пытается найти элемент, даже если он загружен не полностью. Я предлагаю вам перепроверить xpath элемента, на который вы пытаетесь щелкнуть.

Также попробуйте посмотреть, когда страница полностью загрузится, и используйте time.sleep(number of seconds) чтобы убедиться, что вы нажали на элемент, или вы можете проверить наличие определенного элемента или свойства элемента, которое сообщит вам, что страница загружена.

Еще одно предложение заключается в том, что вы можете использовать driver.current_url, чтобы увидеть, на какую страницу вы ориентируетесь. У меня была эта проблема, когда я работал над несколькими вкладками, и мне пришлось сказать python / selenium, чтобы вручную переключиться на эту вкладку

...