实战项目之-scrapy框架爬取球探网数据

 

项目简介:

球探中的英超比赛(3个表)
1. 球队的信息
     (球队ID,名字,创建时间,城市,训练场,风格特点,胜率相关) 
http://zq.win007.com/cn/team/Summary/19.html
2. 从2013年到2019年所有的比赛
     (比赛id, host_id, guest_id, 比赛的信息)
http://zq.win007.com/cn/League/2018-2019/36.html
3. 需要找到每个球员在上面的比赛中的数据
     (球员的名字, 比赛id, 球队id, 这个球员在这场比赛中的数据)
点击比分->球员统计
http://bf.win007.com/Count/1552443cn.htm
存到MySQL中

思路简介及遇到的那些坑:

1.通过简单分析,我们发现这三个表可以通过第2项需求的内容联系起来:​​​​​​

  • 或许我们可以通过比赛id去获取每场比赛的球队阵容及成员信息.
  • 或许我们可以通过比赛id去获取到双方的队伍名及队伍id.
  • 或许根据双方的队伍名及id,可以找到第1项要求的队伍详细信息 

2.仔细分析一下,我们的项目要求需要爬每支球队的相关数据,在页面可以看出,只有20支队伍,如果仅爬取这一个页面.

   之前年份降级的球队就会获取不到,所以我们要先爬取第2项内容.

3.由于我们是爬取多年的数据,需要发送多个url,所以将start_urls换成start_requests函数.

4.爬取过程中,发现2013年的比赛详情页数据和往年不同,所以我们需要分开来写.

5.网页结构分析过程中发现数据是存在js里的,所以我们要找到数据的接口,另外返回来的数据结构是需要用eval来转化的.

6.第一次爬取的时候,可以顺利爬取,version没有特别在意,第二天就不行了,所以还需要加上实时的时间字符串.

7.在获取某个接口的时候,可能需要用到你的referer,否则服务器不理你,并向你丢出了一组~443~!

8.这3个表的提交(pipline)基本一致,所以我们可以只写一次用来提交数据库.

9.由于三个表的数据是不一样的,所以需要定义3个item,将3个item分别实例化在spider,并分别将数据提交给items

备注: 由于本人水平有限,可能代码和分析有一定的错误,我是一个求知欲很强的人,欢迎各路大佬莅临指正.

愿路过的小哥哥,工作顺利,阖家欢乐~

愿路过的小姐姐,肤白貌美大长腿~

spider页面:

# -*- coding: utf-8 -*-
import scrapy
import re,time
from qiutan.items import SaichengItem
from qiutan.items import Team_DataItem
from qiutan.items import Member_Data_New_Item
from qiutan.items import Member_Data_Old_Item

class EcSpider(scrapy.Spider):

    name = 'Ec'
    #作用域
    allowed_domains = ['zq.win007.com','bf.win007.com']

    #将不同年份url交给Scheduler
    def start_requests(self):
        re = time.strftime('%Y%m%d%H', time.localtime())  # 2019042509
        base_url = 'http://zq.win007.com/jsData/matchResult/{}/s36.js?version={}'
        date_lis = ['{}-{}'.format(i,i+1) for i in range(2013,2019)]
        for date in date_lis:
            req_base = scrapy.Request(base_url.format(date,re), callback = self.parse)
            req_base.meta['date'] = date
            req_base.meta['re'] = re
            yield req_base


    def team_data_id(self,response):
        # 获取每个队伍的id和队名
        pat = re.compile("\[(\d+),'(.*?)'")
        ballteam = pat.findall(response.text)[1:]
        lis_all_team = []
        for item in ballteam:
            lis_all_team.append(item[0])
            lis_all_team.append(item[-1])
        return lis_all_team


    #表2 全部轮次的数据表
    def parse(self, response):
        #获取球队id_队名列表
        lis_all_team = self.team_data_id(response)
        #获取每年所有队伍数据 38轮
        ball_lunci_team = re.findall('\[(\[\d{3,}.*?\])\];',response.text)
        num = 0
        #根据38轮遍历每一小轮
        for eve_turn in ball_lunci_team:
            #每小页数据
            item = SaichengItem()
            num += 1
            # 每轮次的10条数据
            eve_turn_team = re.findall('\[\d{6}.*?\]',eve_turn)
            for eve_turn_team_data in eve_turn_team:
                #将每行数据转化为list类型 索引取值
                #[851543,36,-1,'2013-08-17 19:45',25,58,'1-0','1-0','7',
                # '13',1.25,0.5,'2.5/3','1',1,1,1,1,0,0,'']
                lis = eve_turn_team_data.strip('[|]').replace('\'','').split(',')
                #根据获取的战队id去之前的列表找索引位置
                index_num_h = lis_all_team.index(lis[4])
                index_num_g = lis_all_team.index(lis[5])
                item['lunci'] = num
                bs_num_id = lis[0]
                item['bs_time'] = lis[3]        #2014-05-04 23:00 <class 'str'>
                item['bs_num_id'] = bs_num_id
                item['host_team'] = lis_all_team[index_num_h+1]
                item['h_team_id'] = lis[4]
                item['res_score'] = lis[6]
                item['guest_team'] = lis_all_team[index_num_g+1]
                item['g_team_id'] = lis[5]
                item['all_rang'] = self.rangqiu(lis[10])
                item['half_rang'] = self.rangqiu(lis[11])
                item['sizes_balls_a'] = lis[12]
                item['sizes_balls_h'] = lis[13]
                item['half_score'] = lis[7]
                yield item
                # 拼接每个比赛详细的url http://bf.win007.com/detail/ 1130517 cn.htm
                # 2013-08-17 ,2014-5-12 老版页面  判断年份 保存版本
                if item['bs_time'] < '2014-05-12 
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值