zoukankan      html  css  js  c++  java
  • 20200227 scrapy框架

    昨日回顾

    # 1 xpath
    
    /    //和能看懂    
    
    用:去copy      
    
    ## 2 selenium
    
    驱动浏览器,模拟浏览器行为(为解决js执行的问题)
    
    page_source 
    
    查找标签:点击,键盘输入,清空,写文字
    
    执行js:打开标签,滑动屏幕
    
    cookie(重要):可以手动通过selenium登陆进去,取到cookie,搭建cookie池
    
    动作链:很炫,基本用处很少
    
    ## 3 抓包工具的使用
    
    抓手机包:移动开发的后端(postman),抓包工具
    
    移动开发人员在你手机上装一个连接你机器的app
    
    app--resful接口-》10.0.0.1  
    
    app-------抓包工具(可以看到发送和接受到的数据什么样)----------->你电脑的ip(跑着项目),在你电脑上加断点
    

    scrapy框架

    1.介绍

    Scrapy 是一个基于 Twisted 的异步处理框架,是纯 Python 实现的爬虫框架,其架构清晰,模块之间的耦合程度低,可扩展性极强,可以灵活完成各种需求。我们只需要定制开发几个模块就可以轻松实现一个爬虫。

    1.1 框架的生命周期

    img

    它可以分为如下的几个部分。

    • Engine,引擎,用来处理整个系统的数据流处理,触发事务,是整个框架的核心。
    • Item,项目,它定义了爬取结果的数据结构,爬取的数据会被赋值成该对象。
    • Scheduler, 调度器,用来接受引擎发过来的请求并加入队列中,并在引擎再次请求的时候提供给引擎。
    • Downloader,下载器,用于下载网页内容,并将网页内容返回给蜘蛛。
    • Spiders,蜘蛛,其内定义了爬取的逻辑和网页的解析规则,它主要负责解析响应并生成提取结果和新的请求。
    • Item Pipeline,项目管道,负责处理由蜘蛛从网页中抽取的项目,它的主要任务是清洗、验证和存储数据。
    • Downloader Middlewares,下载器中间件,位于引擎和下载器之间的钩子框架,主要是处理引擎与下载器之间的请求及响应。
    • Spider Middlewares, 蜘蛛中间件,位于引擎和蜘蛛之间的钩子框架,主要工作是处理蜘蛛输入的响应和输出的结果及新的请求。

    1.1 框架流程

    Scrapy 中的数据流由引擎控制,其过程如下:

    • Engine 首先打开一个网站,找到处理该网站的 Spider 并向该 Spider 请求第一个要爬取的 URL。
    • Engine 从 Spider 中获取到第一个要爬取的 URL 并通过 Scheduler 以 Request 的形式调度。
    • Engine 向 Scheduler 请求下一个要爬取的 URL。
    • Scheduler 返回下一个要爬取的 URL 给 Engine,Engine 将 URL 通过 Downloader Middlewares 转发给 Downloader 下载。
    • 一旦页面下载完毕, Downloader 生成一个该页面的 Response,并将其通过 Downloader Middlewares 发送给 Engine。
    • Engine 从下载器中接收到 Response 并通过 Spider Middlewares 发送给 Spider 处理。
    • Spider 处理 Response 并返回爬取到的 Item 及新的 Request 给 Engine。
    • Engine 将 Spider 返回的 Item 给 Item Pipeline,将新的 Request 给 Scheduler。
    • 重复第二步到最后一步,直到 Scheduler 中没有更多的 Request,Engine 关闭该网站,爬取结束。

    通过多个组件的相互协作、不同组件完成工作的不同、组件对异步处理的支持,Scrapy 最大限度地利用了网络带宽,大大提高了数据爬取和处理的效率。

    五大组件

    引擎:大总管,总的控制数据流动

    调度器:去重,加入队列

    下载器:负责下载,加载数据

    爬虫:咱们主要在这写,解析response和重新发起请求

    项目管道:持久化相关

    二大中间件

    爬虫中间件:爬虫和引擎之间(用的少)

    下载中间件:引擎和下载器之间(加代理,加cookie,修改user-agent,集成selenium)

    2.安装

    mac/Linux: 
    	pip install scrapy
    
    
    windows:	(两种方式)	
    	1. pip install scrapy
    	
    	2. 如果报错,以下
    		-pip install wheel	(xxx.whl文件安装模块)
    		-下载pywin32	
    			-pip install pywin32  或者 下载.exe文件安装https://sourceforge.net/projects/pywin32/files/pywin32/
             -下载twisted的wheel文件
             - 执行pip iinstall 下载目录Twisted-17.9.0-cp36-cp36m-win_amd64.whl(可以直接手动拖放至控制台)
    
    

    3.创建项目

    通过命令行

    # 创建项目
    scrapy startproject 项目名
    
    
    # 创建爬虫
    	#(django中创建app)在spiders文件夹下创建一个py文件,一个py文件就是一个爬虫(不要注册,没有注册一说)
    scrapy genspider 爬虫名 爬取的地址
    scrapy genspider chouti dig.chouti.com
    
    # 打开项目,pycharm打开
    

    运行爬虫

    # 命令行运行
    scrapy crawl 爬虫名
    scrapy crawl 爬虫名 --nolog	# 不打印日志
    	或者更改log级别: LOG_LEVEL='ERROR'	# 也可不打印日志
    	
        
        
    # pycharm运行
    设置
    	在项目目录下创建一个py文件,假设叫main.py,点击右键执行即可执行爬虫,等同于命令
        from scrapy.cmdline import execute
    	execute(['scrapy','crawl','chouti','--nolog'])
    
    

    保存数据到本地文件

    # 保存文件的指令
    from scrapy.cmdline import execute
    execute(['scrapy', 'crawl',  'lianjia', '-o', 'items.csv','--nolog'])
    

    目录介绍

    -scarpyfirst 项目名
    	-scrapy.cfg 		 上线相关的(不用管)
      	-scrapyfirst 		 文件夹
      	-spiders文件夹         所有的爬虫写在这里面
        	-chouti.py		  一个py文件就是一个爬虫(类似于django的app)
            -items.py         :配合管道,做数据存储(类似于django中models.py 写一个个的模型类)
        -middlewares.py   		:中间件(爬虫中间件,下载中间件都写在这里面)
        -pipelines.py  			:管道,持久化相关,数据存储卸载这
        -settings.py			:配置文件相关
    

    setting介绍

    #配置文件全是大写
    ROBOTSTXT_OBEY = True  #是否遵循爬虫协议,如果是true,基本上网站都爬不了,遵循要爬取网站的爬虫协议,一般设置成false
    USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36'
    LOG_LEVEL='ERROR'   # 只打印错误信息
    
    # 控制持久化的类执行顺序
    ITEM_PIPELINES = {
       'mypachong.pipelines.MypachongMySQLPipeline': 100,  # 优先级,数值越小,优先级越高
       'mypachong.pipelines.MypachongPipeline': 300,        # 优先级,数值越小,优先级越高
    }
    

    使用--爬取天猫

    自定义启动文件run.py

    #-*- coding: utf-8 -*-
    #!/usr/bin/env python3
    
    ' 启动文件 '
    
    __author__ = 'Fwzzz'
    
    # 代替cmd的命令
    from scrapy.cmdline import execute
    execute(['scrapy','crawl','chouti','--nolog'])
    # execute(['scrapy','crawl','chouti'])
    
    

    爬虫文件

    # -*- coding: utf-8 -*-
    import scrapy
    from urllib.parse import urlencode
    from mypachong import items
    
    
    # 爬取天猫
    
    
    
    class ChoutiSpider(scrapy.Spider):
        # 爬虫名
        name = 'chouti'
        # 允许爬取的域名
        allowed_domains = ['www.tmall.com']
        # 初始请求  自行向域名发送get请求获取数据
        # start_urls = ['http://www.baidu.com/']
    
    
    # 自定义初始请求
    
        # 实例化获取初始请求对象
        def __init__(self,*args,**kwargs):
            # 继承父类的属性
            super(ChoutiSpider,self).__init__(*args,**kwargs)
            # 定义接口的url
            self.api = 'http://list.tmall.com/search_product.htm?'
            # 定义搜索的接口参数     (通过urlencode拼接)
            self.param = {
                    'q' :'女装大佬',
                    'totalPage' :1,
                    'jumpto' :1
            }
    
        # 想要自行发送定义请求,重写Spider类中的start_requests方法
        def start_requests(self):
            # 获取主页的url
            url = self.api + urlencode(self.param)
            # 搜索页发送请求
            # callback 回调函数,进行处理获取数据   并指定dont_filter=True 链接不去重
            yield scrapy.Request(url=url,callback=self.getpage,dont_filter=True)
    
    
        # 获取响应,进行数据的清洗(获取总页码)
        def getpage(self,response):
            # 进行解析
            page = response.css('[name="totalPage"]::attr(value)').extract_first()
            # print(page)   # 30
            # 将接口的url页数更换
            self.param['totalPage'] = int(page)
            # 发送新的请求,获取所有页面的数据
            # for i in range(1,self.param['totalPage']+1):
            for i in range(1,2):
                self.param['jumpto'] = i
                # 拼接url
                url = self.api + urlencode(self.param)
                # 发送请求到新的回调函数中去
                yield scrapy.Request(url,callback=self.get_info,dont_filter=True)
    
    
        # 解析页面中的数据
        def get_info(self, response):
            # 获取数据 价格,商品名,交易量,图片
            # 先获取当前页面的所有商品标签对象
            product_list = response.css('.product  ')
            for product in product_list:
                # 解析单数据
                good_title = product.css('.productTitle a::attr(title)').extract_first()
                good_price = product.css('.productPrice em::attr(title)').extract_first()
                good_img = product.css('.productImg img::attr(src)').extract_first()
                # 图片懒加载解决
                if not good_img:
                    good_img = product.css('.productImg img::attr(data-ks-lazyload)').extract_first()
                # print(good_title,good_img,good_price)
    
                # 返回数据给items或者继续发送请求
                item = items.MypachongItem()    # 实例化获得items对象
                # 将数据封装成items对象
                item['good_title'] = good_title
                item['good_price'] = good_price
                item['good_img'] = good_img
    
                # 这里需要设置setting文件中的ITEM_PIPELINES,yield之后并触发pipelines
                yield item
    
    

    items文件 控制接收持久化字段

    # -*- coding: utf-8 -*-
    
    # Define here the models for your scraped items
    #
    # See documentation in:
    # https://docs.scrapy.org/en/latest/topics/items.html
    
    import scrapy
    
    
    # 规定了items接受的那些对象
    class MypachongItem(scrapy.Item):
        # define the fields for your item here like:
        # name = scrapy.Field()
        good_title = scrapy.Field()
        good_price = scrapy.Field()
        good_img = scrapy.Field()
    
    

    pipelines.py 持久化存储

    # -*- 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
    
    import pymysql
    
    
    # 存数据 --文件保存方式
    class MypachongPipeline(object):
    
        def open_spider(self,spider):
            '''爬虫打开时触发一次'''
            print('我打开了')
            self.f = open('a.txt','w')
    
    
        def process_item(self, item, spider):
            '''每次数据都会触发'''
            # print('在items后我被触发了')
            self.f.write(item['good_title']+item['good_price']+item['good_img'])
            self.f.write('
    ')
            return item
    
        def close_spider(self,spider):
            '''爬虫关闭之后触发一次'''
            print('我关闭了')
    
    
    
    # 存数据 --MySQL保存方式  需要去settings文件中设置ITEM_PIPELINES优先级
    class MypachongMySQLPipeline(object):
        def open_spider(self,spider):
            self.conn = pymysql.connect(
                host='127.0.0.1',
                user='root',
                password='',
                database='tianmao',
                port=3306
            )
            print('我打开了mysql')
    
        def process_item(self, item, spider):
            cursor = self.conn.cursor()
            sql = "insert into article (title,price,img) values ('%s','%s','%s')"%(item['good_title'],item['good_price'],item['good_img'])
            # sql = f"insert into article (title,price,img) values ('{item['good_title']}','{item['good_price']}','{item['good_img']}')"
            cursor.execute(sql)
            # 提交
            self.conn.commit()
    
    
        def close_spider(self,spider):
            self.conn.close()
            print('我关闭了mysql')
    

    settings.py

    BOT_NAME = 'mypachong'
    
    
    
    SPIDER_MODULES = ['mypachong.spiders']
    NEWSPIDER_MODULE = 'mypachong.spiders'
    
    
    
    ROBOTSTXT_OBEY = False
    
    
    
    # 控制持久化的类执行顺序
    ITEM_PIPELINES = {
       'mypachong.pipelines.MypachongMySQLPipeline': 100,  # 优先级,数值越小,优先级越高
       'mypachong.pipelines.MypachongPipeline': 300,        # 优先级,数值越小,优先级越高
    }
    

    4. scrapy的数据解析(重点)

    css选择器

    res.css('[name="tag"]::text').extract_first()
    
    	::text		获取标签内文本
    	::attr(属性)	获取标签属性值
                
    # 需要与下面的extract想配合获取内容
    
        .extract()		获取对象内容列表
    	.extract_first()	获取第一个
    
    

    5. scrapy的持久化存储(重点)

    详细使用参见上面的爬取天猫案例

    第一种,通过命令:scrapy crawl chout -o aa.csv  (用的比较少)
    	需要在parser解析方法中返回列表套字典的格式
        
        
    第二种:通过管道方式(文件,数据,redis,mongodb),同时支持以多种方式存储
    	-1 在items.py中定义一个类,写属性(要存多少字段,就有多少属性)
    	-2 在爬虫中中解析出数据,把数据放到这个类对象中,然后  yield item
      	-3 在配置文件中配置:ChoutiPipeline对应pipelines.py中的类
      	ITEM_PIPELINES = {
       		'scrapyfirst.pipelines.ChoutiPipeline': 300,   # 数字表示优先级,数字越小,优先级越高
    		}
      -4 pipelines.py中写ChoutiPipeline类
      	-open_spider:开启时调用,打开文件,打开数据库连接
        -process_item:存数据
        -close_sapider:关闭时调用,关闭文件,关闭数据库连接
        
      -总结:ITEM_PIPELINES可以写多个,有优先级的,数字越小,优先级越大,一定要注意process_item一定要return ,					否则后续就拿不到item了
    

    补充

    1 pycharm系列激活

    http://idea.medeming.com/jet/
    

    2 ide,开发工具

    你用什么ide?

    ide系列:
    
    java:eclipse(免费),myeclips(收费),idea(大部分java都用它)
    
    python:pycharm,vscode(微软出的,免费,go,c,python,java)
    
    go:goland,vscode。。
    
    开发安卓:eclipse+adt,谷歌爸爸花钱买了jetbrains公司的版权idea+adt=androidstatdio(免费)
    
    java,当年已经有大量的java开发人员,java可以直接无缝转过去,java虚拟机
    
    开发ios:必须买Mac,Xcode(黑苹果)
    
    jetbrains公司全家桶系列:idea,pycharm,webstom,goland,php
    

    python体系

    python基础,mysql,前端,web框架,爬虫,数据分析,人工智能
    

    java体系

    javase:基础,可以做桌面开发(基本上没有)
    
    学完基础+安卓相关包的学习
    
    javaee:web相关
    
    javame:手机开发(不是安卓,ios,很古老的java手机软件)
    
    区别:jdk,jre,jvm
    
    jdk:java软件开发工具包,java开发人员需要安装
    
    jre:java运行环境,java软件才能运行
    
    jvm:java虚拟机 (java程序运行在虚拟机之上),跨平台,一次编码到处运行
    
    c/c++:如果想在windwos上运行,需要在window上编译  exe
    
    go----》编译之后---》直接可以运行   跨平台编译:在windows平台可以编译出liunx下可执行的文件
    
    java写了代码----》编译--》jar包和war包  不是编译成直接可以运行的二进制(中间态)---》需要操作系统装java虚拟机(java虚拟机,要跑起来,至少就得占500m内存)
    
  • 相关阅读:
    ENode 1.0
    ENode 1.0
    ENode 1.0
    canvas转图片
    Canvas API
    微信 js api[转]
    Dicom格式文件解析器[转]
    跟我学AngularJS:全局变量设置之value vs constant vs rootscope vs 服务[转]
    angularJS 事件广播与接收[转]
    RequireJs
  • 原文地址:https://www.cnblogs.com/fwzzz/p/12460459.html
Copyright © 2011-2022 走看看