Scrapy豆瓣项目实战

作者: Demafic | 来源:发表于2019-02-11 22:56 被阅读9次

    在没有scrapy时我们经常使用urllib,requests进行爬取,会封装http头部信息,代理,去重,数据存储,异常检验,造了许多轮子。
    十分麻烦。
    那么这时候scrapy出现了。scrapy是一套基于Twisted的异步处理框架,是纯python实现的爬虫框架,用户只需要定制开发几个模块就可以轻松的实现一个爬虫,用来抓取网页内容或者各种图片。

    认识Scrapy

    scrapy框架:

    image.png

    Scrapy Engine:Scrapy引擎,类似于交通站
    Schedule:Scrapy调度器,类似于队列
    Downloader:Scrapy下载器
    Spiders:Scrapy爬虫
    Item Pipeline:Scrapy管道
    Downloader MiddlewaresSpider Middlewares:Scrapy中间件

    Scrapy Engine发送requests请求给SchedulerScheduler进行排队。
    Downloader下载所有Scrapy。 Engine发送过来的请求,并将所有获得的response交还给引擎。
    然后引擎再将response交给Spiders进行解析。
    Spiders就是平时我们写正则表达式或者Xpath之类的组件,用于分析和提取数据。
    Spiders负责处理所有的数据,当然如果数据中含有别的url,会将url提交给引擎,再有引擎提交给Scheduler
    Item Pipeline就是我们封装去重类,存储类的地方。它是处理Spiders获取到的数据,并进行后期的处理,过滤或者存储。
    而其中一个中间件——Downloader Middlewares就是我们封装代理,隐藏爬虫的地方
    Spider Middlewares可以理解为自定义扩展引擎和Spiders之间通信功能的组件,比如说进入Spidersresponses和出去Spidersrequests,进行一些修改。

    数据流程

    Spiders里写入入口url,告诉Scrapy Engine要处理哪个网站;
    然后Scrapy Engine会告诉Scheduler,将这个request排列入队一下;
    Scheduler排好队之后将请求还给Scrapy Engine
    Scrapy Engine将需要下载的requestsDownloader
    如果Downloader没有下载好,会通过Scrapy Engine重新扔给Scheduler
    如果下载好了,生成了responses,交给Spiders
    Spiders就会进行数据解析;
    数据解析成两部分,一部分是我们需要的数据,直接交给Item PIpeline;另一部分就是新的请求,又扔给Scrapy Engine,重新进行循环,知道获取全部的信息。

    Scrapy项目实战准备

    爬取豆瓣电影top250数据,将数据保存为csv,json和储存到mongo数据库中。
    目标url:https://moviedouban.com/top250

    Scrapy抓取4步走:

    • 新建项目
    • 明确目标
    • 制作爬虫
    • 存储内容

    新建项目

    cmd内键入scrapy startproject douban
    即可在目标路径下新建名为doubanscrapy项目
    同时可以看到在此项目下有几个文件需要一一认识

    image.png

    介绍各个文件

    其中,scrapy.cfg是项目的配置文件。
    item.py是定义item数据结构的地方,所有的item定义都可以以在这编写。
    setting.py是项目的设置文件,比如说user_agent,robots协议,中间件设置,以及开启pipeline
    那么更重要的一个文件是在spiders内的spiders.py,需要我们在cmd内进行生成:scrapy genspider [爬虫名] [域名]
    比如这里我写成scrapy genspider doubanspider movie.douban.com
    那么会在spiders的文件夹内生成,如下图:

    image.png

    明确目标

    在目标网页中明确自己要获得的内容,比如我们需要的是排名,电影名,简介,星级,评论,描述
    那么在items.py中按照实例写好我们要抓取的项目:

    class DoubanSpiderItem(scrapy.Item):
        # define the fields for your item here like:
        # name = scrapy.Field()
        #序号
        serial_number = scrapy.Field()
        #电影名   
        movie_name = scrapy.Field()
        #介绍
        introduce = scrapy.Field()
        #星级
        star = scrapy.Field()
        #评论
        evaluate = scrapy.Field()
        #描述
        describe = scrapy.Field()
    

    制作爬虫

    打开douban_spider.py,

    class DoubanspiderSpider(scrapy.Spider):
        #爬虫名,不能和项目名相同
        name = 'doubanspider'
        #允许爬取的域名
        allowed_domains = ['movie.douban.com']
        #入口url,扔到调度器里
        start_urls = ['https://movie.douban.com/top250']
    

    根据上面的数据流程可知,这个入口url是要通过引擎扔给调度器的,调度器再通过引擎给下载器,下载器下载之后又会通过引擎,扔给spiders进行解析,那么解析的工作就是由parse来进行的。
    由于豆瓣是有反爬机制的,所以要在setting.py内将user_agent进行改写。
    同时代码如下:

    # -*- coding: utf-8 -*-
    import scrapy
    from douban_spider.items import DoubanSpiderItem
    
    class DoubanspiderSpider(scrapy.Spider):
        #爬虫名,不能和项目名相同
        name = 'doubanspider'
        #允许爬取的域名
        allowed_domains = ['movie.douban.com']
        #入口url,扔到调度器里
        start_urls = ['https://movie.douban.com/top250']
    
        def parse(self, response):
            movie_list = response.xpath('//ol[@class="grid_view"]//li')
            for i_item in movie_list:
                douban_item = DoubanSpiderItem()
                douban_item['serial_number'] = i_item.xpath('.//em/text()').extract()
                douban_item['movie_name'] = i_item.xpath('.//a//span[1]/text()').extract()
                content = i_item.xpath(".//div[@class='bd']/p[1]/text()").extract()
                for i_content in content:
                    content_s = ''.join(i_content.split())
                    douban_item['introduce'] = content_s
                douban_item['star'] = i_item.xpath(".//div[@class='star']/span[4]/text()").extract_first()
                yield douban_item
                #一个yield给piplelines 这是我们需要储存的数据
                
            next_link = response.xpath("//div[@class='paginator']/span[@class='next']/a/@href").extract()
            if next_link:
                next_link = next_link[0]
                yield scrapy.Request('https://movie.douban.com/top250'+str(next_link),callback=self.parse)
                #一个是我们又获得的url,扔给引擎
    

    存储内容

    cmd内键入

    scrapy crawl doubanspider -o test.csv
    

    即可以csv的格式保存
    同理,将test.csv改为test.json,即可以json的格式保存。
    当我们打开test.csv时,可能发现是乱码,那么我们用notepad++打开,将编码格式改为UTF-8-BOM,另存为即可。
    另外也可以存入mongo的啦,这个就下次再写啦。。

    制作词云

    不过我们这里为了制作词云,就先将它储存为txt文件。
    在pipelines.py内代码如下:

    class LldqspiderPipeline(object):
     
        
     
        
    #item在后期使用的时候还要转换回来,他存在的意义只是防止出错导致程序中止
        def process_item(self, item, spider):
            with open ('lldq.txt','a',encoding='utf-8') as f:
                f.write(str(item['previews']))
            print('储存成功')
            return item
    

    就可以获得lldq.txt啦。
    利用txt文件制作词云可以看我上一篇文章啦。

    结果

    同时第一次获得的词云中,流浪,地球出西安次数较多,考虑到这是电影名,所以也将这两个剔除。
    所以最后的结果:

    $M0~UHO~1OEB%G3X2D9$2Y9.png

    可以看到《流浪地球》作为一部科幻片还是广受好评的,可以说开启了中国科幻电影元年啊,特效也是相当宏大,堪比好莱坞,希望以后能见到越来越多如此优秀的中国科幻电影把。
    P&L

    相关文章

      网友评论

        本文标题:Scrapy豆瓣项目实战

        本文链接:https://www.haomeiwen.com/subject/zyonsqtx.html