爬蟲_小結04

一、接觸過幾種爬蟲模塊
urllib requestscss

二、robots協議是什麼?
網站有一些數據不想被爬蟲程序爬取,能夠編寫robots協議文件,明確指明哪些內容能夠爬取哪些不能夠爬取。
在Scrapy框架中在settings.py文件中使用了硬性語法對該協議進行了生效python

三、如何處理驗證碼?
使用三方的打碼平臺好比:雲打碼平臺、打碼兔,能夠用來處理驗證碼。

四、掌握幾種數據解析的方式?
re、xpath(最經常使用)、bs4(python獨有)

五、如何爬取動態加載的頁面數據?
selenium; ajax:抓包工具抓取異步發起的請求(url)

六、接觸過哪些反爬機制?如何處理?
robots協議、UA、封IP、驗證碼、動態數據加載、數據加密、token
處理:
配置不遵照robots協議、假裝User-Agent、代理IP更換、打碼平臺對驗證碼識別、
selenium處理或者使用抓包工具去抓取動態加載的AJAX請求數據包、
按照已知的各類加密方式進行解密、去前臺頁面進行token值的查找手動放入請求攜帶的參數中。

七、在Scrapy中接觸過幾種爬蟲類?
Spider、CrawlSpider(連接提取器和規則解析器)、RedisCrawlSpider、RedisSpider

八、如何實現分佈式流程?
必需要經過scrapy-redis組件來實現,能夠由RedisCrawlSpider、RedisSpider這兩種類分別實現。

9.簡述 requests模塊的做用及基本使用?
Requests 自稱 "HTTP for Humans",說明使用更簡潔方便。
Requests支持HTTP鏈接保持和鏈接池,支持使用cookie保持會話,支持文件上傳,支持自動肯定響應內容的編碼,
支持國際化的 URL 和 POST 數據自動編碼。

十、requests模塊參數,data與json參數的區別?
在經過requests.post()進行POST請求時,傳入報文的參數有兩個,一個是data,一個是json。
data與json既能夠是str類型,也能夠是dict類型。
區別:
一、無論json是str仍是dict,若是不指定headers中的content-type,默認爲application/json
二、data爲dict時,若是不指定content-type,默認爲application/x-www-form-urlencoded,至關於普通form表單提交的形式
三、data爲str時,若是不指定content-type,默認爲application/json
四、用data參數提交數據時,request.body的內容則爲a=1&b=2的這種形式,用json參數提交數據時,request.body的內容則爲'{"a": 1, "b": 2}'的這種形式

十一、簡述 beautifulsoup模塊的做用及基本使用?
和 lxml 同樣,Beautiful Soup 也是一個HTML/XML的解析器,主要的功能也是如何解析和提取 HTML/XML 數據。
lxml 只會局部遍歷,而Beautiful Soup 是基於HTML DOM的,會載入整個文檔,解析整個DOM樹,所以時間和內存開銷都會大不少,因此性能要低於lxml。

十二、簡述 seleninu模塊的做用及基本使用?
Selenium 能夠根據咱們的指令,讓瀏覽器自動加載頁面,獲取須要的數據,甚至頁面截屏,或者判斷網站上某些動做是否發生。
Selenium 本身不帶瀏覽器,不支持瀏覽器的功能,它須要與第三方瀏覽器結合在一塊兒才能使用。

1三、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) ajax

 

1四、在scrapy框架中如何設置代理(兩種方法)?redis

一.使用中間件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字段

1五、scrapy框架中如何實現大文件的下載?
利用scrapy下載大量大尺寸圖片及視頻時有時會報錯,顯示放棄重試
緣由:
這是因爲scrapy併發請求過多,默認狀況下會同時下載16個文件,而鏈接時間默認超過三分鐘就會丟失。
就是說若是三分鐘以內你的網速無法支持你同時下載完16個文件的話就會形成這個問題。
解決方法:
在settings.py中將默認併發鏈接數調小或者將timeout時間調大
CONCURRENT_REQUESTS = 2
DOWNLOAD_TIMEOUT=1800
此時併發請求被調成2, 等待時間被1800秒,通常的小視頻和圖片是沒有問題了。數據庫

1六、scrapy中如何實現限速?
自動限速:
限制爬蟲速度,對對方服務器友好些,防止被識別

在setting.py開啓相關擴展:
自動限速設定:
AUTOTHROTTLE_ENABLED = True
設定爬取速度:
DOWNLOAD_DELAY = 1 #單位爲秒json


1七、scrapy中如何實現暫定爬蟲?
1.進入到scrapy項目裏
二、在scrapy項目裏建立保存記錄信息的文件 zant/001
三、執行命令:
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文件從中止的地方開始繼續爬取。瀏覽器

 

1八、scrapy中如何進行自定製命令?服務器

【同時運行多個scrapy爬蟲的幾種方法(自定義scrapy項目命令)】
    一、建立commands目錄
        mkdir commands
    注意:commands和spiders目錄是同級的
    
    二、在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   
    三、commands命令下添加__init__.py文件
        touch __init__.py
        注意:這一步必定不能省略。

    cnblogs.commands爲命令文件目錄,crawlall爲命令名。
    4. 在settings.py中添加配置:
        COMMANDS_MODULE = 'cnblogs.commands'
    5. 運行命令scrapy crawlall
View Code

 

1九、scrapy中如何實現的記錄爬蟲的深度?
經過在settings.py中設置DEPTH_LIMIT的值能夠限制爬取深度,這個深度是與start_urls中定義url的相對值。cookie

20、scrapy中的pipelines工做原理?
pipelines文件實現了一個item pipieline類,和scrapy的item pipeline是同一個對象,
經過從settings中拿到咱們配置的REDIS_ITEMS_KEY做爲key,
把item串行化以後存入redis數據庫對應的value中(這個value能夠看出出是個list,咱們的每一個item是這個list中的一個結點),
這個pipeline把提取出的item存起來,主要是爲了方便咱們延後處理數據。併發

2一、scrapy的pipelines如何丟棄一個item對象?
//TODO

2二、簡述scrapy中爬蟲中間件和下載中間件的做用?
下載中間件:
下載中間件是處於引擎(crawler.engine)和下載器(crawler.engine.download())之間的一層組件,能夠有多個下載中間件被加載運行。
1.當引擎傳遞請求給下載器的過程當中,下載中間件能夠對請求進行處理 (例如增長http header信息,增長proxy信息等);
2.在下載器完成http請求,傳遞響應給引擎的過程當中, 下載中間件能夠對響應進行處理(例如進行gzip的解壓等)
Spider中間件(Middleware):
下載器中間件是介入到Scrapy的spider處理機制的鉤子框架,能夠添加代碼來處理髮送給 Spiders 的response及spider產生的item和request。

2三、scrapy-redis組件的做用?
實現分佈式抓取

2四、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 上,來實現的。


2五、scrapy-redis的調度器如何實現任務的深度優先和廣度優先?
//TODO


2六、假設有以下兩個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}


2七、爬取數據後使用哪一個數據庫存儲數據的,爲何?
有規則的數據能夠存入 MySQL 中,可是要注意抓取內容出現缺失的狀況
不規則的數據存儲在 MongoDB 中,直接將數據存入再進行數據清洗

相關文章
相關標籤/搜索