• 爬虫_小结04


    1、接触过几种爬虫模块
    urllib requests

    2、robots协议是什么?
    网站有一些数据不想被爬虫程序爬取,可以编写robots协议文件,明确指明哪些内容可以爬取哪些不可以爬取。
    在Scrapy框架中在settings.py文件中使用了硬性语法对该协议进行了生效

    3、如何处理验证码?
    使用三方的打码平台比如:云打码平台、打码兔,可以用来处理验证码。

    4、掌握几种数据解析的方式?
    re、xpath(最常用)、bs4(python独有)

    5、如何爬取动态加载的页面数据?
    selenium; ajax:抓包工具抓取异步发起的请求(url)

    6、接触过哪些反爬机制?如何处理?
    robots协议、UA、封IP、验证码、动态数据加载、数据加密、token
    处理:
    配置不遵守robots协议、伪装User-Agent、代理IP更换、打码平台对验证码识别、
    selenium处理或者使用抓包工具去抓取动态加载的AJAX请求数据包、
    按照已知的各种加密方式进行解密、去前台页面进行token值的查找手动放入请求携带的参数中。

    7、在Scrapy中接触过几种爬虫类?
    Spider、CrawlSpider(链接提取器和规则解析器)、RedisCrawlSpider、RedisSpider

    8、如何实现分布式流程?
    必须要通过scrapy-redis组件来实现,可以由RedisCrawlSpider、RedisSpider这两种类分别实现。

    9.简述 requests模块的作用及基本使用?
    Requests 自称 "HTTP for Humans",说明使用更简洁方便。
    Requests支持HTTP连接保持和连接池,支持使用cookie保持会话,支持文件上传,支持自动确定响应内容的编码,
    支持国际化的 URL 和 POST 数据自动编码。

    10、requests模块参数,data与json参数的区别?
    在通过requests.post()进行POST请求时,传入报文的参数有两个,一个是data,一个是json。
    data与json既可以是str类型,也可以是dict类型。
    区别:
    1、不管json是str还是dict,如果不指定headers中的content-type,默认为application/json
    2、data为dict时,如果不指定content-type,默认为application/x-www-form-urlencoded,相当于普通form表单提交的形式
    3、data为str时,如果不指定content-type,默认为application/json
    4、用data参数提交数据时,request.body的内容则为a=1&b=2的这种形式,用json参数提交数据时,request.body的内容则为'{"a": 1, "b": 2}'的这种形式

    11、简述 beautifulsoup模块的作用及基本使用?
    和 lxml 一样,Beautiful Soup 也是一个HTML/XML的解析器,主要的功能也是如何解析和提取 HTML/XML 数据。
    lxml 只会局部遍历,而Beautiful Soup 是基于HTML DOM的,会载入整个文档,解析整个DOM树,因此时间和内存开销都会大很多,所以性能要低于lxml。

    12、简述 seleninu模块的作用及基本使用?
    Selenium 可以根据我们的指令,让浏览器自动加载页面,获取需要的数据,甚至页面截屏,或者判断网站上某些动作是否发生。
    Selenium 自己不带浏览器,不支持浏览器的功能,它需要与第三方浏览器结合在一起才能使用。

    13、scrapy框架中各组件的工作流程?
    Scrapy Engine: 这是引擎,负责Spiders、ItemPipeline、Downloader、Scheduler中间的通讯,信号、数据传递等等
    Scheduler(调度器): 它负责接受引擎发送过来的requests请求,并按照一定的方式进行整理排列,入队、并等待Scrapy Engine(引擎)来请求时,交给引擎。
    Downloader(下载器):负责下载Scrapy Engine(引擎)发送的所有Requests请求,并将其获取到的Responses交还给Scrapy Engine(引擎),由引擎交给Spiders来处理
    Spiders:它负责处理所有Responses,从中分析提取数据,获取Item字段需要的数据,并将需要跟进的URL提交给引擎,再次进入Scheduler(调度器)
    Item Pipeline:它负责处理Spiders中获取到的Item,并进行处理,比如去重,持久化存储(存数据库,写入文件,总之就是保存数据用的)
    Downloader Middlewares(下载中间件):你可以当作是一个可以自定义扩展下载功能的组件
    Spider Middlewares(Spider中间件):你可以理解为是一个可以自定扩展和操作引擎和Spiders中间‘通信‘的功能组件
    (比如进入Spiders的Responses;和从Spiders出去的Requests)

    14、在scrapy框架中如何设置代理(两种方法)?

    一.使用中间件DownloaderMiddleware进行配置       
            1.在Scrapy工程下新建“middlewares.py”
            # Importing base64 library because we'll need it ONLY in case if the proxy we are going to use requires authentication
            import base64 
            # Start your middleware class
            class ProxyMiddleware(object):
                # overwrite process request
                def process_request(self, request, spider):
                    # Set the location of the proxy
                    request.meta['proxy'] = "http://YOUR_PROXY_IP:PORT"
              
                    # Use the following lines if your proxy requires authentication
                    proxy_user_pass = "USERNAME:PASSWORD"
                    # setup basic authentication for the proxy
                    encoded_user_pass = base64.encodestring(proxy_user_pass)
                    request.headers['Proxy-Authorization'] = 'Basic ' + encoded_user_pass    
                
            2.在项目配置文件里(./pythontab/settings.py)添加
            DOWNLOADER_MIDDLEWARES = {
                'scrapy.contrib.downloadermiddleware.httpproxy.HttpProxyMiddleware': 110,
                'pythontab.middlewares.ProxyMiddleware': 100,
            }           
            注意:
                1.proxy一定是要写号http://前缀
                2.如果代理有用户名密码等就需要在后面再加上一些内容
    使用中间件DownloaderMiddleware进行配置
    二.直接在爬虫程序中设置proxy字段
            可以直接在自己具体的爬虫程序中设置proxy字段,直接在构造Request里面加上meta字段即可     
            class QuotesSpider(scrapy.Spider):
                name = "quotes"
                def start_requests(self):
                    urls = [
                        'http://quotes.toscrape.com/page/1/',
                        'http://quotes.toscrape.com/page/2/',
                    ]
                    for url in urls:
                        yield scrapy.Request(url=url, callback=self.parse, meta={'proxy': 'http://proxy.yourproxy:8001'})
             
                def parse(self, response):
                    for quote in response.css('div.quote'):
                        yield {
                            'text': quote.css('span.text::text').extract_first(),
                            'author': quote.css('span small::text').extract_first(),
                            'tags': quote.css('div.tags a.tag::text').extract(),
                    }
                
            --------------
            import scrapy
    
            class ProxySpider(scrapy.Spider):
                name = 'proxy'
                allowed_domains = ["httpbin.org"]
            
                def start_requests(self):
                    url = 'http://httpbin.org/get'
                    proxy = '127.0.0.0:8000'
            
                    proxies = ""
                    if url.startswith("http://"):
                        proxies = "http://"+str(proxy)
                    elif url.startswith("https://"):
                        proxies = "https://"+str(proxy)
                    #注意这里面的meta={'proxy':proxies},一定要是proxy进行携带,其它的不行,后面的proxies一定 要是字符串,其它任何形式都不行
                    yield scrapy.Request(url, callback=self.parse,meta={'proxy':proxies})
            
                def parse(self,response):
                    print(response.text)
      
    直接在爬虫程序中设置proxy字段

    15、scrapy框架中如何实现大文件的下载?
    利用scrapy下载大量大尺寸图片及视频时有时会报错,显示放弃重试
    原因:
    这是由于scrapy并发请求过多,默认情况下会同时下载16个文件,而连接时间默认超过三分钟就会丢失。
    就是说如果三分钟之内你的网速没法支持你同时下载完16个文件的话就会造成这个问题。
    解决方法:
    在settings.py中将默认并发连接数调小或者将timeout时间调大
    CONCURRENT_REQUESTS = 2
    DOWNLOAD_TIMEOUT=1800
    此时并发请求被调成2, 等待时间被1800秒,一般的小视频和图片是没有问题了。

    16、scrapy中如何实现限速?
    自动限速:
    限制爬虫速度,对对方服务器友好些,防止被识别

    在setting.py开启相关扩展:
    自动限速设定:
    AUTOTHROTTLE_ENABLED = True
    设定爬取速度:
    DOWNLOAD_DELAY = 1 #单位为秒


    17、scrapy中如何实现暂定爬虫?
    1.进入到scrapy项目里
    2、在scrapy项目里创建保存记录信息的文件 zant/001
    3、执行命令:
    scrapy crawl 爬虫名称 -s JOBDIR=保存记录信息的路径
    如:scrapy crawl cnblogs -s JOBDIR=zant/001
    执行命令会启动指定爬虫,并且记录状态到指定目录
    爬虫已经启动,我们可以按键盘上的ctrl+c停止爬虫,停止后我们看一下记录文件夹,会多出3个文件,
    其中的requests.queue文件夹里的p0文件就是URL记录文件,这个文件存在就说明还有未完成的URL,当所有URL完成后会自动删除此文件
    当我们重新执行命令:scrapy crawl cnblogs -s JOBDIR=zant/001  时爬虫会根据p0文件从停止的地方开始继续爬取。

    18、scrapy中如何进行自定制命令?

    【同时运行多个scrapy爬虫的几种方法(自定义scrapy项目命令)】
        1、创建commands目录
            mkdir commands
        注意:commands和spiders目录是同级的
        
        2、在commands下面添加一个文件crawlall.py
        这里主要通过修改scrapy的crawl命令来完成同时执行spider的效果。
        
            from scrapy.commands import ScrapyCommand  
            from scrapy.crawler import CrawlerRunner
            from scrapy.utils.conf import arglist_to_dict
            
            class Command(ScrapyCommand):
                requires_project = True
                
                def syntax(self):  
                    return '[options]'  
                
                def short_desc(self):  
                    return 'Runs all of the spiders'  
                
                def add_options(self, parser):
                    ScrapyCommand.add_options(self, parser)
                    parser.add_option("-a", dest="spargs", action="append", default=[], metavar="NAME=VALUE",
                        help="set spider argument (may be repeated)")
                    parser.add_option("-o", "--output", metavar="FILE",
                        help="dump scraped items into FILE (use - for stdout)")
                    parser.add_option("-t", "--output-format", metavar="FORMAT",
                        help="format to use for dumping items with -o")
                
                def process_options(self, args, opts):
                    ScrapyCommand.process_options(self, args, opts)
                    try:
                        opts.spargs = arglist_to_dict(opts.spargs)
                    except ValueError:
                        raise UsageError("Invalid -a value, use -a NAME=VALUE", print_help=False)
                
                def run(self, args, opts):
                    #settings = get_project_settings()
                    spider_loader = self.crawler_process.spider_loader
                    for spidername in args or spider_loader.list():
                        print "*********cralall spidername************" + spidername
                        self.crawler_process.crawl(spidername, **opts.spargs)
                    self.crawler_process.start()
                
            self.crawler_process.spider_loader.list()方法获取项目下所有的spider,然后利用self.crawler_process.crawl运行spider   
        3、commands命令下添加__init__.py文件
            touch __init__.py
            注意:这一步一定不能省略。
    
        cnblogs.commands为命令文件目录,crawlall为命令名。
        4. 在settings.py中添加配置:
            COMMANDS_MODULE = 'cnblogs.commands'
        5. 运行命令scrapy crawlall
    View Code

    19、scrapy中如何实现的记录爬虫的深度?
    通过在settings.py中设置DEPTH_LIMIT的值可以限制爬取深度,这个深度是与start_urls中定义url的相对值。

    20、scrapy中的pipelines工作原理?
    pipelines文件实现了一个item pipieline类,和scrapy的item pipeline是同一个对象,
    通过从settings中拿到我们配置的REDIS_ITEMS_KEY作为key,
    把item串行化之后存入redis数据库对应的value中(这个value可以看出出是个list,我们的每个item是这个list中的一个结点),
    这个pipeline把提取出的item存起来,主要是为了方便我们延后处理数据。

    21、scrapy的pipelines如何丢弃一个item对象?
    //TODO

    22、简述scrapy中爬虫中间件和下载中间件的作用?
    下载中间件:
    下载中间件是处于引擎(crawler.engine)和下载器(crawler.engine.download())之间的一层组件,可以有多个下载中间件被加载运行。
    1.当引擎传递请求给下载器的过程中,下载中间件可以对请求进行处理 (例如增加http header信息,增加proxy信息等);
    2.在下载器完成http请求,传递响应给引擎的过程中, 下载中间件可以对响应进行处理(例如进行gzip的解压等)
    Spider中间件(Middleware):
    下载器中间件是介入到Scrapy的spider处理机制的钩子框架,可以添加代码来处理发送给 Spiders 的response及spider产生的item和request。

    23、scrapy-redis组件的作用?
    实现分布式抓取

    24、scrapy-redis组件中如何实现的任务的去重?
    原理:
    在分布式爬取时,会有master机器和slave机器,其中,master为核心服务器,slave为具体的爬虫服务器。
    在master服务器上搭建一个redis数据库,并将要抓取的url存放到redis数据库中,所有的slave爬虫服务器在抓取的时候从redis数据库中获取链接,
    由于scrapy_redis自身的队列机制,slave获取的url不会相互冲突,然后抓取的结果最后都存储到数据库中。
    master的redis数据库中还会将抓取过的url的指纹存储起来,用来去重。相关代码在dupefilter.py文件中的request_seen()方法中可以找到。

    去重问题:
    dupefilter.py 里面的源码:
    def request_seen(self, request):
    fp = request_fingerprint(request)
    added = self.server.sadd(self.key, fp)
    return not added
    去重是把 request 的 fingerprint 存在 redis 上,来实现的。


    25、scrapy-redis的调度器如何实现任务的深度优先和广度优先?
    //TODO


    26、假设有如下两个list:a = ['a', 'b', 'c', 'd', 'e'],b = [1, 2, 3, 4, 5],
    将 a 中的元素作为 key,b 中元素作为 value,将 a,b 合并为字典。

    a = ['a', 'b', 'c', 'd', 'e']
    b = [1, 2, 3, 4, 5]

    zip1 = zip(a,b)
    # print(zip1) #<zip object at 0x000002984CB6CCC8>
    # print(list(zip1))
    d = {}
    for i in zip1:
    d[i[0]] = i[1]
    print(d) #{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}


    27、爬取数据后使用哪个数据库存储数据的,为什么?
    有规则的数据可以存入 MySQL 中,但是要注意抓取内容出现缺失的情况
    不规则的数据存储在 MongoDB 中,直接将数据存入再进行数据清洗

  • 相关阅读:
    当框架限制了我的想法,我选择Hack
    Ubuntu下自制douban.fm播放器
    如何让基于Swing的Java程序在Linux下看起来更和谐
    基于Bootstrap的黑色极简博客园主题
    spring boot引入外部jar包
    Spring缓存注解@CachePut , @CacheEvict,@CacheConfig使用
    【转】c#如何监视文件或者文件夹的变化
    【转】一些重要的计数器
    【原创】使用timer、imagelist与notifyicon控件实现图标闪烁并避免了GDI泄漏(重点)
    【转】全角字符与半角字符的相互转换(C#)
  • 原文地址:https://www.cnblogs.com/MR-allen/p/10841432.html
Copyright © 2020-2023  润新知