赞
踩
申明:本文对爬取的数据仅做学习使用,不涉及任何商业活动,侵删
本次爬取目标是:
- 番剧的基本信息(名字, 类型, 集数, 连载or完结, 链接等)
- 番剧的参数信息(播放量, 点赞, 投币, 追番人数等)
- 时间信息(开播时间, 完结时间)
番剧索引页展示的番剧信息属于动态渲染, 因此要通过获取页面响应来得到我们想要的数据, 按F12到Network中找我们需要的响应数据:
来分析一下Request URL, 先无事其他的参数, 来看我们最需要的一部分: page=1&...&pagesize=20
page
:表示当前页码pagesize
:表示页面展示的番剧数可以尝试访问Request URL, 来确认可以拿到我们需要的数据:
这一个请求并不能满足需求, 跟进番剧页链接, 并继续找响应数据:
几乎所有的数据都被我们得到了, 但唯独缺一个番剧类型
跟进番剧简介网址:https://www.bilibili.com/bangumi/media/md102392, 这是一个静态页面, 可以直接从响应中获取到我们需要的信息:
完成可数据源的分析, 接下来开始写代码
scrapy startproject bilibili_spider
,bilibili_spider为项目名称,创建完成后会自动生成下列文件:
bilibili_spider
__init__.py
scrapy.cfg
#项目部署的配置文件bilibili_spider
#项目目录, 包含了项目运行相关的文件
__init__.py
items.py
#项目的目标文件middlewares.py
#项目的中间件文件pipelines.py
#项目的管道文件settings.py
#项目的设置文件spiders
#项目的爬虫目录
__init__.py
scrapy genspider bilibili bilibili.com
,bilibili是爬虫文件的名称,后面是目标网站的域名, 由于本次爬取涉及的站点较多, 这里可以将www省略掉, 以避免出错进入items.py文件中设置爬取的目标,基于python之禅简单生于复杂
, 我将上述最后两次请求合并到一个, 即从番剧详情页获取评论数和评分
import scrapy class BilibiliSpiderItem(scrapy.Item): # 索引页的ajax 可以获得以下信息: season_id = scrapy.Field() # 番剧编号 media_id = scrapy.Field() # 媒体编号 title = scrapy.Field() # 标题 index_show = scrapy.Field() # 集数 is_finish = scrapy.Field() # 是否完结 video_link = scrapy.Field() # 链接 cover = scrapy.Field() # 封面图 pub_real_time = scrapy.Field() # 真实发布日期 renewal_time = scrapy.Field() # 最近更新日期 # 番剧信息的ajax请求: favorites = scrapy.Field() # 追番 coins = scrapy.Field() # 硬币 views = scrapy.Field() # 播放量 danmakus = scrapy.Field() # 弹幕 # 番剧详情页的ajax请求: cm_count = scrapy.Field() # 评论数 score = scrapy.Field() # 评分 media_tags = scrapy.Field() # 类型标签
# -*- coding: utf-8 -*- import json from datetime import datetime import scrapy from scrapy.spiders import CrawlSpider from bilibili_video.items import BilibiliSpiderItem class BilibiliSpider(CrawlSpider): name = 'bilibili' allowed_domains = ['bilibili.com'] # 索引页的ajax request_url = 'https://bangumi.bilibili.com/media/web_api/search/result?page={}&season_type=1&pagesize=20' page = 1 start_urls = [request_url.format(page)] # 番剧信息的ajax请求 season_url = 'https://bangumi.bilibili.com/ext/web_api/season_count?season_id={}&season_type=1&ts={}' # 番剧详情页的ajax请求 media_url = 'https://www.bilibili.com/bangumi/media/md{}' def parse(self, response): # if self.page == 2: # 限制爬取页数,用于测试爬取状态 # return list_data = json.loads(response.text).get('result').get('data') if list_data is None: # 如果响应中没有数据,则结束执行 return for data in list_data: ts = datetime.timestamp(datetime.now()) yield scrapy.Request(url=self.season_url.format(data.get('season_id'), ts), callback=self.parse_details, meta=data) self.page += 1 # 生成下一页的请求 yield scrapy.Request(url=self.request_url.format(self.page), callback=self.parse) def parse_details(self, response): item = BilibiliSpiderItem() meta_data = response.meta item['season_id'] = meta_data.get('season_id') item['media_id'] = meta_data.get('media_id') item['title'] = meta_data.get('title') item['index_show'] = meta_data.get('index_show') item['is_finish'] = meta_data.get('is_finish') item['video_link'] = meta_data.get('link') item['cover'] = meta_data.get('cover') item['pub_real_time'] = meta_data.get('order').get('pub_real_time') item['renewal_time'] = meta_data.get('order').get('renewal_time') resp_data = json.loads(response.text).get('result') item['favorites'] = resp_data.get('favorites') item['coins'] = resp_data.get('coins') item['views'] = resp_data.get('views') item['danmakus'] = resp_data.get('danmakus') yield scrapy.Request(url=self.media_url.format(item['media_id']), callback=self.parse_media, meta=item) def parse_media(self, response): item = response.meta resp = response.xpath('//div[@class="media-info-r"]') item['media_tags'] = resp.xpath('//span[@class="media-tags"]/span/text()').extract() item['score'] = resp.xpath('//div[@class="media-info-score-content"]/text()').extract()[0] item['cm_count'] = resp.xpath('//div[@class="media-info-review-times"]/text()').extract()[0] yield item
项目源码链接:https://github.com/zhanghao19/bilibili_spider
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。