Part 0 安装

采用Anaconda版本的Python可以直接使用conda install -c scrapinghub scrapy进行安装,采用pip install Scrapy有的环境需要其他的依赖,可能会报错。

Part 1 信息获取

打开番剧索引链接https://www.bilibili.com/anime/index/

F12打开浏览器控制台,inspect in,点到对应的番剧发现信息列表如图,虽然点右键可以复制Xpath,不过这样获得的Xpath经常在Scrapy里面无法获取。这里我们手工来填,就根据属性 class="bangumi-item"就行。(在使用Xpath helper输入Xpath查询之前是不带xh-highlight的,这里是因为插件高亮显示的原因)

获取结果如下:

由于这里是按追番人数分的,切换到按更新时间和评分分信息又会不一样。再细分一下,各个信息Xpath如下。是否会员观看就没管了…也差不多。

标题 //*[@class="bangumi-item"]//*[@class="bangumi-title"]

人数 //*[@class="bangumi-item"]//*[@class="shadow"]

集数 //*[@class="bangumi-item"]//*[@class="pub-info"]

命令行测试

这里是在浏览器里面获得的,再来测试一下Scrapy里面能否成功获取。

开cmd输入scrapy shell "https://www.bilibili.com/anime/index",命令行方式测试一下是否能正常获取。

需要注意有的时候因为反爬虫机制不能正确返回Response,查询一下帮助scrapy shell -h,加上-s USER_AGENT='Mozilla/5.0'就可以更改对应的设置,即

scrapy shell "https://www.bilibili.com/anime/index" -s USER_AGENT='Mozilla/5.0'

In [1]: response.xpath('//*[@class="bangumi-item"]//*[@class="bangumi-title"]').extract()

Out[1]: []

获取失败了?再输入view(response),在浏览器里面看一下返回的结果是怎样的。结果发现弹出一个:“没有找到这样的番剧”。是哪里出错了?输入response.text查看一下源代码,发现里面并没有出现具体信息,所以光用这个网址来获得信息是不行的。

API获取

F12里面Network抓包看一下,为了找出是在哪里出现了具体信息,我们需要在Response里面批量搜索,比如追番人数391.9。按照网上的方法,点右键先把抓下来的包存成har,然后搜索391.9

出现在4527行

它的request请求格式出现在与之最近的4124行

https://bangumi.bilibili.com/media/web_api/search/result?season_version=-1&area=-1&is_finish=-1&copyright=-1&season_status=-1&season_month=-1&pub_date=-1&style_id=-1&order=3&st=1&sort=0&page=1&season_type=1

网址扔到浏览器里面看一下,到了最后还是成了API的形式…

API格式分析

几个关键的如下:

sort 0降序排列 1升序排列

order 3 追番人数排列 0更新时间 4最高评分 2播放数量 5开播时间

page 控制返回的Index

pagesize 20为默认,和网页上的一致 不过最多也就25

剩下的属性和网页右侧的筛选栏一致,大概也能猜出来了。

番剧详细信息获取与调试

需要注意有的番剧有付费信息,有的没有;有的人数不够,没有评分信息。比如下面这个就没有badge badge_type等信息

{'cover': 'http://i0.hdslb.com/bfs/bangumi/152c536f8ecaad8f3d7d568d33da81c963a4a722.png',

'index_show': '全12话',

'is_finish': 1,

'link': 'https://www.bilibili.com/bangumi/play/ss23850',

'media_id': 78352,

'order': {'follow': '202.4万人追番',

'play': '4704.6万次播放',

'pub_date': 1522944000,

'pub_real_time': 1522944000,

'renewal_time': 1532966400,

'score': '9.6分',

'type': 'follow'},

'season_id': 23850,

'title': '超能力女儿'}

不过对详细信息来说就不再是API形式返回的了,用我们最开头失败了的Xpath方法来获取。方法还是差不多,我就直接列结果了。

Tags //*[@class="media-tag"]/text()

简介 //*[@name="description"]/attribute::content

有一点比较奇怪,在网页里面审查元素,Staff表 //*[@class="mic-evaluate"] 第一个元素为声优表 第二个为编剧等Staff表

然而,Scrapy命令行里面测试一下

In [5]: response.xpath('//*[@class="media-tag"]/text()').extract()

Out[5]: ['搞笑', '战斗', '日常', '声控', '漫改']

Tags 简介是没问题的,Staff就获取不到了。response.text查看一下,果然Scrapy和浏览器打开的不一样,发现CV表和Staff表在一大串json里面(执行text=response.xpath('//script')[4].extract()得到),太多了就不贴了,非常详细,还包括评论、每集的标题等等,用正则表达式提出来好了。

In [66]: actor_p=re.compile('actors":(.*?),')

In [67]: re.findall(actor_p,text)

Out[67]: ['"扎克:冈本信彦\\n蕾:千菅春香\\n丹尼:樱井孝宏\\n艾迪:藤原夏海\\n凯西:伊濑茉莉也"']

In [71]: ratings_count_p=re.compile('count":(.*?),')

In [72]: re.findall(ratings_count_p,text)

Out[72]: ['20853']

n [73]: staff_p=re.compile('staff":(.*?),')

In [74]: re.findall(staff_p,text)

Out[74]: ['"原作:真田まこと\\n监督:铃木健太郎\\n系列构成:藤冈美畅\\n角色设计&总作画监督:松元美季\\n美术监督:魏斯曼(スタジオちゅーりっぷ)\\n色彩设计:田边香奈\\n摄影监督:高桥昭裕\\n编集:近藤勇二(Real-T)\\n音响监督:岩浪美和\\n 音响效果:小山恭正\\n音乐:ノイジークローク\\n音乐制作:Lantis\\n动画制作:J.C.STAFF\\n制作:「杀戮天使」制作委员会"']

Part 2 爬虫编写

本次编写一个仅用于分析文本数据、不下载番剧封面图片的爬虫。

命令行下输入scrapy startproject bilibili,Pycharm新建Project,打开该目录。

items.py定义要爬的字段,我自己定义的列在文末。

spider文件夹下新建一个bilibili_spider.py,用来定义具体的行为。比较麻烦的是API每页包含20个子页面,API中还有这20个番剧的信息,并且需要根据API来判断是否把所有番剧爬完了。

这些爬取行为的问题可以参考如下文章:

Scrapy框架之带有分页的详情页面抓取

Scrapy研究探索(五)——自动多网页爬取(抓取某人博客所有文章)

Scrapy中的scrapy.Spider.parse()如何被调用?

如何获取http://a.com中的url,同时也获取http://a.com页面中的数据?

可以直接在parse方法中将request和item一起“返回”,并不需要再指定一个parse_item例如:

def parse(self, response):

#do something

yield scrapy.Request(url, callback=self.parse)

#item[key] = value

yield item

如果想使用-o out.csv输出,需要注意设定编码,在设置settings.py中添加一行

FEED_EXPORT_ENCODING = 'utf-8'

然后启动爬虫scrapy crawl bilibili -o out.csv,虽然用Excel打开仍然是乱码,但是记事本打开就是正常的了。这是因为Excel是ANSI编码,记事本另存为该编码就好。

最终效果如图,后续就可以对分数、CV、类型等等进行分析了。

items.py

# -*- coding: utf-8 -*-

# Define here the models for your scraped items

#

# See documentation in:

# https://doc.scrapy.org/en/latest/topics/items.html

import scrapy

class BilibiliItem(scrapy.Item):

# define the fields for your item here like:

badge= scrapy.Field()

badge_type= scrapy.Field()

is_finish= scrapy.Field()

media_id= scrapy.Field()

index_show= scrapy.Field()

follow= scrapy.Field()

play= scrapy.Field()

pub_date= scrapy.Field()

pub_real_time= scrapy.Field()

renewal_time= scrapy.Field()

score= scrapy.Field()

season_id= scrapy.Field()

title = scrapy.Field()

tags= scrapy.Field()

brief= scrapy.Field()

cv= scrapy.Field()

staff= scrapy.Field()

count= scrapy.Field()

pass

bilibili_spider.py

import scrapy

import logging

from scrapy import Request

from bilibili.items import BilibiliItem

import re

import json

class MySpider(scrapy.Spider):

name = 'bilibili'

allowed_domains = ['bilibili.com']

url_head = 'https://bangumi.bilibili.com/media/web_api/search/result?season_version=-1&area=-1&is_finish=-1&copyright=-1&season_status=-1&season_month=-1&pub_date=-1&style_id=-1&order=3&st=1&sort=0&season_type=1'

start_urls = [url_head+"&page=1"]

# 先处理列表中的番剧信息

def parse(self, response):

self.log('Main page %s' % response.url,level=logging.INFO)

data=json.loads(response.text)

next_index=int(response.url[response.url.rfind("=")-len(response.url)+1:])+1

if(len(data['result']['data'])>0):

# 发出Request 处理下一个网址

next_url = self.url_head+"&page="+str(next_index)

yield Request(next_url, callback=self.parse)

medias=data['result']['data']

for m in medias:

media_id=m['media_id']

detail_url='https://www.bilibili.com/bangumi/media/md'+str(media_id)

yield Request(detail_url,callback=self.parse_detail,meta=m)

# 再处理每个番剧的详细信息

def parse_detail(self, response):

item = BilibiliItem()

item_brief_list=['badge','badge_type','is_finish','media_id','index_show','season_id','title']

item_order_list=['follow','play','pub_date','pub_real_time','renewal_time','score']

m=response.meta

for key in item_brief_list:

if (key in m):

item[key]=m[key]

else:

item[key]=""

for key in item_order_list:

if (key in m['order']):

item[key]=m['order'][key]

else:

item[key]=""

tags=response.xpath('//*[@class="media-tag"]/text()').extract()

tags_string=''

for t in tags:

tags_string=tags_string+" "+t

item['tags']=tags_string

item['brief'] = response.xpath('//*[@name="description"]/attribute::content').extract()

detail_text = response.xpath('//script')[4].extract()

actor_p = re.compile('actors":(.*?),')

ratings_count_p = re.compile('count":(.*?),')

staff_p = re.compile('staff":(.*?),')

item['cv'] = re.findall(actor_p,detail_text)[0]

item['staff'] = re.findall(staff_p,detail_text)[0]

count_list=re.findall(ratings_count_p,detail_text)

if(len(count_list)>0):

item['count'] = count_list[0]

else:

item['count']=0

# self.log(item)

return item

python爬取b站追番信息_Scrapy实战B站番剧信息爬取相关推荐

  1. 信息抽取实战 基于 paddlenlp 的简历信息抽取实战 完整代码

    完整项目演示:信息抽取实战 基于 paddlenlp 的简历信息抽取实战 视频简介链接自取_哔哩哔哩_bilibili 项目介绍: 输入一段简历的文本,然后将信息进行解析,根据不同的内容 解析,存储到 ...

  2. 【校招VIP】出品:在线实习“职查查”大V信息认证实战

    本课程出自校招VIP原创内容,请勿擅自转载,测试项目课程「在线实习"职查查"大V信息认证实战」持续更新中...... 查看课程:[测试]在线实习"职查查"大V信 ...

  3. 信息抽取实战:三元组抽取(限定领域 vs 开放领域)(附代码)

    信息抽取实战:三元组抽取 目录 信息抽取实战:三元组抽取 一.限定领域的三元组抽取 比赛介绍 数据分析 序列标注模型 关系分类模型 三元组提取 总结 二.开放领域的三元组抽取 标注平台 序列标注 文本 ...

  4. 他爬取了B站所有番剧信息,发现了这些……

    本文来自「楼+ 之数据分析与挖掘实战 」第 4 期学员 -- Yueyec 的作业.他爬取了B站上所有的番剧信息,发现了很多有趣的数据- 关键信息:最高播放量 / 最强up主 / 用户追番数据 / 云 ...

  5. [爬虫] B站番剧信息爬取

    申明:本文对爬取的数据仅做学习使用,不涉及任何商业活动,侵删 简述 本次爬取目标是: 番剧的基本信息(名字, 类型, 集数, 连载or完结, 链接等) 番剧的参数信息(播放量, 点赞, 投币, 追番人 ...

  6. 使用Scrapy框架,爬取b站番剧信息。

    使用Scrapy框架,爬取b站番剧信息. 感觉好久没写爬虫的,今天看了在b站浏览了一会儿,发现b站有很多东西可以爬取的,比如首页的排行榜,番剧感觉很容易找到数据来源的,所以就拿主页的番剧来练练手的. ...

  7. python爬取的信息条数比页面显示多_Python爬取分析北京二手房数据?数据结果真的太吓人了...

    有个朋友联系我,想统计一下北京二手房的相关的数据,而自己用Excel统计工作量太过于繁杂,问我用Python该如何实现. 构造要访问的URL 这里,我试着抓取北京海淀区二手房的相关数据.首先,是观察一 ...

  8. python爬取58同城租房信息_python爬虫:找房助手V1.0-爬取58同城租房信息(示例代码)...

    #!/usr/bin/python # -*- encoding:utf-8 -*-importrequests frombs4 importBeautifulSoup frommultiproces ...

  9. python爬取58同城所有租房信息_python爬虫:找房助手V1.0-爬取58同城租房信息

    #!/usr/bin/python # -*- encoding:utf-8 -*-importrequests frombs4 importBeautifulSoup frommultiproces ...

最新文章

  1. 最短JS判断是否为IE6(IE的写法)
  2. WINDOWS2003 ORACLE10G RAC一步一步 手把手 实录
  3. 让串口可以自动分辨一帧数据
  4. Harbor高可用集群配置
  5. NVIDIA GPU 架构梳理
  6. 很强大的一个jquery分页插件
  7. 【边缘检测】RCF: Richer Convolutional Features for Edge Detection
  8. 前端组件化-抽象公共组件类
  9. 【遥感物候】1983-2012年时间序列中国地区GIMMS 3g NDVI下载(已进行旋转、格式转换、投影变换和裁剪)
  10. php获取对象属性值
  11. 排序算法专题-基数排序
  12. java开发运行环境的安装步骤_配置java开发运行环境的步骤
  13. 计算机利用if函数总评,Excel中IF函数的嵌套用法_
  14. buuctf——密码学的心声
  15. java项目----教务管理系统_基于Java的教务管理系统
  16. mysql数据库日志操作
  17. 合并的表格怎么加横线_如何在excel中文字后面加横线
  18. c语言标识首字母不能是,c语言的标识符由哪字符组成
  19. 【问题解决】mac微信截图只能截到空白页面问题
  20. solidworks万向节配合

热门文章

  1. Java list集合 分组并排序
  2. java多线程复习与巩固(二)
  3. 各种DBMS和Sql语言
  4. Mr.Alright---安卓如何修改3rd App(某兔兔、某大师、CPU-Z)等检测信息
  5. 垂直电商的生门与死穴
  6. 数字化时代,企业如何做好数字营销
  7. python采用的是基于_Python采用的是基于____的内存管理方式
  8. Python将DOCX转换为markdown文件
  9. 设置LinearLayout的宽和高
  10. 最荐一本好的网页设计的电子书!!!