day71 Charles&scrapyd&scrapy-redis

今天講抓包工具的charles的使用;一個示例:鬥魚圖片的直播間圖片的抓取並且存放在MongoDB中;爬蟲項目的遠程部署及使用scrapy-redis模塊進行分佈式爬蟲。

Charles

  • Charles是一個Mac端用來抓取手機端數據包的工具,相當於在windows中的fidder.

使用步驟爲:
1. 下載安裝軟件
2. 綁定軟件端的端口號,默認爲8888
3. 設置mac爲熱點,手機連接到熱點上,手動保定ip和端口
4. 手機端下載證書,安裝
5. 開始使用

示例:爬取手機端鬥魚直播圖片信息

  • 爬取基本流程跟之前一樣,不一樣的地方有:
  • 存儲圖片使用ImagesPipeLine類
    • get_media_requests(self, item, info) 方法,用來獲取請求中的圖片等信息
  • 設置圖片存儲位置:在settings中設置,可以使相對路徑,也可以是絕對路徑
    • 如:相對路徑:IMAGES_STORE = ‘images/’
  • 修改文件圖片的文件名:os.rename(),注意沒有設置圖片使用默認填充圖片的情況,可以使用try預處理一下
  • 將圖片存儲到mongoDB中,使用pymongo模塊,步驟如下:
    • 鏈接mongoDB:self.client=pymongo.MongoClient(‘127.0.0.1’, 27017)
    • 創建數據庫:self.db = self.client[‘Douyu’]
    • 創建集合: self.collection = self.db[‘room’]
    • 插入數據:self.collection.insert(dict(item))

douyu.py:

# -*- coding: utf-8 -*-
import scrapy
import json
from DouYu.items import DouyuItem


class DouyuSpider(scrapy.Spider):
    name = 'douyu'
    allowed_domains = ['douyu.com']
    base_urls = 'http://capi.douyucdn.cn/api/v1/getVerticalRoom?limit=20&'
    offset = 0
    url = base_urls + str(offset)
    start_urls = [url]

    def parse(self, response):
        # 解析數據
        data_list = json.loads(response.body)['data']

        # 如果沒有數據,停止循環 遞歸
        if not data_list:
            return

        # 循環遍歷每一個字典
        for data_dict in data_list:
            item = DouyuItem()

            # 房間ID
            item['room_id'] = data_dict['room_id']
            # 頭像的大圖
            item['vertical_src'] = data_dict['vertical_src']
            # 房間的名字
            item['room_nam e'] = data_dict['room_name']
            # 暱稱
            item['nick_name'] = data_dict['nick_name']
            # 座標城市
            item['auchor_city'] = data_dict['auchor_city']

            # 解析完畢數據 --》引擎 ---》管道
            yield item

            # self.offset += 20
            # url = self.base_urls + str(self.offset)
            # yield scrapy.Request(url=url, callback=self.parse)

items.py


import scrapy


class DouyuItem(scrapy.Item):
    # 房間ID
    room_id = scrapy.Field
    # 頭像的大圖
    vertical_src = scrapy.Field
    # 房間的名字
    room_name = scrapy.Field
    # 暱稱
    nickname = scrapy.Field
    # 座標城市
    auchor_city = scrapy.Field

pipelines.py

import json
import scrapy
from scrapy.pipelines.images import ImagesPipeline
from settings import IMAGES_STORE
import os
import pymongo


# 下載 頭像的圖片
class DouyuImagePipeline(ImagesPipeline):
    # 下載圖片的方法
    def get_media_requests(self, item, info):
        # 1.圖片的的url
        image_url = item['vertical_src']

        # 2.發送圖片的請求
        yield scrapy.Request(url=image_url)

        # 3.圖片存儲路徑 --設置文件 settings.py

    # 修改圖片的名字 --》暱稱
    def item_completed(self, results, item, info):
        # 有可能列表爲空,所以判斷一下
        path = [x['path'] for ok, x in results if ok]
        if path:
            # 1.獲取老的圖片的路徑
            old_path = IMAGES_STORE + path[0]

            # 2.拼接 暱稱的 新的路徑
            new_path = IMAGES_STORE + item['nickname'] + '.jpg'

            # 3.將路徑替換 os.rename
            # 預處理原因:有主播的頭像是空的, 鬥魚給的是一樣的佔位圖
            try:
                os.rename(old_path, new_path)
            except Exception, err:
                print '圖片已經修改成功'
        return item


class DouyuPipeline(object):
    def open_spider(self, spider):
        self.file = open('douyu,json', 'w')

    def process_item(self, item, spider):
        str_item = json.dumps(dict(item)) + '\n'
        self.file.write(str_item)
        return item

    def close_spider(self, spider):
        self.file.close()


class DouyuMongoDBPipeline(object):
    def open_spider(self, spider):
        # 連接數據庫
        self.client = pymongo.MongoClient('127.0.0.1', 27017)
        self.db = self.client['Douyu']
        self.collection = self.db['room']

        # 將數據寫入數據庫
        def process_item(self, item, soider):
            self.collection.insert(dict(item))
            return item

        # 關閉客戶端
        def close_spider(self, spider):
            self.client.close()

setting.py

BOT_NAME = 'DouYu'

SPIDER_MODULES = ['DouYu.spiders']
NEWSPIDER_MODULE = 'DouYu.spiders'

# 設置圖片保存的路徑 最後的 斜槓要加
# 相對路徑
IMAGES_STORE = 'images/'

USER_AGENT = "Mozilla/5.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12A365 Safari/600.1.4"

ROBOTSTXT_OBEY = False

DOWNLOAD_DELAY = 3

ITEM_PIPELINES ={
    'Douyu.pipelines.DouyuPipeline':300,
    'Douyu.pipelines.DouyuImagePipeline':400,
    'Douyu.pipelines.DouyuMongoDBPipeline':500,
}

scrapyd遠程部署爬蟲項目

  • scrapyd是一個python的功能模塊,需要安裝服務器端和客戶端
  • 完成的功能就是,只需要一個url就可以遠程管理(開啓,關閉,查看日誌)部署到遠程服務器上的爬蟲項目,比如下班回家使用手機也可以查看公司服務器爬蟲項目的運行情況

瀏覽器輸入url後,顯示效果如下:

# scrapyd.png

使用步驟如下:

1.安裝
    1.服務端
        pip install scrapyd
    2.客戶端
        pip install scrapyd-client

    3.配置 服務端conf, bind:0.0.0.0(任意訪問)

    4.開啓服務 scrapyd
    5.配置項目中的部署文件:(以下步驟默認爲Tencent項目的tencent2爬蟲)
        修改以前:
        [deploy]
        #url = http://localhost:6800/
        project = Tencent

        修改之後:
        [deploy:scrapyd_Tencent]
        url = http://localhost:6800/
        project = Tencent

    6. 將 爬蟲的項目 部署到 服務器
        6.1千萬注意 cd 項目路徑下
        6.2 scrapyd-deploy scrapyd_Tencent -p Tencent

    7. 開啓爬蟲
    curl http://localhost:6800/schedule.json -d project=Tencent -d spider=tencent2

    8. 終止爬蟲
    curl http://localhost:6800/cancel.json -d project=Tencent -d job=a6fc833a25a111e89a80acbc329a1151

scrapy-redis分佈式爬蟲

  • 所謂分佈式,就是同一個資源庫調用若干臺機器各爬取部分數據,如100萬的數據分給5臺機器,每臺機器20萬數據,假設機器性能相同,沒有反爬情況,那麼,原來一臺機器需要5個小時的工作量,分佈式5臺機器,只需要1個小時就完成任務了。
  • scrapy本身是不能分佈式的,因爲每一個項目的調度器都是獨立的。
  • 使用scrapy-redis組件,就可以完成分佈式的功能,它是在scrapy架構的基礎上拓展了集中處理請求的功能。

scrapy-redis框架

# scrapy-redis框架.png

scrapy-redis原理

# scrapy-redis原理圖.png

四大組件:

  • Scheduler
  • Duplication Filter
  • Item Pipeline
  • Base Spider

  • 通過重寫scheduler和spider類,實現了調度、spider啓動和redis的交互

實現步驟:

  • 可參考官方案例:

    https://github.com/rolando/scrapy-redis
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章