四个scrapy爬虫

                                              scrapy 爬虫

1.普通scrapy爬虫知识

     1.scrapy cmd命令

       1.scrapy shell 就可以开始运行脚本了 

                 开启了scrapy 脚本运行环境列:

                  

       2.scrapy fetch http://www.baidu.com   打印网页源码

       3.scrapy view https://www.biadu.com   下载网页源代码 并用浏览器打开  可查看是否动态加载非常好用

      4.创建和运行

          创建一个项目: scrapy startproject  项目名     --->  scrapy genspider  文件名 起始url  

           运行 :   1.scrapy crawl  项目名     2. 进入到项目根目录  scrapy runspider  文件名.py    

       5.csv json 类的通过命令保存

        直接在运行时输入  改变保存格式

scrapy crawl spdiername -o name.csv

       3.创建一个start.py  

          from scrapy.cmdline import execute

         execute('scrapy crawl manhua'.split())  运行就可以了

     2.普通scrapy

         1.scrapy 中xpath的结果:

          [<Selector xpath='//div[@class="co_content2"]/ul/a' data='<a> <img src="/images/m.jpg" width="180"'>]

          scrapy 中xpath() 后的结果是一个 selector  对象列表   可以继续 xpath

           extract()   的作用是 取出 data中的数据 组成一个列表

          .extract_first()  取列表的第一个元素   extract()[i]取列表第i个元素

          .extract_first(default=’’)        如果找不到则默认为 ...

          2.其他知识

              response .body 表示取得二进制文件         response.text 也可以出来是页面源码 然后可以用正则解析

           3.注意事项

              1.注意item=实例化的位置 每循环一次(产生一个新的值)都要实例化一个新的item

              2.yeild item:放在最后一次循环后面 每实例化一个新的item 提交一次

              3.通过meta传参方法

                    scrapy.Request(meta={'abc':item})               接受参数   item=response.meta['abc']

               4.from copy import deepcopy 当for 循环下 需要多个item数据时  可使用 deepcopy  复制一个新的空间 

                5.重写__init__方法时    需要继承父类  super(之类名,self).__init__()   

      3.管道类pipelines 

              1.利用管道类添加数据

# 在管道中可以添加一些数据  给item
class AqiPipeline(object):
    def process_item(self, item, spider):
        item['crawl_time'] = datetime.now()
        item['spider_name']=spider.name
        return item

               2.JSON管道 CSV类似

from scrapy.exporters import JsonItemExporter, CsvItemExporter
class Aqi Json/Csv Pipeline(object):
    def open_spider(self, spider):
        self.file = open('aqi.json/csv', 'wb')
        self.writer = Json/Csv ItemExporter(self.file)
        self.writer.start_exporting()
    def process_item(self, item, spider):
        self.writer.export_item(item)
        return item
    def close_spider(self, spider):
        self.writer.finish_exporting()
        self.file.close()

              3.Redis 管道 

import redis
class AqiRedisPipeline(object):
    def open_spider(self, spider):
        # 连接redis
        self.conn = redis.StrictRedis(host='127.0.0.1', port=6379)
        # 存放的key 名
        self.save_key = 'Aqi_Redis'
    def process_item(self, item, spider):
        self.conn.lpush(self.save_key, item)
        return item

               4.Msql 管道


import pymysql
class mysqlPipeline(object):
    conn = None
    cursor = None
    def open_spider(self, spider):
        self.conn = pymysql.Connect(host='127.0.0.1', port=3306, user='root', password='', db='spider')
        print('数据库连接成功')
    def process_item(self, item, spider):
        self.cursor = self.conn.cursor()
        sql = 'insert into 糗事 values ("%s","%s") ' % (item['user'], item['content'])
        try:
            self.cursor.execute(sql)
            self.conn.commit()
        except Exception as e:
            print(e)
            self.conn.rollback()
        return item
    def close_spider(self, spider):
        self.cursor.close()
        self.conn.close()
        print('爬虫完毕')

       4.图片管道之高级用法:

from scrapy.pipelines.images import ImagesPipeline
from scrapy.http import Request
from .settings import IMAGES_STORE
import os
class ManhuaPipeline(ImagesPipeline):
    name=0
    def get_media_requests(self, item, info):
        image_url_list = item['url_list']
        for url in image_url_list:
            yield Request(url=url)

    def item_completed(self, results, item, info):
        old_paths =  [x['path'] for ok, x in results if ok]
        for path in old_paths:
            self.name+=1
            old_path=IMAGES_STORE +path
            new_path = item['name']+'/'+str(self.name) + '.jpg'
            print(new_path+'下载完成')
            try:
                os.renames(old_path, new_path)
            except Exception as e:
                print('错误!!')
        print(item['name'] + '下载完成!!')
        return item

        4.setting

            记得开启各种 管道 和中间件........

LOG_LEVEL = 'WARNING'  #ERROR
ROBOTSTXT_OBEY = False
USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'
默认16
# CONCURRENT_REQUESTS = 32

 2.特殊scrapy 

     1.处理动态网页

          可以由两个方法拦截动态网页的request     然后由process_request    process_response 返回新的 response

#spider中
from selenium import webdriver
     #在spider中先实例化 浏览器对象
    def __init__(self):
        self.br=webdriver.Chrome()

 # middlewares 中间件中
from time import sleep
from scrapy.http import HtmlResponse   
class AqiDownloaderMiddleware(object):
    # 通过判断enging 传过来的 request 对象的url 是不是动态页面的url
    # 如果是 拦截对应的response 返回新de自己构建的 response
    def process_request(self, request, spider):
        url=request.url
        if 'month=2' in url:
            br=spider.br
            br.get(url=url)
            sleep(2)
            data=br.page_source
            return HtmlResponse(url=request.url,body=data,request=request,encoding='utf-8')
        return None

      2. 处理UA池,代理池

        利用 process_request 拦截 request  在 中间件 交给下载器 之前 给请求 带上 headers 和设置代理

import random
class SpiderDownloaderMiddleware(object):
    UA_list = []
    proxy_http_list = []
    proxy_https_list = []
    def process_request(self, request, spider):
        if request.url.split(':')[0]== 'http':
            request.meta['proxy']=random.choice(self.proxy_http_list)
        else:
            request.meta['proxy']=random.choice(self.proxy_https_list)
        request.meta['headers'] = random.choice(self.UA_list)
        requet.headers['User-Agent']=random.choice(self.UA_list)
        
        return None

       3. 处理 post请求 三种方法

               1.cookie登录 

                 重写父类 start_requests 方法 在构造 request 请求起始url时带上cookies scrapy 不支持 headers 带cookie

import scrapy
class CookieSpider(scrapy.Spider):
    name = 'cookie'
    # allowed_domains = ['www.com']
    start_urls = ['http://www.renren.com/971322510']
    cookie_str = "anonymid=jxg4mooq7i6vpy;ln_uact=15614140557;................ "
    cookie = {i.split('='): i.split('=') for i in cookie_str.split(';')}
     #让cookie 转换为字典
    def start_requests(self):
        for url in self.start_urls:
            yield scrapy.Request(url, cookies=self.cookie, callback=self.parse)
    #验证 是否成功
    def parse(self, response):
        with open('renren.html', 'wb') as f:
            f.write(response.body)

                2.post 模拟登录

                 重写父类 start_requests 方法 构造 FormRequest请求起始url时带上form表单   默认是post 登录url

                  之后需要登录的所有网页即可以访问了  cookie 自动处理

import scrapy
class PostSpider(scrapy.Spider):
    name = 'post'
    start_urls = ['https://www.renren.com/ajaxLogin/login']
    def start_requests(self):
        data = {
            "email": "15614140557",
            "domain": "renren.com",
            "icode": "",
        "password": "36965a09f50b04d7e4db020b5d21384a8f475581244523435190b4ef13d8fe9a",
        }
        for url in self.start_urls:
            yield scrapy.FormRequest(url=url,formdata=data,callback=self.parse)
    def parse(self, response):

             3. scrapy 自带的  构造 FormRequest.from_response 对象 传入变化的 如 密码 用户名即可

                用xpath自动需找 form表单   表单中需要 有 action 才可以

import scrapy
class AutoSpider(scrapy.Spider):
    name = 'auto'
    start_urls = ['https://github.com/login']
    def parse(self, response):
        form_data={
            'login':'wyc-12321',
            'password':'wyc15213798476'
        }
        yield scrapy.FormRequest.from_response(
            response,
            formxpath='//*[@id="login"]/form',
            formdata=form_data,
            callback=self.parse_detail
        )
    def parse_detail(self,response):
        with open('github.html','wb') as f:
            f.write(response.body)

3.scrapy中的 crawl spider

   1.正则选择器的 rule

   2.注意   crawlspider中  不能重写parse方法  ,这个方法被用来  提取规则解析器中的url

import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider,Rule
class AqiproSpider(CrawlSpider):
    name = 'aqiPro_Crawl'
    # start_urls 默认不过滤 url dont_filter= True
    start_urls = ['https://www.aqistudy.cn/historydata/']
    rules = (
        Rule(  LinkExtractor( allow='monthdata'  )  ),
        Rule(  LinkExtractor(allow='daydata'),callback='parse_day'),
        Rule(LinkExtractor(restrict_css='#1'), follow=False),  不写callback只负责找url
        # css选择器 自动提取 标签下的 a 标签中的 href
        )
    # crawl url自动过滤
    def parse_day(self, response):
            yield item

      2.rule的其他用法

          rule(allow=(),deny=() ,restrict_xpaths() )  deny 不允许提取的url   

3.分布式爬虫 Redis spider

    1.流程

       1.运行一个redisspider 时 发生阻塞,等待主机发布任务,当redis中  有起始url 时 各个分机 开始抢任务,抢到任务的 爬虫文件             继续  提取 url 交给到 调度器,然后 去重后入队列 交给 redis 调度器 添加指纹 后出队列  再返回给 scrapy 调度器 

       2. 运行

          scrapy crawl 项目名   --->阻塞   -->向redis中   lpush redis_key  www.baidu.com          -->开始爬虫

   2.具体文件配置

         1.spider文件

import scrapy
from scrapy_redis.spiders import RedisSpider   #分布式包
class AqiproSpider(RedisSpider):               #更换继承关系
    name = 'aqiPro_redis'
    redis_key = 'redispider'                   #主机 分布第一个任务的 key名
    def parse(self, response):
        pass

           2.setting配置 

# 1.分布式的调度器
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
# 2.分布式的 过滤器
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
# 3.分布式的 断点续爬
SCHEDULER_PERSIST = True
# 4.分布式的 管道
'scrapy_redis.pipelines.RedisPipeline': 400         #普通scrapy也可以使用
# 5.连接 redis 的 ip port
REDIS_HOST = '127.0.0.1'
REDIS_PORT = 6379

 3.rediscrawlspdier

import scrapy
from scrapy.spiders import  Rule
from scrapy.linkextractors import LinkExtractor
from scrapy_redis.spiders import RedisCrawlSpider
class AqiproSpider(RedisCrawlSpider):           #更换继承父类
    name = 'aqiProRedisCrawl'
    redis_key = 'RedisCrawl'
    rules = (
        # 所有城市链接
        Rule(  LinkExtractor( allow='monthdata'  )  ),
        #所有 月链接
        Rule(  LinkExtractor(allow='daydata'),callback='parse_day'),
        )
    def parse_day(self, response):
            yield item

 4.redis 持久化存储 原理

            普通scrapy 去重原理:将请求url放入 set集合 当结束程序时集合被释放 ,下一次运行时从头开始爬取

            redisspider 运行后  redis中 存在一  指纹集合  request 请求url 集合   item字典

            1.指纹集合用来存放url的指纹结合(包括处理请求头,参数,cookie)l,越来越来多,程序结束后  继续存在redis中

            2.request集合 存放 没有请求过的url redis调度器将这些 url 出队列 交给 scrapy调度器,越来越少

           去重原理

    def request_seen(self, request):
        fp = self.request_fingerprint(request)
        # This returns the number of values added, zero if already exists.
        added = self.server.sadd(self.key, fp)
        return added == 0      #如果 指纹存在 added =0 return True  如果不存在 return False
                               #fp 就是url cookie header 指纹结合
                               # 既 添加了指纹 又做了判断

           入队列原理

    def enqueue_request(self, request):
        if not request.dont_filter and self.df.request_seen(request):
            # 要过滤为true再去判断指纹 >> 指纹存在返回True >>入队列失败     指纹不存在,返回False>>入队列 
            #不过滤 直接入队列
            self.df.log(request, self.spider)
            return False
        if self.stats:
          #不过滤  入队列   # 过滤  指纹 不存在 入队列
            self.stats.inc_value('scheduler/enqueued/redis', spider=self.spider)
        self.queue.push(request)
        return True

 

        

 

     

 

数据治理是确保数据准确性、可靠性、安全性、可用性和完整性的体系和框架。它定义了组织内部如何使用、存储、保护和共享数据的规则和流程。数据治理的重要性随着数字化转型的加速而日益凸显,它能够提高决策效率、增强业务竞争力、降低风险,并促进业务创新。有效的数据治理体系可以确保数据在采集、存储、处理、共享和保护等环节的合规性和有效性。 数据质量管理是数据治理中的关键环节,它涉及数据质量评估、数据清洗、标准化和监控。高质量的数据能够提升业务决策的准确性,优化业务流程,并挖掘潜在的商业价值。随着大数据和人工智能技术的发展,数据质量管理在确保数据准确性和可靠性方面的作用愈发重要。企业需要建立完善的数据质量管理和校验机制,并通过数据清洗和标准化提高数据质量。 数据安全与隐私保护是数据治理中的另一个重要领域。随着数据量的快速增长和互联网技术的迅速发展,数据安全与隐私保护面临前所未有的挑战。企业需要加强数据安全与隐私保护的法律法规和技术手段,采用数据加密、脱敏和备份恢复等技术手段,以及加强培训和教育,提高安全意识和技能水平。 数据流程管理与监控是确保数据质量、提高数据利用率、保护数据安全的重要环节。有效的数据流程管理可以确保数据流程的合规性和高效性,而实时监控则有助于及时发现并解决潜在问题。企业需要设计合理的数据流程架构,制定详细的数据管理流程规范,并运用数据审计和可视化技术手段进行监控。 数据资产管理是将数据视为组织的重要资产,通过有效的管理和利用,为组织带来经济价值。数据资产管理涵盖数据的整个生命周期,包括数据的创建、存储、处理、共享、使用和保护。它面临的挑战包括数据量的快速增长、数据类型的多样化和数据更新的迅速性。组织需要建立完善的数据管理体系,提高数据处理和分析能力,以应对这些挑战。同时,数据资产的分类与评估、共享与使用规范也是数据资产管理的重要组成部分,需要制定合理的标准和规范,确保数据共享的安全性和隐私保护,以及建立合理的利益分配和权益保障机制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值