美文网首页
Scrapy爬虫框架

Scrapy爬虫框架

作者: 雨林木风博客 | 来源:发表于2018-02-15 15:49 被阅读0次

    Scrapy是一个著名的爬虫框架,以前写爬虫都是用Python写那种特别原生低级的爬虫,一般都是以单线程为主,但是自己写多线程又会变的特别难,而且爬虫遇到突发状况就挂掉了。还有爬取某些网站,需要登录后才能抓取内容,所以涉及到模拟登录,总之感觉特别麻烦。虽然爬虫感觉很好玩,但是这一系列困难又成为了拦路虎!

    Docker安装Scrapy

    首先说一下Scrapy的安装吧,以前安装软件都会涉及好多依赖,往往安装这个软件,还得去下载别的依赖库,可能会遇到版本老啊,安装过程中报错啦,各种问题,总之,草泥马!所以在学习新技术的时候,并不是被这个新技术所难倒,而是首先软件的环境安装就被血虐!
    前一段时间学了Docker,这个东西真是特别爽啊!所以今天我们用Docker来进行scrapy环境的搭建。在Docker hub上搜索Scrapy,看看有没有好人已经把镜像给我们做好了!找到一个还算合适的!
    镜像名:aciobanu/scrapy
    地址:https://hub.docker.com/r/aciobanu/scrapy/

    把它拉取到本地仓库
    docker pull aciobanu/scrapy

    镜像

    我们用pycharm来连接docker环境,也就是一旦我们的pycharm连接上选中的容器,那么我们在pycharm中写的代码使用的环境将是容器内的环境,而不是本机的环境。
    我们的项目名字为tutorial,来连接一下docker

    打开Preferences

    打开Project Interpreter -->右边⚙-->add remote -->选中Docker-->在下面的框中选择aciobanu/scrapy 这个镜像

    连接docker

    现在环境已经搭建好了,屌不屌,真心很屌啊!用别人现成的镜像就好了!

    本机安装方法(不用Docker)
    https://www.jianshu.com/p/a03aab073a35

    建立项目

    标红的是我自己添加的,其他都是默认生成的!因为我本机也装了scrapy,所以直接用startproject命令建立的目录,如果仅仅用docker的话,目录需要自己手动建立!

    项目目录

    Scrapy原理介绍

    原理图
    Scrapy Engine

    Scrapy的引擎,用来对这几个大的模块进行控制。

    Scheduler调度器

    主要维护url队列。

    Downloader下载器

    主要负责获取页面数据。

    Spiders爬虫

    这个是我们来操作的,我们可以创建一个爬虫用于抓取某一类网站,可以设置爬虫的爬取策略等。

    Item Pipeline

    用来对获取的数据进行处理,比如把数据存放到数据库啊,或者直接用文件来存储啊。

    实战Scrapy框架

    原理再好不如拉出来溜溜!用一个实例来练习一下!
    我们来抓取博客园上的一些文章列表吧,来个简单易学的!
    博客园地址
    https://www.cnblogs.com/cate/mysql/1

    文章列表

    我们看到这个页面上有好多文章,每一个文章卡片显示该文章的标题,发布时间,摘要,阅读量。每一页都有20个这样的文章卡片。直到我抓取的时候,mysql系列文章有120页,而且每页对应的链接都是有规律的,https://www.cnblogs.com/cate/mysql/1这是第一页链接,https://www.cnblogs.com/cate/mysql/2这是第二页链接。

    我们最终想得到的数据是这样的,把每个文章的标题,阅读量,发布时间,摘要全部抓取下来,存储到项目根目录下的data.list文件中。

    结果数据

    开始写代码吧!
    在spiders目录下新建一个xiaohuar_spider.py的文件,代码如下:

    #!/usr/bin/env python
    # _*_ coding:utf-8 _*_
    import scrapy
    
    import sys
    reload(sys)
    sys.setdefaultencoding("utf8")
    
    class XiaoHuarSpider(scrapy.spiders.Spider):
    
       # 爬虫的名字,这个是必须有的,而且name变量名是框架规定好的
        name = "cnblogs_mysql"
        page_index = 1  # 标记第几页
    
       # url种子列表,这里我们以第一页为起始页面进行抓取,变量名为框架规定的,必须有,不可更改
        start_urls = ['https://www.cnblogs.com/cate/mysql/' + str( page_index )]
    
       # parse函数为框架默认函数,名称必须一样 
        def parse(self, response):
           
            # 利用xpath方式来定位网页元素,写过爬虫的都懂得
            post_items = response.xpath("//div[@id='wrapper']/div[@id='main']/div[@id='post_list']/div[@class='post_item']/div[@class='post_item_body']")
    
            # 把每页的20个文章卡片信息通过yield方式存储起来
            for post_items_body in post_items:
    
                yield {
                    'article_title':
                        post_items_body.xpath("h3/a/text()").extract_first().strip(),
                    'article_summary':
                        # post_items_body.xpath("p[@class='post_item_summary']/text()").extract_first().strip(),
                        post_items_body.xpath("p[@class='post_item_summary']/text()").extract()[1].strip(),
                    'article_date':
                        post_items_body.xpath("div[@class='post_item_foot']/text()").extract()[1].strip(),
                    'article_view':
                        post_items_body.xpath("div[@class='post_item_foot']/span[@class='article_view']/a/text()").extract_first().strip()
                }
                next_page_url = None
               # 标记当前是第几页
                self.page_index += 1  # 抓取完当前页就加1
    
                # 暴力些,我们把120页全抓了
                if self.page_index <= 120:
                   # 拼接生成下一个抓取url
                    next_page_url = "https://www.cnblogs.com/cate/mysql/" + str(self.page_index)
                else:
                    next_page_url = None
    
                if next_page_url is not None:
                   # 将下一个待抓取的url加入url队列,后续继续进行抓取
                    yield scrapy.Request(response.urljoin(next_page_url))
    

    然后把数据存储起来,打开pipelines.py文件,代码如下:

    # -*- coding: utf-8 -*-
    
    # Define your item pipelines here
    #
    # Don't forget to add your pipeline to the ITEM_PIPELINES setting
    # See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html
    
    
    class TutorialPipeline(object):
        # 默认函数,在爬虫启动的时候,创建data.list文件,设置为写权限
        def open_spider(self, spider):
            self.fp = open("data.list", "w")
    
        #  默认函数,在爬虫关闭的时候,把文件流关闭
        def close_spider(self, spider):
            self.fp.close()
    
       # 默认函数,用来把刚才yield存储的信息持久化到data.list中
        def process_item(self, item, spider):
    
            self.fp.write(item["article_title"] + "\n")
            self.fp.write(item["article_view"] + "\n")
            self.fp.write(item["article_date"] + "\n")
            self.fp.write(item["article_summary"] + "\n\n")
    
            return item
    

    设置settings.py,代码如下:

    # Configure item pipelines
    # See https://doc.scrapy.org/en/latest/topics/item-pipeline.html
    ITEM_PIPELINES = {
       'tutorial.pipelines.TutorialPipeline': 300,
    }
    

    其实现在代码已经写完了,是不是看起来很爽啊,非常模块化!

    正常启动Scrapy,直接在命令行终端用scrapy crawl 爬虫名就可以启动,但是由于我们的scrapy环境处于docker中,而本机没有scrapy环境,所以直接在命令行运行命令,是缺少环境的。所以我们写个python脚本利用docker内的环境执行,从而来启动爬虫。

    在项目根目录下新建begin.py,代码如下:

    from scrapy import cmdline
    
    cmdline.execute("scrapy crawl cnblogs_mysql".split())
    

    新建Python应用

    启动脚本

    在右上角点击下拉框,在弹出的对话框里,选择左上角➕号,选择Python,右侧给应用起名为spider,脚本路径为begin.py的路径,然后ok。

    直接运行spider应用就可以通过begin.py脚本把Scrapy爬虫启动起来!

    启动爬虫

    爬呀爬,爬呀爬。。。然后你会在根目录下发现多了一个data.list,打开之后的数据和上面演示的一样!

    相关文章

      网友评论

          本文标题:Scrapy爬虫框架

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