【问题标题】:Splinter Click on "Popup" Cookies Privacy Agreement + Splinter Wait For Element to Load?Splinter 单击“弹出”Cookie 隐私协议 + Splinter 等待元素加载?
【发布时间】:2023-03-15 20:53:02
【问题描述】:

---------大家好!

这里有两个问题。

我正在学习网络抓取,并正在为我玩的游戏创建一个自定义项目来尝试它。我试图从中抓取的网址是:https://paladins.guru/profile/4894277-TofuCookies/champions

我遇到了两个问题:

问题 1:Splinter 无法点击“隐私/Cookie 按钮”

每次我用我的代码打开网页时都会出现这个弹出窗口。我单击按钮上的检查并尝试使用类无济于事.find_by_text().find_by_id()。 (其他.find_by 在这种情况下没有意义。)我认为这里的问题是这个弹出窗口的按钮也是通过Javascript 生成的,因此无法抓取它。此弹出窗口也不在新窗口中。

问题 2:如何在 Splinter 中“等待”?

因此,每个字符块(以黄色突出显示)都有其自己的随附高级信息表,我想抓取这些高级信息表(以红色标出)。但是,您一次只能查看一张高级表格,这意味着如果我想查看第二个字符“Yagorath”的表格,我需要点击“Yagorath”div,这将隐藏与“ Jenos”并展示了“Yagorath”表。

在我的代码中,我相信我已经成功地点击了相关的 div 标签,但是该高级表格需要一个加载时间才能显示在页面上。在我的代码中,我只是在快速单击 div,并且由于在单击下一个 div 之前表格永远没有机会加载,因此刮板对于所有值都返回空。

这是我的代码,以防有人想检查。

# Import dependencies
from splinter import Browser
from bs4 import BeautifulSoup as bs
from webdriver_manager.chrome import ChromeDriverManager

# Connecting to site
executable_path = {'executable_path': ChromeDriverManager().install()}
browser = Browser('chrome', **executable_path, headless=False)

# Visiting site
url = 'https://paladins.guru/profile/4894277-TofuCookies/champions'
browser.visit(url)

# Fetch raw html, parse into BS object
soup = bs(browser.html, 'html.parser')

# Create storage variables for building df
all_df_headers = ['Champion']
all_champ_data = []
is_first_champion = True

# Click the privacy agree button
# browser.click_link_by_id('div[class=" css-47sehv"]')
# ------- NEED TO CLICK THE ACCEPT BUTTON HERE -----------

# Scrape every champion row from BS object
champ_rows = soup.find_all('div', class_ = 'row champion-table__row')
for champ in champ_rows:
    # Temp storage variables
    curr_champ_data = []

    # Scrape champion name
    curr_name = champ.find('div', class_ = 'row__champion__name').text
    curr_champ_data.append(curr_name)

    # Click to reveal statistics (but only if its not the first champion because site comes loaded with stats revealed for first champion)
    if is_first_champion == False:
        target = 'div[class="row champion-table__row"]'
        browser.find_by_tag(target).click()
        # ------- NEED A WAIT TIMER HERE ----------- 
    
    # Scrape every statistic per champion
    statistics = champ.find_all('div', class_ = 'column col-2 col-sm-4')
    for stat in statistics:
        # Scrape statistic header (but only if its the first champion)
        if is_first_champion == True:    
            curr_header = stat.find('div', class_='percentile-stat__label text-ellipsis text-uppercase').text.strip()
            if curr_header not in all_df_headers:
                all_df_headers.append(curr_header)

        # Scrap statistic value
        curr_value = stat.find('div', class_='percentile-stat__value c-help col-11').text.strip()
        curr_champ_data.append(curr_value)
    
    # Append finished champ data list to mega list
    all_champ_data.append(curr_champ_data)

    # Adjust boolean so no longer scrap header for all subsequent champions (since all champs will have same statistics headers)
    is_first_champion = False

# Close browser when done
browser.quit()

【问题讨论】:

    标签: python selenium web-scraping popup splinter


    【解决方案1】:

    我无法回答您的实际问题,但我可以帮助您获取您想要的数据...这太长了,无法发表评论。

    在使用该站点时,我发现了一些后端 api,它们将帮助您获得所需的数据,首先是所有用于加载统计数据的数据:https://api.paladins.guru/v3/profiles/4894277-TofuCookies/champions

    每个冠军都有一个 url(你需要这个来从上面链接中的代码中获取名称):https://api.paladins.guru/v3/champions

    你可以像这样得到你想要的数据:

    import requests
    import pandas as pd
    
    champ_url = 'https://api.paladins.guru/v3/champions'
    champs = requests.get(champ_url).json()
    
    stats_url = 'https://api.paladins.guru/v3/profiles/4894277-TofuCookies/champions'
    stats = requests.get(stats_url).json()
    
    details = []
    for champ in stats['champions']['-1']: #-1 is the total queue I think, there are 7 other queues, but they are encoded: 424, 428, 237, 452, 465, 469, 468
        info = stats['champions']['-1'][champ]['total']
        info['champion'] = champs[champ]['name'] #add in real name from champs data above
    
        details.append(info)
    
    df = pd.DataFrame(details)
    df.to_csv('palandin_data.csv', index=False)
    print('Saved to paladins.csv')
    

    【讨论】:

    • 非常感谢!我知道 Paladins API,并且可以看到您的方法肯定会更快、更干净地查询信息!但是,我主要对了解有关网络抓取的更多信息感兴趣,因此很遗憾需要继续寻找。不过,谢谢!
    猜你喜欢
    • 1970-01-01
    • 2018-07-17
    • 1970-01-01
    • 2013-09-11
    • 1970-01-01
    • 2014-10-08
    相关资源
    最近更新 更多