实习导师布置任务说通过网络爬虫获取NBA球员数据,网页如下:

当首先看到这个网页,心想这就是几个数据简简单单的爬取一下,当实际上手发现
网站是基于Ajax写的,数据动态获取,所以无法通过下载源代码然后解析获得。
从某不良少年写的抓取淘宝mm的例子中收到启发,对于这样的情况,一般可以同构自己搭建浏览器实现。phantomJs,CasperJS都是不错的选择。该网址做了动态数据反爬,当我们检查网页时,发现代码跟我们看到网页数据不一样
为此,仅抓取实时数据。选取python的selenium,模拟搭建浏览器,模拟人为的点击等操作实现数据生成和获取。selenium的一大优点就是能获取网页渲染后的源代码,即执行操作后的源代码。普通的通过 url解析网页的方式只能获取给定的数据,不能实现与用户之间的交互。selenium通过获取渲染后的网页源码,并通过丰富的查找工具,个人认为最好用的就是find_element_by_xpath("xxx"),通过该方式查找到元素后可执行点击、输入等事件,进而向服务器发出请求,获取所需的数据。
1.首先运行爬虫得导入相关模块
-
os: 这个库提供了与操作系统交互的功能,比如文件和目录的创建、删除等。 -
time: 这个库允许你进行时间相关的操作,例如暂停执行(time.sleep())。 -
selenium: 这是一个用于自动化网页测试的工具,可以模拟用户在浏览器中的操作。 -
webdriver: Selenium的核心组件,用于控制浏览器。 -
By: 这是Selenium中的一个模块,提供了定位网页元素的方法,如id、name、css选择器等。 -
pandas: 这是一个数据分析库,可以用于处理和分析数据。
import os
import time
from selenium inport webdriver
from selenium.webdriver.common.by import By
import pandas as pd
2.第二步,我们则需要开始爬取数据了,定义一个爬取数据的函数,进行爬虫操作,我们是使用selenium库进行动态数据爬取,但总体还是使用xpath进行数据路径的爬取,接下来是代码部分,关键地方都做了一些注释,xpath路径可以通过xpath工具来查看获取
def get_data(url):
"""
通过给定的URL获取球员数据。
参数:
url(str):包含球员数据的网页URL。
返回:
无返回值,但将数据保存到文件。
"""
try:
#初始化WebDriver实例,使用Edge浏览器
driver = webdriver.Edge()
#导航到指定的URL
driver.get(url)
#循环5次,每次暂停1秒并获取页面上的数据
for i in range(5)
time.sleep(1)
#球员排名
rank = driver.find_elements(By.XPATH,'//div/table/tbody/tr/td[1]/span')
#球员姓名
name = driver.find_elements(By.XPATH,'//div/table/tbody/tr/td[2]/div/a')
#球队
team = driver.find_elements(By.XPATH,'//div/table/tbody/tr/td[3]/a')
#比赛场次
game = driver.find_elements(By.XPATH,'//div/table/tbody/tr/td[4]/span')
#出场时间
play_time = driver.find_elements(By.XPATH,'//div/table/tbody/tr/td[5]/span')
#得分
score = driver.find_elements(By.XPATH,'//div/table/tbody/tr/td[6]/span')
#篮板
rebound = driver.find_elements(By.XPATH,'//div/table/tbody/tr/td[7]/span')
#助攻
assist = driver.find_elements(By.XPATH,'//div/table/tbody/tr/td[8]/span')
#抢断
steal = driver.find_elements(By.XPATH,'//div/table/tbody/tr/td[9]/span')
#盖帽
block = driver.find_elements(By.XPATH,'//div/table/tbody/tr/td[10]/span')
#投篮命中率
shooting = driver.find_elements(By.XPATH,'//div/table/tbody/tr/td[11]/span')
#三分命中率
three_shooting = driver.find_elements(By.XPATH,'//div/table/tbody/tr/td[12]/span')
#罚球命中率
free_throw = driver.find_elements(By.XPATH,'//div/table/tbody/tr/td[13]/span')
#构建数据字典,包含所有收集的数据
data = {
'球队排名':[rank[i].text for i in range(len(rank))],
'球队姓名':[name[i].text for i in range(len(name))],
'球队':[team[i].text for i in range(len(team))],
'比赛场次':[game[i].text for i in range(len(game))],
'出场时间':[play_time[i].text for i in range(len(play_time))],
'得分' : [score[i].text for i in range(len(score))],
'篮板': [rebound[i].text for i in range(len(rebound))],
'助攻':[assist[i].text for i in range(len(assist))],
'抢断':[steal[i].text for i in range(len(stral))],
'盖帽':[block[i].text for i in range(len(block))],
'投篮命中率':[shooting[i].text for i in range(len(shooting))],
'三分命中率':[three_shooting[i].text for i in range(len(three_shooting))],
'罚球命中率':[free_throw[i].text for i in range(len(free_throw))]
}
#保存数据到文件
save_data(data)
#点击下一页按钮
driver.find_elements(By.XPATH,'//*[@id="app"]/div[2]/div/div[2]/section[1]/ul/li[7]').click()
#如果已经是第五次迭代,则跳出循环
if i == 4:
break
except Exception as e:
#打印异常信息
print(e)
finally:
#关闭浏览器窗口
driver.quit()
3.第三步就是保存数据的步骤了,按照之前第二步调用一个save_data()函数还未定义,进行定义并且将刚刚爬取到的数据保存到excel文件中
def save_data(data):
"""
保存NBA球员数据到Excel文件中。
如果文件"NBA球员数据.xlsx"不存在,则直接将数据写入新文件中。
如果文件已存在,则将新数据追加到现有文件中,并覆盖原有文件。
:param data: 要保存的NBA球员数据,通常为列表或字典形式。
:return : 无返回值。
"""
#检查文件是否存在
if not os.path.exists('NBA球员数据.xlsx'):
#如果文件不存在,将数据转化为DataFrame并写入Excel文件
df1 = pd.DataFrame(data)
df1.to_excel('NBA球员数据.xlsx',index =False)
else:
#如果文件已存在,读取现有Excel文件内容
df2 = pd.read_excel('NBA球员数据.xlsx')
#将新数据追加到现有DataFrame中,并重置索引
df2= pd.concat([df2,pd.DataFrame(data)],ignore_index=True)
#覆盖写入修改后的DataFrame到Excel文件中
df2.to_excel('NBA数据.xlsx',index =False)
4.调用并执行主函数并初始化地址
if __name__ == '__main__':
url = "https://china.nba.cn/statistics/playerstats"
get_data(url)
最后代码都是全程手打的如有错误,敬请谅解

409

被折叠的 条评论
为什么被折叠?



