Python 3.x Web数据抓取:通过选择下拉菜单获取所有数据

Python 3.x Web数据抓取:通过选择下拉菜单获取所有数据,python-3.x,web-scraping,drop-down-menu,Python 3.x,Web Scraping,Drop Down Menu,我正在尝试从中获取数据 但面临一个问题,尤其是下拉列表(“按年份筛选”) 我能够在下拉列表中检索姓名,即20202019,。等 但无法检索每个列表元素的数据 当我们点击“按年份过滤”列表时,会出现一个下拉列表,然后在赛季(年份)中,球员会发生变化(我们会得到当年赛季的球员以及总结)。 我想按赛季获得每个球员的数据。 当我们点击下拉列表时,也不会创建新的URL 我找不到任何解决办法。 使用以下python代码从下拉列表中检索季节/年份值 Python代码 squad_url= "

我正在尝试从中获取数据 但面临一个问题,尤其是下拉列表(“按年份筛选”)

我能够在下拉列表中检索姓名,即20202019,。等 但无法检索每个列表元素的数据

当我们点击“按年份过滤”列表时,会出现一个下拉列表,然后在赛季(年份)中,球员会发生变化(我们会得到当年赛季的球员以及总结)。 我想按赛季获得每个球员的数据。 当我们点击下拉列表时,也不会创建新的URL

我找不到任何解决办法。 使用以下python代码从下拉列表中检索季节/年份值

Python代码

    squad_url= "https://www.iplt20.com/teams/sunrisers-hyderabad/squad"
    driver = webdriver.Chrome(executable_path=".\chromedriver.exe")
    driver.get(squad_url)
    html = driver.page_source
    soup2 = BeautifulSoup(''.join(html), 'html.parser')
    for llist in soup2.find_all("ul",class_="drop-down__dropdown-list"):
        for year in llist.find_all("li"):
            print(year.text)
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
import time
from selenium.common.exceptions import WebDriverException
下拉列表的html代码片段如下

<div class="large-squad-list__filter single-filter">
        <div class="stats-table__filter drop-down js-drop-down is-open">
            <div class="drop-down__clickzone js-dropdown-trigger" tabindex="0" role="button"></div>
            <div class="drop-down__label js-drop-down-label">Filter by Year</div>
            <div class="drop-down__current js-drop-down-current">2020</div>
            <ul class="drop-down__dropdown-list js-drop-down-options">
                <li tabindex="0" role="button" class="drop-down__dropdown-list__option" data-option="ipl2020">2020</li>
                <li tabindex="0" role="button" class="drop-down__dropdown-list__option" data-option="ipl2019">2019</li>
                <li tabindex="0" role="button" class="drop-down__dropdown-list__option" data-option="ipl2018">2018</li>
                <li tabindex="0" role="button" class="drop-down__dropdown-list__option" data-option="ipl2017">2017</li>
                <li tabindex="0" role="button" class="drop-down__dropdown-list__option" data-option="ipl2016">2016</li>
                <li tabindex="0" role="button" class="drop-down__dropdown-list__option" data-option="ipl2015">2015</li>
                <li tabindex="0" role="button" class="drop-down__dropdown-list__option" data-option="ipl2014">2014</li>
                <li tabindex="0" role="button" class="drop-down__dropdown-list__option" data-option="ipl2013">2013</li>
                <li tabindex="0" role="button" class="drop-down__dropdown-list__option" data-option="ipl2012">2012</li>
                <li tabindex="0" role="button" class="drop-down__dropdown-list__option" data-option="ipl2011">2011</li>
                <li tabindex="0" role="button" class="drop-down__dropdown-list__option" data-option="ipl2010">2010</li>
                <li tabindex="0" role="button" class="drop-down__dropdown-list__option" data-option="ipl2009">2009</li>
                <li tabindex="0" role="button" class="drop-down__dropdown-list__option" data-option="ipl2008">2008</li>
            </ul>
        </div>
    </div>
    driver.execute_script("return arguments[0].scrollIntoView(true);", element)
    
    time.sleep(3)
    driver.execute_script("window.scrollBy(0, -100);")
    time.sleep(2)
    #above code ensures drop list is visible, otherwise we get errors of non clickable etc.

    element = driver.find_element_by_class_name("stats-table__filter")
    season_element = element.find_elements_by_tag_name("li")
    for season in season_element:
        action.move_to_element_with_offset(element,0,0).perform()
        element.click()
        action.move_to_element_with_offset(season,0,0).perform()
        time.sleep(2) 

        try:
            print("clicking:",season.text )
            season.click()
        except WebDriverException:
            print("Not clickable", season.text)
            break

按年过滤
2020
    2020年 2019年 2018年 2017年 2016年 2015年 2014年 2013年 2012年 2011年 2010年 2009年 2008年

这可能只是部分答案,但它确实得到了你想要的(统计数据)

问题是,数据是由JS动态加载的。但是,如果您查看流量(检查开发者工具->网络),您将看到有一个发送到API的请求

您可以获取该url并解析响应

这正是代码所做的:

import requests


_ids = [18790, 10192, 7749, 5815, 3957, 2785, 2374, 605]


for _id in _ids:
    url = f"https://cricketapi.platform.iplt20.com/stats/" \
          f"players?teamIds=62&tournamentIds={_id}&scope=TOURNAMENT&pageSize=30"
    response = requests.get(url).json()
    print(f"Printing stats for {response['team']['fullName']}")
    for player in response['stats']['content']:
        print(f"{player['player']['fullName']} - {player['stats']}")
然而,我无法确定锦标赛的来源。此外,没有2013年的数据

样本输出(为简洁起见,仅为其一部分):


经过整整一天的努力,我终于做到了:

在代码中导入以下内容

    squad_url= "https://www.iplt20.com/teams/sunrisers-hyderabad/squad"
    driver = webdriver.Chrome(executable_path=".\chromedriver.exe")
    driver.get(squad_url)
    html = driver.page_source
    soup2 = BeautifulSoup(''.join(html), 'html.parser')
    for llist in soup2.find_all("ul",class_="drop-down__dropdown-list"):
        for year in llist.find_all("li"):
            print(year.text)
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
import time
from selenium.common.exceptions import WebDriverException
下面的Python代码

<div class="large-squad-list__filter single-filter">
        <div class="stats-table__filter drop-down js-drop-down is-open">
            <div class="drop-down__clickzone js-dropdown-trigger" tabindex="0" role="button"></div>
            <div class="drop-down__label js-drop-down-label">Filter by Year</div>
            <div class="drop-down__current js-drop-down-current">2020</div>
            <ul class="drop-down__dropdown-list js-drop-down-options">
                <li tabindex="0" role="button" class="drop-down__dropdown-list__option" data-option="ipl2020">2020</li>
                <li tabindex="0" role="button" class="drop-down__dropdown-list__option" data-option="ipl2019">2019</li>
                <li tabindex="0" role="button" class="drop-down__dropdown-list__option" data-option="ipl2018">2018</li>
                <li tabindex="0" role="button" class="drop-down__dropdown-list__option" data-option="ipl2017">2017</li>
                <li tabindex="0" role="button" class="drop-down__dropdown-list__option" data-option="ipl2016">2016</li>
                <li tabindex="0" role="button" class="drop-down__dropdown-list__option" data-option="ipl2015">2015</li>
                <li tabindex="0" role="button" class="drop-down__dropdown-list__option" data-option="ipl2014">2014</li>
                <li tabindex="0" role="button" class="drop-down__dropdown-list__option" data-option="ipl2013">2013</li>
                <li tabindex="0" role="button" class="drop-down__dropdown-list__option" data-option="ipl2012">2012</li>
                <li tabindex="0" role="button" class="drop-down__dropdown-list__option" data-option="ipl2011">2011</li>
                <li tabindex="0" role="button" class="drop-down__dropdown-list__option" data-option="ipl2010">2010</li>
                <li tabindex="0" role="button" class="drop-down__dropdown-list__option" data-option="ipl2009">2009</li>
                <li tabindex="0" role="button" class="drop-down__dropdown-list__option" data-option="ipl2008">2008</li>
            </ul>
        </div>
    </div>
    driver.execute_script("return arguments[0].scrollIntoView(true);", element)
    
    time.sleep(3)
    driver.execute_script("window.scrollBy(0, -100);")
    time.sleep(2)
    #above code ensures drop list is visible, otherwise we get errors of non clickable etc.

    element = driver.find_element_by_class_name("stats-table__filter")
    season_element = element.find_elements_by_tag_name("li")
    for season in season_element:
        action.move_to_element_with_offset(element,0,0).perform()
        element.click()
        action.move_to_element_with_offset(season,0,0).perform()
        time.sleep(2) 

        try:
            print("clicking:",season.text )
            season.click()
        except WebDriverException:
            print("Not clickable", season.text)
            break
以上逻辑仅包含如何单击下拉列表的信息。 但随着它,动态数据被加载(我已经从driver.page_source输出中确认)

请求的问题库是未加载动态数据。 但是使用硒可以很容易地做到这一点

我添加了睡眠,以确保滚动已完成。 我在很多地方阅读而不是睡觉,我可以使用WebDriverWait,但我无法让它们工作

我非常确定可以有优化的版本。
(如果找到一个,请在这里发布)

您正在刮取
iplt20
,但仍列为
ipl2020
(否
t
),这是故意的吗?是的,我只发布了我的部分代码,在我的实际代码中,我可以传递哪一年/季节(20202019等)我需要数据。命名约定也与季节年保持一致,以保持一致性和可读性,这就是为什么我更喜欢这种方式是的,在互联网上查看后,我发现硒是解决此问题的答案:)