• DAY 91 爬虫05


    1 切换frame,动作链
    2 xpath选择:在xml中查找内容的一门语言
    -.
       -..
       -/
       -//
       -@
    3 自动登录12306
    -打码平台使用:别人帮我们破解验证码
       -使用selenium点击,滑动
       -有的网站会校验是否使用了自动化测试软件:
      -window.navigator.webdriver
       -获取验证码
      -验证码图片的位置和大小
      -屏幕截图,pillow抠图
           -base64编码,存成图片,前面有标志部分
           -base64的解码和编码  
           
    4 scrapy
    -pip3 install scrapy
    -7个组件
      -爬虫:spiders文件夹下的一个个py文件,爬取的地址,解析数据
           -爬虫中间件:介于爬虫和引擎之间的
           -引擎:大总管,负责数据的流动
           -调度器:爬取地址的调度和去重
           -下载中间件
           -下载器:负责下载
           -管道:存储,数据清洗
           
      -创建项目,创建爬虫
      -scrapy startproject 名字
           -scrapy genspider 爬虫名  爬虫地址
           -scrapy crawl 爬虫名
    -目录结构
       -数据解析
      -xpath
          -拿文本:'.//a/text()'
               -拿属性:'.//a/@href'
           -css
          -拿文本:'a.link-title::text'
               -拿属性:'img.image-scale::attr(src)'
               
           -取一条;extract_first()
           -取多条:extract()

    1 setting中相关配置

    1 是否遵循爬虫协议
    ROBOTSTXT_OBEY = False

    2 请求客户端类型
    USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36'

    3 日志级别(--nolog好在,如果出错,控制台会报错)
    LOG_LEVEL='ERROR'

     

    2 持久化方案

    1 第一种方案,直接存(很少)
    -解析函数返回列表套字典
       -执行:scrapy crawl cnblogs -o 文件名(json,pkl,csv结尾)
       
    2 第二种:通用方法(pipline)
    -1 在items.py中写一个类,继承scrapy.Item
       -2 在类中写属性
      title = scrapy.Field()
       -3 在爬虫中导入类,实例化得到对象,把要保存的数据放到对象中
      item['title'] = title
       -4 修改配置文件,指定pipline,数字表示优先级,越小越大
      ITEM_PIPELINES = {
      'crawl_cnblogs.pipelines.CrawlCnblogsPipeline': 300,
    }
       -5 写一个pipline:CrawlCnblogsPipeline
      -open_spider:数据初始化,打开文件,打开数据库链接
           -process_item:真正存储的地方
          -一定不要忘了return item,交给后续的pipline继续使用
           -close_spider:销毁资源,关闭文件,关闭数据库链接

     

    3 全站爬取cnblogs文章(scrapy的请求传参)

    3.1 request和response对象传递参数

    1 在request对象中
    Request(url=url, callback=self.parse_detail,meta={'item':item})
    2 在response对象中
    item=response.meta['item']

    3.2 解析出下一页的地址并继续爬取

    next='https://www.cnblogs.com'+response.css('.pager a:last-child::attr(href)').extract_first()
    print(next)
    # yield Request(url=next,callback=self.parse)
    yield Request(url=next)

     

    4 提高爬取效率

    #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

     

    5 爬虫中间件和下载中间件

    1 爬虫和下载中间件要使用,需要在配置文件中
    SPIDER_MIDDLEWARES = {
     'crawl_cnblogs.middlewares.CrawlCnblogsSpiderMiddleware': 5,
    }
    DOWNLOADER_MIDDLEWARES = {
     'crawl_cnblogs.middlewares.CrawlCnblogsDownloaderMiddleware': 5,
    }

     

    6 加代理,加cookie,加header,加selenium

    0 在下载中间件的process_reqeust方法中
    1 加cookie
    # request.cookies['name']='lqz'
       # request.cookies= {}
    2 修改header
     # request.headers['Auth']='asdfasdfasdfasdf'
         # request.headers['USER-AGENT']='ssss'
    3 加代理
     request.meta['proxy']='http://103.130.172.34:8080'
       
       
    4 fake_useragent模块,可以随机生成user-aget
       from fake_useragent import UserAgent
           ua = UserAgent()
           print(ua.ie)   #随机打印ie浏览器任意版本
           print(ua.firefox) #随机打印firefox浏览器任意版本
           print(ua.chrome)  #随机打印chrome浏览器任意版本
           print(ua.random)  #随机打印任意厂家的浏览器
           
    5 如果process_request返回的是Request对象
    -会交给引擎,引擎把请求放到调度中,等待下次被调度
       
       
    6 集成selenium
    -在爬虫类中类属性
       driver = webdriver.Chrome(executable_path='')
       -在爬虫类中方法:
         def close(spider, reason):
           spider.driver.close()
       -在中间件中的process_reqeust中
       from scrapy.http import HtmlResponse
       spider.driver.get(url=request.url)
          response=HtmlResponse(url=request.url,body=spider.driver.page_source.encode('utf-8'),request=request)
       return response

     

    7 去重规则源码分析

    1 使用了集合去重
    2 默认使用的去重类:
    DUPEFILTER_CLASS = 'scrapy.dupefilters.RFPDupeFilter'
    3 后期你可以自己写一个类,替换掉内置的去重
    -布隆过滤器:极小内存校验是否重复
    -https://www.cnblogs.com/xiaoyuanqujing/protected/articles/11969224.html


    4 生成指纹,会把下面两种地址生成一样的指纹(本质是把?后面的参数排序,再生成指纹)
    www.baidu.com?name=lqz&age=18
    www.baidu.com?age=18&name=lqz
    #布隆过滤器
    # python中使用
    #https://www.lfd.uci.edu/~gohlke/pythonlibs/#bitarray
    pip3 install bitarray-xx.whl
    pip3 install pybloom_live


    from pybloom_live import ScalableBloomFilter
    bloom = ScalableBloomFilter(initial_capacity=100, error_rate=0.001, mode=ScalableBloomFilter.LARGE_SET_GROWTH)

    url = "www.cnblogs.com"

    url2 = "www.liuqingzheng.top"

    bloom.add(url)

    print(url in bloom)

    print(url2 in bloom)

     

    8 scrapy-redis实现分布式爬虫

    1 安装scrapy-redis
    2 在原来的基础上,爬虫类继承RedisSpider
    class CnblogsSpider(RedisSpider):
    name = 'cnblogs_redis'
    allowed_domains = ['www.cnblogs.com']
    redis_key = 'myspider:start_urls'
    3 在setting中配置
    SCHEDULER = "scrapy_redis.scheduler.Scheduler"
    DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
    # 默认就是本地6379
    #REDIS_HOST = 'localhost'
    #REDIS_PORT = 6379
    ITEM_PIPELINES = {
    'scrapy_redis.pipelines.RedisPipeline': 400
    }

    4 在多台机器上启动scrapy,向redis中插入起始爬取地址
    scrapy crawl cnblogs_redis

    redis-cli lpush myspider:start_urls https://www.cnblogs.com/
  • 相关阅读:
    面试题15:链表中倒数第K个结点
    面试题31:连续子数组的最大和
    数据库索引实例
    面试题27:二叉搜索树与双向链表
    面试题28:字符串的排列
    java比较器Comparable接口和Comaprator接口
    面向对象知识汇总
    虚函数与纯虚函数
    Linux IO实时监控iostat命令详解
    hive GroupBy操作(翻译自Hive wiki)
  • 原文地址:https://www.cnblogs.com/DEJAVU888/p/14894117.html
Copyright © 2020-2023  润新知