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 

然后把数据存储起来,打开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"] + "nn")

        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爬虫框架

发表评论