Web 数据抓取:通过选择下拉菜单获取所有数据 python
Web Data scraping: getting all data by selecting drop down menus python
我正在尝试从 https://www.iplt20.com/teams/sunrisers-hyderabad/squad" 获取数据
但面临一个问题,尤其是下拉列表(“按年份过滤”)。
我能够在下拉列表中检索名称,即 2020、2019,。 ETC
但无法检索每个列表元素的数据。
当我们点击按年份筛选列表时,会出现一个下拉列表,然后在赛季(年份)上,球员会发生变化(我们会得到当年打过那个赛季的球员以及概括)。
我想按赛季获取每个球员的数据。
当我们点击下拉列表
时也没有创建新的 URL
我找不到任何解决方案。
使用以下 python 代码从下拉列表中检索 season/year 值。
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)
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>
这可能只是部分答案,但它确实得到了你想要的(统计数据)。
问题是,数据是JS动态加载的。但是,如果您查看流量(检查 Developer Tool -> Network),您会看到发送到 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']}")
但是,我无法确定 tournamentIds
的来源。此外,没有 2013 年以后的数据。
示例输出(为简洁起见,仅部分输出):
Printing stats for Sunrisers Hyderabad
Yusuf Pathan - [{'matchType': 'AGG', 'battingStats': {'50s': 0, '100s': 0, 'inns': 8, 'm': 10, 'r': '40', 'b': 45, '4s': 1, '6s': 1, 'no': 5, 'hs': '16*', 'sr': '88.88', 'a': '13.33'}, 'bowlingStats': {'bbiw': 0, 'bbir': 0, 'bbmw': 0, 'bbmr': 0, '4w': 0, '5w': 0, '10w': 0, 'inns': 1, 'm': 10, 'b': 6, 'r': 8, 'wb': 0, 'nb': 0, 'd': 1, 'w': 0, '4s': 1, '6s': 0, 'maid': 0, 'wmaid': 0, 'ht': 0, 'a': '-', 'e': '8.00', 'sr': '-', 'o': '1.00'}, 'fieldingStats': {'c': 1, 'ro': 0, 's': 0, 'inns': 1, 'm': 10}}, {'matchType': 'IPLT20', 'battingStats': {'50s': 0, '100s': 0, 'inns': 8, 'm': 10, 'r': '40', 'b': 45, '4s': 1, '6s': 1, 'no': 5, 'hs': '16*', 'sr': '88.88', 'a': '13.33'}, 'bowlingStats': {'bbiw': 0, 'bbir': 0, 'bbmw': 0, 'bbmr': 0, '4w': 0, '5w': 0, '10w': 0, 'inns': 1, 'm': 10, 'b': 6, 'r': 8, 'wb': 0, 'nb': 0, 'd': 1, 'w': 0, '4s': 1, '6s': 0, 'maid': 0, 'wmaid': 0, 'ht': 0, 'a': '-', 'e': '8.00', 'sr': '-', 'o': '1.00'}, 'fieldingStats': {'c': 1, 'ro': 0, 's': 0, 'inns': 1, 'm': 10}},
经过一整天的努力,我做到了:
在代码中导入以下内容
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
import time
from selenium.common.exceptions import WebDriverException
Python 下面的代码
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 输出中确认)
requests 库的问题是未加载动态数据。
但是用硒就可以轻松做到。
我添加了睡眠以确保滚动完成。
我在很多地方阅读而不是睡觉可以使用 WebDriverWait,但我无法让它们工作
我很确定可以有优化版本。
(如果找到请post这里)
我正在尝试从 https://www.iplt20.com/teams/sunrisers-hyderabad/squad" 获取数据 但面临一个问题,尤其是下拉列表(“按年份过滤”)。
我能够在下拉列表中检索名称,即 2020、2019,。 ETC 但无法检索每个列表元素的数据。
当我们点击按年份筛选列表时,会出现一个下拉列表,然后在赛季(年份)上,球员会发生变化(我们会得到当年打过那个赛季的球员以及概括)。 我想按赛季获取每个球员的数据。 当我们点击下拉列表
时也没有创建新的 URL我找不到任何解决方案。 使用以下 python 代码从下拉列表中检索 season/year 值。
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)
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>
这可能只是部分答案,但它确实得到了你想要的(统计数据)。
问题是,数据是JS动态加载的。但是,如果您查看流量(检查 Developer Tool -> Network),您会看到发送到 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']}")
但是,我无法确定 tournamentIds
的来源。此外,没有 2013 年以后的数据。
示例输出(为简洁起见,仅部分输出):
Printing stats for Sunrisers Hyderabad
Yusuf Pathan - [{'matchType': 'AGG', 'battingStats': {'50s': 0, '100s': 0, 'inns': 8, 'm': 10, 'r': '40', 'b': 45, '4s': 1, '6s': 1, 'no': 5, 'hs': '16*', 'sr': '88.88', 'a': '13.33'}, 'bowlingStats': {'bbiw': 0, 'bbir': 0, 'bbmw': 0, 'bbmr': 0, '4w': 0, '5w': 0, '10w': 0, 'inns': 1, 'm': 10, 'b': 6, 'r': 8, 'wb': 0, 'nb': 0, 'd': 1, 'w': 0, '4s': 1, '6s': 0, 'maid': 0, 'wmaid': 0, 'ht': 0, 'a': '-', 'e': '8.00', 'sr': '-', 'o': '1.00'}, 'fieldingStats': {'c': 1, 'ro': 0, 's': 0, 'inns': 1, 'm': 10}}, {'matchType': 'IPLT20', 'battingStats': {'50s': 0, '100s': 0, 'inns': 8, 'm': 10, 'r': '40', 'b': 45, '4s': 1, '6s': 1, 'no': 5, 'hs': '16*', 'sr': '88.88', 'a': '13.33'}, 'bowlingStats': {'bbiw': 0, 'bbir': 0, 'bbmw': 0, 'bbmr': 0, '4w': 0, '5w': 0, '10w': 0, 'inns': 1, 'm': 10, 'b': 6, 'r': 8, 'wb': 0, 'nb': 0, 'd': 1, 'w': 0, '4s': 1, '6s': 0, 'maid': 0, 'wmaid': 0, 'ht': 0, 'a': '-', 'e': '8.00', 'sr': '-', 'o': '1.00'}, 'fieldingStats': {'c': 1, 'ro': 0, 's': 0, 'inns': 1, 'm': 10}},
经过一整天的努力,我做到了:
在代码中导入以下内容
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
import time
from selenium.common.exceptions import WebDriverException
Python 下面的代码
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 输出中确认)
requests 库的问题是未加载动态数据。 但是用硒就可以轻松做到。
我添加了睡眠以确保滚动完成。 我在很多地方阅读而不是睡觉可以使用 WebDriverWait,但我无法让它们工作
我很确定可以有优化版本。 (如果找到请post这里)