scrapy框架爬取虎扑NBA球员球队数据

191 阅读3分钟

目标网站:虎扑体育

需求:使用scrapy框架爬取目标网站的数据信息 一、网页分析 首先我们打开目标网站,去到我们需要获取数据的页面,打开开发者工具,我们可以看到,实际上数据就写在源码中,这就很好获取了

image.png 二、代码实操

先创建一个scrapy项目,如何创建我就不细说了。代码如下:

class ExampleSpider(scrapy.Spider):  
  name = "example"  
  # allowed_domains = ["example.com"]  
  start_urls = ['https://nba.hupu.com/stats/players']  
  
  def parse(self, response):  
       res = response.xpath('//*[@id="data_js"]/div[4]/div')

解析网页之后,就是我们熟悉的获取数据的环节了

for i in res:  
    player_name = res.xpath('.//td[2]/a/text()').extract()  
    team_name = res.xpath('.//tr/td[3]/a/text()').extract()  
    score = res.xpath('.//tr/td[@class="bg_b"]/text()').extract()  
    hit_shoot = res.xpath('.//tr/td[5]/text()')[2:].extract()  
    hit_rate = res.xpath('.//tr/td[6]/text()')[2:].extract()  
    Hit_Three = res.xpath('.//tr/td[7]/text()')[2:].extract()  
    Three_point_rate = res.xpath('.//tr/td[8]/text()')[2:].extract()  
    Free_throw = res.xpath('.//tr/td[9]/text()')[2:].extract()  
    Free_throw_rate = res.xpath('.//tr/td[10]/text()')[2:].extract()

获取到数据之后,可以把数据提交到管道实现持久化存储

item = NbaItem()  
item['player_name'] = player_name  
item['team_name'] = team_name  
item['score'] = score  
item['hit_rate'] = hit_rate  
item['hit_shoot'] = hit_shoot  
item['Hit_Three'] = Hit_Three  
item['Three_point_rate'] = Three_point_rate  
item['Free_throw'] = Free_throw  
item['Free_throw_rate'] = Free_throw_rate  
# 提交到管道  
yield item

这里我们就需要去到items.py文件设置相关配置了,因为我们把player_name等数据提交给了管道,管道需要接收数据 ,所以需要设置相关变量去接收数据

player_name = scrapy.Field()  
team_name = scrapy.Field()  
score = scrapy.Field()  
hit_shoot = scrapy.Field()  
hit_rate = scrapy.Field()  
Hit_Three = scrapy.Field()  
Three_point_rate = scrapy.Field()  
Free_throw = scrapy.Field()  
Free_throw_rate = scrapy.Field()

在管道文件pipelines文件中,可以正式开始接收数据了,但是由于一开始,我们的获取数据的代码是写在for循环下的,这就意味着,如果后续我们需要保存文件的话,会多次打开同一个文件夹,所以这里我们需要写一个函数,使得我们只需要打开一次csv文件,该函数只在开始爬虫的时候调用一次

def open_spider(self,spider):  
print('开始爬虫。。。。。。。')  
self.fp = open('./players_data.csv','w',encoding='utf-8')  
  
def process_item(self, item, spider):  
player_name = item['player_name']  
team_name=item ['team_name']  
score= item['score']  
hit_rate= item['hit_rate']  
hit_shoot= item['hit_shoot']  
Hit_Three = item['Hit_Three']  
Three_point_rate=item['Three_point_rate']  
Free_throw=item['Free_throw']  
Free_throw_rate=item['Free_throw_rate']  
self.fp.write(','.join(player_name)+'\n'+','.join(team_name)+'\n'+','.join(score)+'\n'+','.join(hit_rate)+'\n'+','.join(hit_shoot)+'\n'+','.join(Hit_Three)+'\n'+','.join(Three_point_rate)+'\n'+','.join(Free_throw)+'\n'+','.join(Free_throw_rate))
return item

打开文件之后需要写一个函数去关上之前写的打开文件的函数

def close_spider(self,spider):  
print('结束爬虫.......')  
self.fp.close()

实现功能的代码我们就写完了,别忘了修改setting文件下的参数,当我们执行scrapy项目的时候,它会自动给我们返回日志信息,但是我们只需要得到报错的日志就可以了,因为大篇幅的日志不方便我们查看项目执行结果,我们只需要在setting文件下添加LOG_LEVEL = 'ERROR',修改ROBOTSTXT_OBEY = False,添加UA协议,开启item管道,也就是ITEM_PIPELINES 做完这些我们就可以执行程序了 爬取到的数据展示:

image.png 我们需要去jupyter notebook将爬取到的数据处理一下,通过观察不难发现,数据是按行写入的,可以把数据转置一下

data = pd.read_csv('E:/pythonfile/爬虫实例/playerdata.csv')
data = data.T
data

转置前后对比

image.png

image.png 可以看得出转置之后数据更方便我们后续处理,给所有的列增加列名,方便我们理解数据含义

data.columns=['所属球队','得分','命中-出手','命中率','命中三分','三分命中率','命中罚球','罚球命中率']

image.png 可以看到球员姓名没有被处理到,是因为默认了姓名是索引,处理代码如下

data = data.reset_index().rename(columns={'index':'球员姓名'})
data.head()

处理过后的数据就变成了这样

image.png 后续我们可以根据需求进行数据的可视化