title: 爬虫入门六 总结 资料 与Scrapy实例-bibibili番剧信息

date: 2020-03-16 20:00:00

categories: python

tags: crawler

学习资料的补充。

和Scrapy的一个实例 bilibili番剧信息爬取。

1 总结与资料

1.1 基本知识

1、学习Python爬虫基础,安装PyCharm。

2、学习Scrapy框架。

相关官方链接:

Scrapy官网tutorial: https://scrapy-chs.readthedocs.io/zh_CN/0.24/intro/tutorial.html

Requests官网文档: http://cn.python-requests.org/zh_CN/latest/

lxml官方文档: http://lxml.de/tutorial.html

python核心模块之pickle和cPickle讲解:http://www.pythonclub.org/modules/pickle

phantomJS进程不自动退出,需要手动添加:driver.quit(),

参考:http://www.jianshu.com/p/9d408e21dc3a

菜鸟教程(Python篇):https://www.runoob.com/python3/python3-tutorial.html

1.2 Xpath与re

1、学习Scrapy+XPath。

2、学习正则式

3、撰写实验报告1的part1.

相关官方链接:

XPath语法:http://www.w3school.com.cn/xpath/xpath_syntax.asp

Selectors:https://scrapy-chs.readthedocs.io/zh_CN/0.24/topics/selectors.html

2 实例 B站番剧信息爬取

参考: https://www.jianshu.com/p/530acc7b50d1?utm_source=oschina-app

2.1

新建工程。

crapy startproject bilibilianime

2.2 番剧索引

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

F12控制台查看

可见相关信息:追番,会员,名称,话数都在

  • 在Pycharm命令行调试Scrapy Xpath能否获取相关信息

    scrapy shell "https://www.bilibili.com/anime/index" -s USER_AGENT='Mozilla/5.0'
    response.xpath('//*[@class="bangumi-item"]//*[class="bangumi-title"]').extract() out:[]

    返回为空

    View(response) 在浏览器查看,没问题

    Reponse.text 查看内容,发现并没有相关信息

    在浏览器F12,network抓包,xhr选项,右键保存为har到本地搜索。

    在har文件查找鬼灭之刃

    "text": "{\"code\":0,\"data\":{\"has_next\":1,\"list\":[{\"badge\":\"会员专享\",\"badge_type\":0,\"cover\":\"http://i0.hdslb.com/bfs/bangumi/9d9cd5a6a48428fe2e4b6ed17025707696eab47b.png\",\"index_show\":\"全26话\",\"is_finish\":1,\"link\":\"https://www.bilibili.com/bangumi/play/ss26801\",\"media_id\":22718131,\"order\":\"758万追番\",\"order_type\":\"fav_count\",\"season_id\":26801,\"title\":\"鬼灭之刃\",\"title_icon\":\

    向上查找最近的request

    "request": {
    "method": "GET",
    "url": "https://api.bilibili.com/pgc/season/index/result?season_version=-1&area=-1&is_finish=-1&copyright=-1&season_status=-1&season_month=-1&year=-1&style_id=-1&order=3&st=1&sort=0&page=1&season_type=1&pagesize=20&type=1",
    "httpVersion": "HTTP/1.1",

    浏览器访问

    https://api.bilibili.com/pgc/season/index/result?season_version=-1&area=-1&is_finish=-1&copyright=-1&season_status=-1&season_month=-1&year=-1&style_id=-1&order=3&st=1&sort=0&page=1&season_type=1&pagesize=20&type=1

    内容如下

    {"code":0,"data":{"has_next":1,"list":[{"badge":"会员专享","badge_type":0,"cover":"http://i0.hdslb.com/bfs/bangumi/9d9cd5a6a48428fe2e4b6ed17025707696eab47b.png","index_show":"全26话","is_finish":1,"link":"https://www.bilibili.com/bangumi/play/ss26801","media_id":22718131,"order":"758.1万追番","order_type":"fav_count","season_id":26801,"title":"鬼灭之刃","title_icon":""},{"badge":"会员专享","badge_type":0,"cover":"http://i0.hdslb.com/bfs/bangumi/f5d5f51b941c01f8b90b361b412dc75ecc2608d3.png","index_show":"全14话","is_finish":1,"link":"https://www.bilibili.com/bangumi/play/ss24588","media_id":102392,"order":"660.2万追番","order_type":"fav_count","season_id":24588,"title":"工作细胞","title_icon":""},{"badge":"会员专享",
    ...
    ...#略去

    可见bilibili番剧索引页面是以api形式获取相关信息。其中sort,page_size..为设置的格式。

    sort 0降序排列 1升序排列
    order 3 追番人数排列 0更新时间 4最高评分 2播放数量 5开播时间
    page 控制返回的Index
    pagesize 20为默认,和网页上的一致 不过最多也就25
    剩下的属性和网页右侧的筛选栏一致,也能猜出来了。

    综上就可以用api获取索引

    2.3 番剧详细信息

    在上面查鬼灭之刃的时候有一条信息

    https://www.bilibili.com/bangumi/play/ss26801","media_id":22718131

    media_id为番剧id,而番剧详情页为

    https://www.bilibili.com/bangumi/media/md22718131

    可见只需要替换后面的id就可以获得每个番剧的详情

    在鬼灭之刃的详情页,F12查看信息的节点

    比如tags,,在class=media-tags的节点中

    再尝试在scrapy shell能否xpath获取

    >scrapy shell "https://www.bilibili.com/bangumi/media/md22718131" -s USER_AGENT='Mozilla/5.0'
    
    response.xpath('//*[@class="media-tag"]/text()').extract()

    发现可直接获得

    In [1]: response.xpath('//*[@class="media-tag"]/text()').extract()
    Out[1]: ['漫画改', '战斗', '热血', '声控']

    但是,测试发现staff和声优无法直接xpath获取

    就Reponse.text查看response

    ,"staff":"原作:吾峠呼世晴(集英社《周刊少年JUMP》连载)\\n监督:外崎春雄\\n角色设计:松岛晃\\n副角色设计:佐藤美幸、
    梶山庸子、菊池美花\\n脚本制作:ufotable\\n概念美术:卫藤功二、矢中胜、竹内香纯、桦泽侑里\\n摄影监督: "actors":"灶门炭治郎:花江夏树\\n灶门祢豆子:鬼头明里\\n我妻善逸:下野纮\\n嘴平伊之助:松冈祯丞\\n富冈义勇:樱井孝宏\\n鳞泷左近次:大冢芳忠\\n锖兔:
    梶裕贵\\n真菰:加隈亚衣\\n不死川玄弥:冈本信彦\\n产屋敷耀哉:森川智之\\n产屋敷辉利哉:悠木碧\\n产屋敷雏衣:井泽诗织\\n钢铁冢萤:浪川大辅\\n鎹鸦:山崎巧\\n佛堂鬼:绿川光\\n手鬼:子安武人",

    这些在一串json中。用re提取

    比如声优

    Import re
    Actor=Re.compile(‘actors”:(.*?),’) #一直到 , 结束
    Text=reponse.text
    Re.findall(actors,text) In [17]: actors=re.compile('actors":(.*?),')
    In [18]: re.findall(actors,text)
    Out[18]: ['"灶门炭治郎:花江夏树\\n灶门祢豆子:鬼头明里\\n我妻善逸:下野纮\\n嘴平伊之助:松冈祯丞\\n富冈义勇:樱井孝宏\\n鳞泷左近次:大冢芳忠\\n锖兔:梶裕贵\\n真菰:加隈亚衣\\n不死川玄弥:冈本信彦\\n产屋敷耀哉:森川智之\\n产屋敷辉利哉
    :悠木碧\\n产屋敷雏衣:井泽诗织\\n钢铁冢萤:浪川大辅\\n鎹鸦:山崎巧\\n佛堂鬼:绿川光\\n手鬼:子安武人"']

    包括评论、每集的标题等等都可以用re提取

    2.4 索引页详细页面的转换处理

    API每页包含20个子页面,API中还有这20个番剧的信息,并且需要根据API来判断是否把所有番剧爬完了。

    https://blog.csdn.net/u012150179/article/details/34486677

    https://www.zhihu.com/question/30201428

    参考上述处理:

    如何获取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

    2.5 其他

    -o输出注意编码 utf-8,gb18030

    2.6 code

    settings.py

    BOT_NAME = 'bilibilianime'
    SPIDER_MODULES = ['bilibilianime.spiders']
    NEWSPIDER_MODULE = 'bilibilianime.spiders'
    FEED_EXPORT_ENCODING = "gb18030"
    # Crawl responsibly by identifying yourself (and your website) on the user-agent
    #USER_AGENT = 'bilibilianime (+http://www.yourdomain.com)'
    # Obey robots.txt rules
    ROBOTSTXT_OBEY = True

    items.py

    import scrapy
    
    class BilibilianimeItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    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.py (spider)

    import scrapy
    import logging
    from scrapy import Request
    from bilibilianime.items import BilibilianimeItem
    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 = BilibilianimeItem()
    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() 这里原来的代码有bug,应该是想缩小搜索区域加速,但是出了问题
    detail_text = response.text
    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

    2.7 输出

    scrapy crawl bilibili -o bilibilianime.csv

    调用api时使用默认参数,所以是按照追番人数排序

    结果:

    3 其他实例

    https://www.cnblogs.com/xinyangsdut/p/7628770.html 腾讯社招

    https://blog.csdn.net/u013830811/article/details/45793477 亚马逊.cn

    https://github.com/Mrrrrr10/Bilibili_Spider 哔哩哔哩

    https://blog.csdn.net/weixin_42471384/article/details/83049336

  • 爬虫入门六 总结 资料 与Scrapy实例-bibibili番剧信息的更多相关文章

    1. Python爬虫入门六之Cookie的使用

      大家好哈,上一节我们研究了一下爬虫的异常处理问题,那么接下来我们一起来看一下Cookie的使用. 为什么要使用Cookie呢? Cookie,指某些网站为了辨别用户身份.进行session跟踪而储存在 ...

    2. python爬虫入门(六) Scrapy框架之原理介绍

      Scrapy框架 Scrapy简介 Scrapy是用纯Python实现一个为了爬取网站数据.提取结构性数据而编写的应用框架,用途非常广泛. 框架的力量,用户只需要定制开发几个模块就可以轻松的实现一个爬 ...

    3. 6.Python爬虫入门六之Cookie的使用

      大家好哈,上一节我们研究了一下爬虫的异常处理问题,那么接下来我们一起来看一下Cookie的使用. 为什么要使用Cookie呢? Cookie,指某些网站为了辨别用户身份.进行session跟踪而储存在 ...

    4. python爬虫入门六:Selenium库

      在我们爬取网页过程中,经常发现我们想要获得的数据并不能简单的通过解析HTML代码获取,这些数据是通过AJAX异步加载方式或经过JS渲染后才呈现在页面上显示出来. selenuim是一种自动化测试工具, ...

    5. Python爬虫入门之Cookie的使用

      本节我们一起来看一下Cookie的使用. 为什么要使用Cookie呢? Cookie,指某些网站为了辨别用户身份.进行session跟踪而储存在用户本地终端上的数据(通常经过加密) 比如说有些网站需要 ...

    6. 爬虫练习四:爬取b站番剧字幕

      由于个人经常在空闲时间在b站看些小视频欢乐一下,这次就想到了爬取b站视频的弹幕. 这里就以番剧<我的妹妹不可能那么可爱>第一季为例,抓取这一番剧每一话对应的弹幕. 1. 分析页面 这部番剧 ...

    7. 爬虫入门三 scrapy

      title: 爬虫入门三 scrapy date: 2020-03-14 14:49:00 categories: python tags: crawler scrapy框架入门 1 scrapy简介 ...

    8. 爬虫入门scrapy

      Python之路[第十九篇]:爬虫   网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本.另外一些不常使用 ...

    9. Python爬虫入门教程 37-100 云沃客项目外包网数据爬虫 scrapy

      爬前叨叨 2019年开始了,今年计划写一整年的博客呢~,第一篇博客写一下 一个外包网站的爬虫,万一你从这个外包网站弄点外快呢,呵呵哒 数据分析 官方网址为 https://www.clouderwor ...

    随机推荐

    1. [从源码学设计]蚂蚁金服SOFARegistry之延迟操作

      [从源码学设计]蚂蚁金服SOFARegistry之延迟操作 0x00 摘要 SOFARegistry 是蚂蚁金服开源的一个生产级.高时效.高可用的服务注册中心. 本系列文章重点在于分析设计和架构,即利 ...

    2. 白日梦的Elasticsearch实战笔记,ES账号免费借用、32个查询案例、15个聚合案例、7个查询优化技巧。

      目录 一.导读 二.福利:账号借用 三._search api 搜索api 3.1.什么是query string search? 3.2.什么是query dsl? 3.3.干货!32个查询案例! ...

    3. 计算机网络安全 —— 非对称加密算法 RSA 和数字签名(二)

      一.非对称加密算法基本概念 在对称密钥系统中,两个参与者要共享同一个秘密密钥.但怎样才能做到这一点呢?一种是事先约定,另一种是用信使来传送.在高度自动化的大型计算机网络中,用信使来传送密钥显然是不合适 ...

    4. echarts图表X轴文字过长解决解决方案:根据文字长度自动旋转

      Echarts 标签中文本内容太长的时候怎么办 ? 关于这个问题搜索一下,有很多解决方案.无非就是 省略(间隔显示).旋转文字方向.竖排展示 前面两种解决方案,就是echarts暴露的: {   ax ...

    5. Maven 知识点总结以及解决jar报冲突的几种方法

      1.常见的命令 Compile Test Package Install Deploy Clean 2.坐标的书写规范 groupId 公司或组织域名的倒序 artifactId 项目名或模块名 ve ...

    6. fiddler安装以及使用说明

      一.fiddler fiddler是一个抓包工具,通过使用它抓包我们可以很清晰的看到抓的内容的协议,URL,参数等. 1.安装 在普通下载网站找到安装包,直接安装,点击下一步即可. 二.使用 1.se ...

    7. 策略模式 VS 状态模式

      策略模式 VS 状态模式 策略模式 VS 状态模式 | 菜鸟教程 https://www.runoob.com/w3cnote/state-vs-strategy.html

    8. Python基础(列表中变量与内存关系)

      在Python中,copy的是内存地址,引用的是列表的引用地址,列表里存的是各个元素的地址 例如: name = [1,2,3,4,['xfxing','summer',6]] n2 = name.c ...

    9. 数据分析中常用的Excel函数

      数据分析中excel是一个常见且基础的数据分析工具,要想掌握好它,学会使用其中的常用函数是一个绕不过去的坎.从网上搜集的资料来说,基本上确定了数据分析中Excel的常用函数有以下这六类 数学函数:SU ...

    10. 十四:SpringBoot-配置MongoDB数据库,实现增删改查逻辑

      SpringBoot-配置MongoDB数据库,实现增删改查逻辑 1.MongoDB数据库 1.1 MongoDB简介 1.2 MongoDB特点 2.SpringBoot整合MongoDB 2.1 ...