• 关于b站爬虫的尝试(二)


    前几天学习了scrapy的框架结构和基本的使用方法,部分内容转载自:http://blog.csdn.net/qq_30242609/article/details/52810840

    scrapy由编写蜘蛛的spiders文件夹和其他框架自带的几个python文件组成

    其中

    items.py

    双击打开这个文件,看一下都初始化了什么东西

    # -*- coding: urf-8 -*-
    # Define here the models for your scrapyed items
    #
    # See documentation in
    # http://doc.scrapy.org/en/latest/topics/items.html
    
    import scrapy
    
    class HeartsongItem(scrapy.Item):
        # define the fields for your item here like:
        # 
        # name = scrapy.Filed()
        pass
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    通过里面的注释可见,这个文件的作用是定义我们要爬取信息的标准格式,打个比方说,如果我们要爬取一批人的个人信息,包括姓名,性别,生日,那么我们可以这样来书写这个文件

    import scrapy
    
    class HeartsongItem(scrapy.Item):
       name = scrapy.Filed()
       sex = scrapy.Filed()
       birthday = scrapy.Filed()
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    易见本文件只是定义了一个类,至于什么时候实例化它,怎么保存它,请继续了解下面的内容。

    settings.py

    如其名,这是本项目的配置文件,里面注释着很多常用的配置项,我们通过在其他文件中引入本文件的方式来使用这些配置项。 
    当然,我们可以把这些注释都删掉,等需要开启哪个功能的时候再另行编辑。 
    我们此处先看看默认打开的配置项吧

    BOT_NAME = 'heartsong'
    SPIDER_MODULES = ['heartsong.spiders']
    NEWSPIDER_MODULE = 'heartsong.spider'
    # Obey robots.txt rules
    ROBORSTXT_OBEY = True
    • 1
    • 2
    • 3
    • 4
    • 5

    因为我们写的是定向爬虫,前面三个按默认即可,我们不去管他。看第四项,注释里说这个配置项的意思是是否遵守robots.txt,那么robots.txt是个什么东西呢? 
    通俗来说,robots.txt是遵循Robot协议的一个文件,它保存在网站的服务器中,它的作用是,告诉搜索引擎爬虫,本网站哪些目录下的网页不希望你进行爬取收录。在Scrapy启动后,会在第一时间访问网站的robots.txt文件,然后决定该网站的爬取范围。 
    当然,我们并不是在做搜索引擎,而且在某些情况下我们想要获取的内容恰恰是被robots.txt所禁止访问的。所以,我们就将此配置项设置为False,拒绝遵守Robot协议

    pipelines.py

    双击打开这个文件,看看都初始化了什么东西

    # -*- coding: utf-8 -*-
    
    # Define your item pipelines here
    # 
    # Don't forget to add your pipeline to the ITEM_PIPELINES setting
    # See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html
    
    class HeartsongPipeline(object):
        def process_item(self, item, spider):
            return item
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    从注释中所能得到的信息微乎其微,只告诉我们要启用此文件的话必须要在settings.py里配置一下ITEM_PIPELINES,好,那我们就老老实实的去settings.py里配置一下吧,不过注意,此处有坑,在1.0.x版本(极客学院教程中使用),配置项用list格式来书写,而在最新的1.1.2版本中,需要用dict格式,否则会报错,无法爬取,配置好后,我们的setting.py如下:

    # -*- coding: utf-8 -*-
    
    BOT_NAME = 'heartsong'
    SPIDER_MODULES = ['heartsong.spiders']
    NEWSPIDER_MODULE = 'heartsong.spider'
    
    ROBORSTXT_OBEY = True
    
    ITEM_PIPELINES = {
        'heartsong.pipelines.HeartsongPipeline': 300,
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    此处的300表示优先级,因为本项目只用到这一个pipeline,所以随意取0-1000中的一个数值即可。 
    好,镜头切回pipelines.py,这个文件到底有什么用呢?当然用处很多啦,本教程中介绍的作用只有两个: 
    * 对爬取到的数据(Item)进行处理,比如存入数据库 
    * 爬虫结束时产生事件,比如发送一封邮件

    爬虫

    在默认生成的spiders目录下新建heartsong_spider.py,我们的爬虫就写在这里面,因为是介绍,那么此处就写个简单的下载网站的主页,让大家能运行一下,感受一下scrapy。

    import scrapy
    
    class HeartsongSpider(scrapy.spiders.Spider):
        name = "heartsong"  # 爬虫的名字,执行时使用
        allowed_domains = ["heartsong.top"]  # 允许爬取的域名,非此域名的网页不会爬取
        start_urls = [
            "http://www.heartsong.top"  # 起始url,此例只爬这一个页面   
        ]
    
        def parse(self, response):  # 真正的爬虫方法
            html = response.body  # response是获取到的来自网站的返回
            # 以下四行将html存入文件
            filename = "index.html"
            file = open(filename, "w")
            file.write(html)
            file.close()
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    要说明的是,这个类不是随心所欲来写的,name,allowed_domains,start_urls,都是类似于”重载”的值。也就是说,scrapy内部会检测这些变量的值,变量名不可以起成其它的名字,类似的变量之后还会有介绍。至于parse方法,就是重载的父类的方法,我们爬虫的主体一般就写在这里面。 
    好,现在让我们来运行它 
    在命令行中进入heartsong目录下,执行命令

    scrapy crawl heartsong
    • 1

    此处的名字heartsong是与爬虫类中的name保持一致。   

    以上是scrapy的基本架构。

    由于递归爬取的时候存在超链接指向图片等问题反而增加request工作量,目前主要思考通过首先爬取所有up主信息,再爬取其空间内视频信息的办法。但是具体的爬取方案无法确定。如果要采取不遗漏的方法,又只能从视频方面开始爬取,回到了最初的问题。目前error视频的数量大概占总数量的一半,问题还不是很大,暂时搁置递归爬取的问题。

    目前依然采取根据av号枚举的方式访问视频并记录信息。根据测试程序的反馈,scrapy的爬取效率并不比request的方法高多少。。。可能有部分人认为的效率高主要由于scrapy自带的多进程爬取的方法。但是当request也采取多进程爬取时,主要耗时依然在于获取网络源码的过程中。这部分的时间目前没有办法减少。

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    import scrapy
    import re

    class bilibili(scrapy.Spider):
    name = "bilibili"
    # 允许的域名
    allowed_domains = ["bilibili.com"]
    start_urls = []
    for av in xrange(10000):
    start_urls.append("http://www.bilibili.com/video/av"+str(av))

    def parse(self, response):
    page = response.body
    temp = re.search(r'<div class="v-title"><h1 title="(.+?)">', page)
    if temp:
    title = re.search(r'<div class="v-title"><h1 title="(.+?)">', page).group(1)
    authorkit = re.search(r'r-info.+?title="(.+?)"', page)
    if authorkit:
    author = authorkit.group(1)
    aid = re.search(r'aid=(d+)', page).group(1)
    cid = re.search(r'cid=(d+)', page).group(1)
    print cid
    print aid
    url = 'https://api.bilibili.com/x/web-interface/archive/stat?aid='+str(aid)
    return scrapy.http.Request(url=url, callback=self.parse_item_page)

    def parse_item_page(self, response):
    print response.body
  • 相关阅读:
    Fiddler配置代理hosts的方法
    Android利用Fiddler进行网络数据抓包
    Android键盘面板冲突 布局闪动处理方案
    View的三次measure,两次layout和一次draw
    jquery.fly.min.js 拋物插件
    js刷新页面方法大全
    Console命令详解,让调试js代码变得更简单
    div中的内容垂直居中的五种方法
    Struts2之i18N国际化
    maven阿里云中央仓库
  • 原文地址:https://www.cnblogs.com/silencestorm/p/8513076.html
Copyright © 2020-2023  润新知