• Scrapy 框架 (学习笔记-1)


    环境:

    1.windows 10
    2.Python 3.7
    3.Scrapy 1.7.3
    4.mysql 5.5.53

    一、Scrapy 安装

    1. Scrapy:是一套基于Twisted的一部处理框架,是纯Python实现的爬虫框架,用户只需要定制开发几个模块就可以轻松的实现一个爬虫,用来抓取网页内容或者各种图片。
    1. 安装命令:pip install scrapy
    2. 查看是否安装成功,命令: scrapy

    二、项目实战

    1. 抓取豆瓣电影('https://movie.douban.com/top250')Top250数据,并将数据保存为csv,json和存储到数据库中
    2. 一个完整项目基本包括:新建项目、明确目标、制作爬虫、存储内容四个步骤。

    (一)、新建项目

    1. 创建项目
        命令: scrapy startproject [项目名称]     例:scrapy startproject Douban
        项目目录结构:
            # Douban
                # Douban
                    # spiders
                        # __init__.py
                    # __init__.py
                    # items.py
                    # middlewares.py
                    # pipelines.py    
                    # settings.py
                # scrapy.cfg
    2.创建爬虫 
        在spiders下执行命令: scrapy genspider [爬虫名] [待爬取网站的域名]    例:scrapy genspider douban_top250 movie.douban.com (此时spiders目录下会生成一个'douban_top250.py'爬虫文件)

    == 注意:爬虫名称不能与项目名称重复 ==

    (二)、明确目标


    1. 明确要抓取哪些数据,并在 items.py 文件中进行定义.

       例:
            import scrapy
    
            class DoubanItem(scrapy.Item):
                # define the fields for your item here like:
                # name = scrapy.Field()
    
                # 序号
                serial_num = scrapy.Field()
                # 电影名称
                movie_name = scrapy.Field()
                # 电影介绍
                introduce = scrapy.Field()
                # 电影评论数
                evaluate_num = scrapy.Field()
                # 电影描述
                describe = scrapy.Field()
                # 电影星级
                star = scrapy.Field()

    (三)、制作爬虫

    1.打开爬虫文件(douban_top250.py)

        # -*- coding: utf-8 -*-
        import scrapy
    
        class DoubanTop250Spider(scrapy.Spider):
            # 爬虫名称
            name = 'douban_top250'
            # 允许的域名
            allowed_domains = ['movie.douban.com']
            # 入口URL
            start_urls = ['https://movie.douban.com/top250']
    
            def parse(self, response):
                pass

    2.在settings.py文件中开启 'USER_AGENT' 并设置为正确的代理

    3.输出爬取的信息 例:

      def parse(self, response):
            print(response.text)
    4.执行爬虫运行命令: scrapy crawl [爬虫名称]   例: scrapy crawl douban_top250

    == 注意:必须在 spiders 文件夹下执行 scrapy crawl 命令 ==

    5.解析爬取的网页数据,例:
    # -*- coding: utf-8 -*-
    import scrapy
    from Douban.items import DoubanItem
    class DoubanTop250Spider(scrapy.Spider):
        # 爬虫名称
        name = 'douban_top250'
        # 允许的域名
        allowed_domains = ['movie.douban.com']
        # 入口URL
        start_urls = ['https://movie.douban.com/top250']
    
        # 默认的解析方法
        def parse(self, response):
            # 导入item文件,实例对象
            res = DoubanItem()
            # 书写详细的xpath语句对数据进行解析
            # 获取第一页的所有电影
            movie_list = response.xpath('//div[@class="article"]/ol[@class="grid_view"]/li')
            # 循环获得的电影
            for movie in movie_list:
                # 获取电影序号
                res['serial_num'] = movie.xpath('.//div[@class="item"]/div[@class="pic"]/em/text()').extract_first()
                # 获取电影名称
                titles = movie.xpath('.//div[@class="item"]/div[@class="info"]/div[@class="hd"]/a/span/text()').extract()
                movie_name = ''
                for title in titles:
                    movie_name = movie_name + "".join(title.split())
                res['movie_name'] = movie_name
                # 获取电影介绍
                res['introduce'] = "".join(movie.xpath('.//div[@class="bd"]/p/text()').extract_first().split())
                # 获取电影评论数
                res['evaluate_num'] = movie.xpath('.//div[@class="star"]/span[4]/text()').extract_first()
                # 获取电影描述
                res['describe'] = movie.xpath('.//div[@class="bd"]/p[@class="quote"]/span/text()').extract_first()
                # 获取电影的评分
                res['score'] = movie.xpath('.//div[@class="star"]/span[2]/text()').extract_first()
                # 将结果提交至管道pipelines里面,进行数据的清洗以及存储
                yield res
            # 解析下一页规则
            string = response.xpath('.//span[@class="next"]/a/@href').extract_first()
            if string :
                href = self.start_urls[0] + string
                yield scrapy.Request(href,callback=self.parse)

    (四)、存储内容


    1、将数据保存为 json、csv 文件

       命令:scrapy crawl [爬虫名称] -o [保存文件名]
        例:
            1. scrapy crawl douban_top250 -o douban1.json
            2. scrapy crawl douban_top250 -o douban2.csv

    2、将数据保存至数据库中

      1. 创建mysql数据库及相关表
        2. 在settings.py文件中开启 EXTENSIONS 设置
        3. 在pipelines.py文件中导入pymysql模块
        4. pipelines.py文件中类的命名是创建项目时自动生成的,一般为: [项目名称]Pipeline
        5. 在类中process_item方法内进行保存数据操作
        例:
    # -*- coding: utf-8 -*-
    
    # Define your item pipelines here
    #
    # Don't forget to add your pipeline to the ITEM_PIPELINES setting
    # See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html
    
    # 导入pymysql模块
    import pymysql
    
    class DoubanPipeline(object):
    
        # 初始化相关属性
        def __init__(self):
            # 连接database
            try:
                self.conn = pymysql.connect(
                    host="127.0.0.1",  # 数据库IP地址
                    port=3306,  # 端口号
                    db="python_movie",  # 数据库名称
                    user="root",  # 用户名
                    password="root",  # 密码
                    charset="utf8",  # 编码格式
                    use_unicode=True,  # 指定字符的编码、解码格式
                    cursorclass=pymysql.cursors.DictCursor,  # 数据返回格式
                )
                # 得到一个可以执行SQL语句的光标对象
                self.cursor = self.conn.cursor()
            except Exception as e:
                print(e)
    
        # 开启爬虫时执行,只执行一次
        def open_spider(self,spider):
            pass
    
        # 处理提取的数据(保存数据)
        def process_item(self, item, spider):
            sql = "INSERT INTO movie (serial,`name`,introduce,evaluate,`describe`,score) VALUES (%s,%s,%s,%s,%s,%s)"
            # 执行sql语句
            try:
                self.cursor.execute(sql, tuple(item.values()))
                self.conn.commit()
            except Exception as e:
                print(e)
    
        # 关闭爬虫时执行,只执行一次。 (如果爬虫中间发生异常导致崩溃,close_spider可能也不会执行)
        def close_spider(self, spider):
            self.cursor.close()
            self.conn.close()

    (五)、下载中间件编写


    1. 设置代理 IP

    1.在middlewares.py文件中编写
    2.创建一个类,继承 object,在此类中编写代理IP
    3.在类中创建方法
    def process_request(self,request,spider):
            pass
    注意:这个方法名称是固定默认的,
    4.在process_request方法中设置request中的meta属性中的prproxy参数,参数值为自己的代理服务器与端口号
    request.meta['proxy'] = '[IP地址/域名]:[端口号 ]'
    5.在process_request方法中设置代理的用户名与密码,固定格式为:
    proxy_name_pass = '[用户名]:[密码]'
    注意:用户名与密码中间用':'号分割
    6.需要用base64.b64encode()对用户名与密码进行加密,而且base64.b64encode()只接受bytes格式的字符串,故:
    proxy_name_pass = base64.b64encode(b'[用户名]:[密码]')
    7.设置http请求头
    request.headers['Proxy-Authorization'] = 'Basic ' + proxy_name_pass.decode()
    8.将代理中间添加至settings.py中的 DOWNLOADER_MIDDLEWARES 中进行注册
    例:
    在 middlewares.py 中编写中间件
    class my_proxy(object):
        # 这个方法名 'process_request' 是固定的
        def process_request(self,request,spider):
            # 设置代理服务器IP地址
            request.meta['proxy'] = "这里写代理IP:这里写端口号"
            # 设置代理服务器账号与密码(注意账号与密码用 ':' 号分割,并且将字符串变为bytes格式)
            proxy_name_pass = b"这里写账号:这里写密码"
            # 加密账号与密码
            encode_name_pass = base64.b64encode(proxy_name_pass)
            # 设置代理服务请求头(注意:Basic后面必须加空格,而且加密后的账号与密码必须转为字符串格式才能拼接)
            request.headers['Proxy-Authorization'] = 'Basic ' + encode_name_pass.decode()  
    在 settings.py 中设置中间件
    # 注意,后面的数字,表示中间件的优先级,多个中间价同时启用时优先级不可以相同
    DOWNLOADER_MIDDLEWARES = {
       'Douban.middlewares.DoubanDownloaderMiddleware': 543,
       'Douban.middlewares.my_proxy': 544,
    }

    2. 设置 User-Agent

    1.同上,在middlewares.py中创建一个类,在默认的process_request()方法中编写中间件
    2.同上,将编写的中间件添加至settings.py中的 DOWNLOADER_MIDDLEWARES 中进行注册
    3.具体操作直接上代码:
    例:
    在 middlewares.py 中编写中间件
    # 设置代理IP中间件
    class my_proxy(object):
        def process_request(self,request,spider):
            # 设置代理服务器IP地址
            request.meta['proxy'] = "这里写代理IP:这里写端口号"
            # 设置代理服务器账号与密码(注意账号与密码用 ':' 号分割,并且将字符串变为bytes格式)
            proxy_name_pass = b"这里写账号:这里写密码"
            # 加密账号与密码
            encode_name_pass = base64.b64encode(proxy_name_pass)
            # 设置代理服务请求头(注意:Basic后面必须加空格,而且加密后的账号与密码必须转为字符串格式才能拼接)
            request.headers['Proxy-Authorization'] = 'Basic ' + encode_name_pass.decode()
    
    # 设置随机User_Agent中间件
    class my_user_agent(object):
        def process_request(self,request,spider):
            # 在网络上搜索User_Agent列表
            USER_AGENT_LIST = [
                 "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; AcooBrowser; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",
                 "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Acoo Browser; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506)",
                 "Mozilla/4.0 (compatible; MSIE 7.0; AOL 9.5; AOLBuild 4337.35; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",
                 "Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US)",
                 "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0)",
                 "Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 1.0.3705; .NET CLR 1.1.4322)",
                 "Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.04506.30)",
                 "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/523.15 (KHTML, like Gecko, Safari/419.3) Arora/0.3 (Change: 287 c9dfb30)",
                 "Mozilla/5.0 (X11; U; Linux; en-US) AppleWebKit/527+ (KHTML, like Gecko, Safari/419.3) Arora/0.6",
                 "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.2pre) Gecko/20070215 K-Ninja/2.1.1",
                 "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9) Gecko/20080705 Firefox/3.0 Kapiko/3.0",
                 "Mozilla/5.0 (X11; Linux i686; U;) Gecko/20070322 Kazehakase/0.4.5",
                 "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.8) Gecko Fedora/1.9.0.8-1.fc10 Kazehakase/0.5.6",
                 "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11",
                 "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.20 (KHTML, like Gecko) Chrome/19.0.1036.7 Safari/535.20",
                 "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; fr) Presto/2.9.168 Version/11.52",
            ]
            # 随机获取一个user_agent,而random.choice()函数,表示从序列中随机选取一个元素
            user_agent = random.choice(USER_AGENT_LIST)
            # 设置Http请求头中的User_Agent
            request.headers['User_Agent'] = user_agent
    在 settings.py 中设置中间件
    # 注意,后面的数字,表示中间件的优先级,多个中间价同时启用时优先级不可以相同
    DOWNLOADER_MIDDLEWARES = {
       'Douban.middlewares.DoubanDownloaderMiddleware': 543,
       'Douban.middlewares.my_proxy': 544,
       'Douban.middlewares.my_user_agent': 545,
    }

    == 注意:1. 中间件定义编写完成以后,一定要在 settings.py 文件中的 DOWNLOADER_MIDDLEWARES = {} 中注册中间件,表示启用此中间件;2. 爬虫文件名和爬虫名称不能相同,spider 目录内不能存在相同爬虫名称的项目文件 ==

    交流群:887934385 

  • 相关阅读:
    python3.6配置flask
    jquery匿名函数和闭包(它山之石)笔记
    .net扩展方法
    对象继承
    MAC OS X PKG FILES
    NLP——天池新闻文本分类 Task2
    Python基础TASK1:变量与数据类型
    NLP——天池新闻文本分类 Task1
    随机分析与随机过程中的一些基本概念
    Java线程池
  • 原文地址:https://www.cnblogs.com/pypypy/p/12002180.html
Copyright © 2020-2023  润新知