<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                [TOC] ## 1. 分布式爬蟲 使用第三方庫scrapy-redis,GitHub地址:https://github.com/rmax/scrapy-redis 1. Scrapy多個spider不能共享待爬取隊列Scrapy queue, 即Scrapy本身不支持爬蟲分布式。 ### 1.1 架構 ![](https://box.kancloud.cn/977dc54d05df123c98601a5a474881b4_1534x1010.png) 結構變化是在請求隊列方面,由redis統一管理請求隊列,協調多個spider服務。redis提供數據存儲(爬取到的數據和待爬取請求URL)、指紋去重、 分布式爬蟲與scrapy框架的改變主要是下邊: 1. 有請求過來了,有spider引擎交個Scheduler,Scheduler將請求交給redis進行驗證(指紋隊列),如果該URL沒有爬取,則redis將URL放回給Scheduler 2. redis與爬蟲相關的三個隊列 "yaoq:dupefilter" :去重指紋隊列 "yaoq:items" : 存儲爬取到的數據隊列 "yaoq:requests" : 待爬取 ## 2. 實踐 * scrapy單機爬蟲時,我們主要自己編寫兩個spider類:CrawlSpider和Spider,在分布式中對應RedisCrawlSpider和RedisSpider ### 2.1 spider 1. 繼承RedisCrawlSpider 2. 沒有start_urls(在redis中給定,多個爬蟲端去隨機獲取) ~~~ pip3 install scrapy-redis ~~~ ~~~ __author__ = 'dailin' from scrapy_redis.spiders import RedisCrawlSpider from scrapy.linkextractors import LinkExtractor from scrapy.spiders import CrawlSpider, Rule from scrapyredis.items import Yaoq class YaoQ(RedisCrawlSpider): name = 'yaoq' allowed_domains = ['yaoq.net'] rules = ( # 只提取復合規則的頁面鏈接,不做分析,所以跟頁面但是沒有,follow是對網易深一層的爬取,false表示不提取連接,也不請求頁面上的連接 Rule(LinkExtractor(allow=r'www.yaoq.net/thread.*\.html'), callback='parse_item', follow=False), Rule(LinkExtractor(allow=r'www.yaoq.net/forum-95-\d+\.html'), follow=True) ) def parse_item(self, response): try: item = Yaoq() # print(response.text) author = response.xpath("//div[@class='pti']//div[@class='authi']/a[1]/text()").extract()[0] authorLocation = response.xpath("//div[@class='pti']//div[@class='authi']/a[1]/@href").extract()[0] pubDate = response.xpath("//div[@class='pti']//div[@class='authi']//em[1]/text()").extract()[0] # 提取所有文本 content = \ response.xpath("//div[@class='pcb']//div[@class='t_fsz']/table[1]//tr")[0].xpath('string(.)').extract()[0] contentData = content.replace("\r\n", "") title = response.xpath("//span[@id='thread_subject']/text()").extract()[0] print(author) print(authorLocation) print(pubDate) print(contentData) print(title) item['title'] = title item['pubDate'] = pubDate item['author'] = author item['authorLocation'] = authorLocation item['content'] = contentData item['id'] = str(uuid.uuid1()) yield item except BaseException as e: print(e) ~~~ ### 2.2 settings ~~~ # -*- coding: utf-8 -*- # 指定使用scrapy-redis的調度器 SCHEDULER = "scrapy_redis.scheduler.Scheduler" # 指定使用scrapy-redis的去重 DUPEFILTER_CLASS = 'scrapy_redis.dupefilters.RFPDupeFilter' # 指定排序爬取地址時使用的隊列, # 默認的 按優先級排序(Scrapy默認),由sorted set實現的一種非FIFO、LIFO方式。 SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.SpiderPriorityQueue' # 可選的 按先進先出排序(FIFO) # SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.SpiderQueue' # 可選的 按后進先出排序(LIFO) # SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.SpiderStack' # 在redis中保持scrapy-redis用到的各個隊列,從而允許暫停和暫停后恢復,也就是不清理redis queues、 # 中斷后可以繼續爬取 SCHEDULER_PERSIST = True # 只在使用SpiderQueue或者SpiderStack是有效的參數,指定爬蟲關閉的最大間隔時間 # SCHEDULER_IDLE_BEFORE_CLOSE = 10 # 通過配置RedisPipeline將item寫入key為 spider.name : items 的redis的list中,供后面的分布式處理item # 這個已經由 scrapy-redis 實現,不需要我們寫代碼 ITEM_PIPELINES = { 'example.pipelines.ExamplePipeline': 300, 'scrapy_redis.pipelines.RedisPipeline': 400 } # 指定redis數據庫的連接參數 # REDIS_PASS是我自己加上的redis連接密碼(默認不做) REDIS_HOST = '127.0.0.1' REDIS_PORT = 6379 #REDIS_PASS = 'redisP@ssw0rd' # LOG等級 LOG_LEVEL = 'DEBUG' #默認情況下,RFPDupeFilter只記錄第一個重復請求。將DUPEFILTER_DEBUG設置為True會記錄所有重復的請求。 DUPEFILTER_DEBUG =True ~~~ ### 2.3 運行爬蟲 #### 2.3.1 運行爬蟲 ~~~ scrapy runspider scrapyredis/spiders/YaoQ.py ~~~ > 此時爬蟲處于等待狀態(因為沒有給定start_urls) #### 2.3.2 在redis中給定start_urls 1. 此時redis中,沒有任何key ![](https://box.kancloud.cn/c2ff518b974965e7ebd03e89f323e64b_543x76.png) 2. 給定起始url(就是想隊列中放入URL,讓爬蟲去爬) >1. 這個起始的URL在redis中對應的鍵名默認是`spidername:start_urls`的組合,例如spider名稱為 > yaoqyaoq,對應的鍵名為yaoq:start_urls。 > 2. 也可以在程序中顯示的指定(start_url名稱任意,但是按照規范來較好) ~~~ lpush yaoq:start_urls 'http://www.yaoq.net/forum-95-1.html' ~~~ > 此時爬蟲開始,其他爬取到的URL也會存儲到redis中 ![](https://box.kancloud.cn/7d53c273c684893362ee2d4a39c71f49_964x140.png) > start_urls被取走,這個隊列消失,此時redis中有三個和該spider相關的隊列 ![](https://box.kancloud.cn/7d53c273c684893362ee2d4a39c71f49_964x140.png) > 1) yaoq:dupefilter:去重隊列 > 2) yaoq:items: 數據 > 3) yaoq:requests :待爬取隊列 #### 2.3.3 處理爬取到的數據 從redis讀取爬取的數據,爬取到的數據默認鍵是 spidername:items ,例如yaoq:items 把數據存儲到mysql(一直阻塞地消費yaoq:items隊列) ~~~ # coding=utf-8 __author__ = 'dailin' import json import redis import pymysql def main(): # 指定redis數據庫信息 rediscli = redis.StrictRedis(host='192.168.56.130', port=6379, db=0) # 指定mysql數據庫 mysqlcli = pymysql.connect(host='192.168.56.130', user='root', passwd='tuna', db='crawl_data', port=3306, charset="utf8", use_unicode=True) while True: # FIFO模式為 blpop,LIFO模式為 brpop,獲取鍵值 source, data = rediscli.blpop(["yaoq:items"]) item = json.loads(data) try: # 使用cursor()方法獲取操作游標 cur = mysqlcli.cursor() sql = "INSERT INTO yaoq (author, author_location, content, id, pub_date, title) VALUES (%s, %s, %s, %s, %s, %s)" # 使用execute方法執行SQL INSERT語句 content = item['content'] print(content) cur.execute(sql,(item['author'], item['authorLocation'], item['content'] ,item['id'], item['pubDate'], item['title'])) # 提交sql事務 mysqlcli.commit() # 關閉本次操作 cur.close() print("inserted %s" % item['title']) except Exception as e: print(e) if __name__ == '__main__': main() ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看