zoukankan      html  css  js  c++  java
  • 爬虫~scrapy1

    1 全站爬取cnblogs

    # 1 scrapy startproject cnblogs_crawl
    # 2 scrapy genspider cnblogs www.cnblogs.com
    

    2 scarpy请求传参

    # 1 放 :yield Request(url,callback=self.parser_detail,meta={'item':item})
    # 2 取:response.meta.get('item')
    

    3 提高爬取效率

    - 在配置文件中进行相关的配置即可:(默认还有一套setting)
    #1 增加并发:
    默认scrapy开启的并发线程为32个,可以适当进行增加。在settings配置文件中修改CONCURRENT_REQUESTS = 100值为100,并发设置成了为100。
    #2 提高日志级别:
    在运行scrapy时,会有大量日志信息的输出,为了减少CPU的使用率。可以设置log输出信息为INFO或者ERROR即可。在配置文件中编写:LOG_LEVEL = ‘INFO’
    # 3 禁止cookie:
    如果不是真的需要cookie,则在scrapy爬取数据时可以禁止cookie从而减少CPU的使用率,提升爬取效率。在配置文件中编写:COOKIES_ENABLED = False
    # 4禁止重试:
    对失败的HTTP进行重新请求(重试)会减慢爬取速度,因此可以禁止重试。在配置文件中编写:RETRY_ENABLED = False
    # 5 减少下载超时:
    如果对一个非常慢的链接进行爬取,减少下载超时可以能让卡住的链接快速被放弃,从而提升效率。在配置文件中进行编写:DOWNLOAD_TIMEOUT = 10 超时时间为10s
    

    4 下载中间件

    # 2大中间件:下载中间件,爬虫中间件
    
    # 1 写在middlewares.py中(名字随便命名)
    # 2 配置生效()
    		SPIDER_MIDDLEWARES = {
       'cnblogs_crawl.middlewares.CnblogsCrawlSpiderMiddleware': 543,
    }
    	DOWNLOADER_MIDDLEWARES = {
       'cnblogs_crawl.middlewares.CnblogsCrawlDownloaderMiddleware': 543,
    }
      
    # 2 下载中间件
    	-process_request:(请求去,走)
      			# - return None: 继续处理当次请求,进入下一个中间件
            # - return Response: 当次请求结束,把Response丢给引擎处理(可以自己爬,包装成Response)
            # - return Request : 相当于把Request重新给了引擎,引擎再去做调度
            # - 抛异常:执行process_exception
      -process_response:(请求回来,走)
      		  # - return a Response object :继续处理当次Response,继续走后续的中间件
            # - return a Request object:重新给引擎做调度
            # - or raise IgnoreRequest :process_exception
      -process_exception:(出异常,走)
      		   # - return None: continue processing this exception
            # - return a Response object: stops process_exception() chain  :停止异常处理链,给引擎(给爬虫)
            # - return a Request object: stops process_exception() chain :停止异常处理链,给引擎(重新调度)
    

    5 集成selenium

    # 在爬虫已启动,就打开一个chrom浏览器,以后都用这一个浏览器来爬数据
    
    # 1 在爬虫中创建bro对象
    	bro = webdriver.Chrome(executable_path='/Users/liuqingzheng/Desktop/crawl/cnblogs_crawl/cnblogs_crawl/chromedriver')
    
    # 2 中间件中使用:
      spider.bro.get(request.url)
      text=spider.bro.page_source
      response=HtmlResponse(url=request.url,status=200,body=text.encode('utf-8'))
      return response
    # 3 关闭,在爬虫中
        def close(self, reason):
            self.bro.close()
    
    

    6 fake-useragent

    # 请求头中的user-agent
    list=['','']
    
    # pip3 install fake-useragent
    
    # https://github.com/hellysmile/fake-useragent
    from fake_useragent import UserAgent
    ua=UserAgent(verify_ssl=False)
    print(ua.random)
    

    7 去重源码分析

    # 去重源码分析
    # from scrapy.core.scheduler import Scheduler
    # Scheduler下:def enqueue_request(self, request)方法判断是否去重
    	if not request.dont_filter and self.df.request_seen(request):
       	Requests对象,RFPDupeFilter对象
    # 如果要自己写一个去重类
    	-写一个类,继承BaseDupeFilter类
      -重写def request_seen(self, request):
      -在setting中配置:DUPEFILTER_CLASS = '项目名.dup.UrlFilter'
    
    # scrapy起始爬取的地址
        def start_requests(self):
            for url in self.start_urls:
                yield Request(url)
              
              
              
              
    -增量爬取(100链接,150个链接)
      -已经爬过的,放到某个位置(mysql,redis中:集合)
      -如果用默认的,爬过的地址,放在内存中,只要项目一重启,就没了,它也不知道我爬过那个了,所以要自己重写去重方案
    -你写的去重方案,占得内存空间更小
    	-bitmap方案
    	-BloomFilter布隆过滤器
      
      
      
    from scrapy.http import Request
    from scrapy.utils.request import request_fingerprint
    
    # 这种网址是一个
    requests1=Request(url='https://www.baidu.com?name=lqz&age=19')
    requests2=Request(url='https://www.baidu.com?age=18&name=lqz')
    
    ret1=request_fingerprint(requests1)
    ret2=request_fingerprint(requests2)
    print(ret1)
    print(ret2)
    
    
    
    # bitmap去重  一个小格表示一个连接地址 32个连接,一个比特位来存一个地址
    # https://www.baidu.com?age=18&name=lqz ---》44
    # https://www.baidu.com?age=19&name=lqz ---》89
    # c2c73dfccf73bf175b903c82b06a31bc7831b545假设它占4个bytes,4*8=32个比特位
    # 存一个地址,占32个比特位
    # 10个地址,占320个比特位
    #计算机计量单位
    # 比特位:只能存0和1
    # 8个比特位是一个bytes
    # 1024bytes=1kb
    # 1024kb=1m
    # 1024m=1g
    
    # 布隆过滤器:原理和python中如何使用
        def request_seen(self, request):
            # 把request对象传入request_fingerprint得到一个值:aefasdfeasd
            # 把request对象,唯一生成一个字符串
            fp = self.request_fingerprint(request)
            #判断fp,是否在集合中,在集合中,表示已经爬过,return True,他就不会再爬了
            if fp in self.fingerprints:
                return True
            # 如果不在集合中,放到集合中
            self.fingerprints.add(fp)
            if self.file:
                self.file.write(fp + os.linesep)
    

    8 分布式爬虫

    # 1 安装pip3 install scrapy-redis
    
    # 源码部分,不到1000行,
        
    # 1 原来的爬虫继承
    from scrapy_redis.spiders import RedisSpider
    class CnblogsSpider(RedisSpider):
      	#start_urls = ['http://www.cnblogs.com/']
        redis_key = 'myspider:start_urls'
        
    # 2 在setting中配置
      SCHEDULER = "scrapy_redis.scheduler.Scheduler"
      DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
      ITEM_PIPELINES = {
         'scrapy_redis.pipelines.RedisPipeline': 300
      }
    # 3 多台机器上启动scrapy
    # 4 向reids中发送起始url
    lpush myspider:start_urls https://www.cnblogs.com
    
    
    

    补充

    # 编译型语言和解释型语言
    # python,js,php 解释型: 一定要有个解释器 (全都夸平台,在不同平台装不通平台的解释器即可)
    # 编译型语言:c,c++   java(有人说是编译型,有人说是解释型)
    	-java:jdk,jre,jvm(三个分别是啥)
      	-jdk:java开发环境(开发人员要装)
        -jre:java运行环境(要运行java程序,必须装)
        -jvm:java虚拟机,所有的java程序必须运行在虚拟机之上
        -java对外发布:跨平台,一处编码,处处运行(1990年)
        -java编译----》字节码文件(.class文件)----》字节码文件在jvm上运行---》在不同平台装不通java虚拟---》实现了跨平台
        -java:1.5---》古老   1.6 1.7 ---》java 8(用的还比较多)---》java9 ---》java13
        
      -c语言:写完了,想在windwos下运行----》跑到windows机器下编译成可执行文件
      					   -想在linux下运行----》跑到linux机器下编译成可执行文件
       			-linux上装python环境(源码安装,make,make install)
      -go编译型:跨平台编译(在windows上可以编译出linux下可执行文件)---》2009年--》微服务
      	-所有代码都编译成一个可执行文件(web项目---》编译之后---》可执行文件---》丢到服务器就能执行,不需要安装任何依赖)
    	-java要运行---》最低最低要跑在java虚拟机之上(光jvm要跑起来,就占好几百m内存)---》
    	-安卓手机app--java开发的---》你的安卓手机在上面跑了个jvm
      
      -go:就是个可执行文件(go的性能比java高,他俩不相上下),阿里:自己写了jvm
      -安卓:谷歌,---->当时那个年代,java程序员多---》java可以快速转过去---》
      -谷歌:Kotlin:---》用来取代java---》写安卓---》在国际上排名比go高
      -同年ios/mac软件:object-c-----》swift(苹果的一个工程师,没事的时候,写的一个语言)---》过了没几年,跳槽去了facebook----》
      
      -java:sun公司出的,后来被甲骨文收购了,开始恶心人---》把java做成收费---》一门收费
      -c#:微软的:一开始收费,比java要好,没人用,免费,开源了,也没人用
      
      -java se  java ee  java me
      
      -python写的代码,用打包工具,打包成exe----》把代码和解释器统统打包到exe中了
      -垃圾回收机制:挺高端
      
    
    

    1 全站爬取cnblogs,做成分布式爬虫

    # 1 代码发布系统 +cmdb+监控+日志---》devops平台、自动化运维平台
    # 2 go挺高级(并发)前端,mysql,redis,mongodb,es    缺了个go的web框架,orm
    	-beego:中国人写的(跟django很像。orm,中间件。。。。。)https://beego.me/docs/intro/
      -gin:老外写的(flask,没有orm ),gorm   https://github.com/gin-gonic/gin
      -Iris:
    
    
  • 相关阅读:
    verilog编码规范
    verilog代码 想法验证---与寄存器输出有关
    MMCM与PLL
    Vivado约束文件(XDC)的探究(2)
    Vivado约束文件(XDC)的探究(1)
    VGA图像显示组成模块分析
    关于Quad PLL /CPLL参考时钟的选择
    GTX的生成(包括COMMON)
    SD-SDI播出系统---使用GTX TX产生恢复时钟
    DRP端口描述
  • 原文地址:https://www.cnblogs.com/bs2019/p/13021873.html
Copyright © 2011-2022 走看看