1. 程式人生 > >使用scrapy爬取手機版鬥魚主播的房間圖片及昵稱

使用scrapy爬取手機版鬥魚主播的房間圖片及昵稱

發現 對手 std pipeline obj ted += 指定 foo

目的:通過fiddler在電腦上對手機版鬥魚主播進行抓包,爬取所有主播的昵稱和圖片鏈接

關於使用fiddler抓取手機包的設置:

把手機和裝有fiddler的電腦處在同一個網段(同一個wifi),手機連接好wifi後,點擊手機wifi的連接,把代理改為手動,主機地址設置為fiddler所在的電腦ip,端口號為8888(fiddler默認使用的端口號),就可以對手機進行抓包

1 創建爬蟲項目douyumeinv

scrapy startproject douyumeinv

2 設置items.py文件,對要爬取數據設置字段名字及類型進行保存

# -*- coding: utf-8 -*-

# Define here the models for your scraped items
#
# See documentation in:
# https://doc.scrapy.org/en/latest/topics/items.html

import scrapy



class DouyumeinvItem(scrapy.Item):
  
    # 主播昵稱
    nickname = scrapy.Field()
    # 主播房間的圖片鏈接
    roomSrc = scrapy.Field()
    # 照片在本地保存的位置
    imagesPath = scrapy.Field()

3 在spiders文件夾內創建爬蟲文件douyuspider.py,代碼如下

# -*- coding: utf-8 -*-
import scrapy
from douyumeinv.items import DouyumeinvItem
import json


class DouyuSpider(scrapy.Spider):

    # 爬蟲名字,終端執行命令時使用。如scrapy crawl douyu
    name = ‘douyu‘
    # 指定爬取的域範圍
    allowed_domains = [‘douyu.com‘]
    # 要爬取的頁碼
    num = 1
    # 主播個數
    n = 0
    # 實際有主播的頁碼
    pageCount = 0

    url = ‘https://m.douyu.com/api/room/mixList?page=‘ + str(num) + ‘&type=qmxx‘
    # 爬取的url列表
    start_urls = [url]

    def parse(self, response):
        ‘‘‘解析函數‘‘‘

        # 把獲取的json數據轉換為python字典
        data = json.loads(response.text)[‘data‘]
        # 獲取實際具有主播的頁碼
        self.pageCount = int(data[‘pageCount‘])
        for each in data[‘list‘]:
            self.n += 1
            item = DouyumeinvItem()
            # 主播房間圖片鏈接
            item[‘roomSrc‘] = each[‘roomSrc‘].encode(‘utf-8‘)
            # 主播昵稱
            item[‘nickname‘] = each[‘nickname‘].encode(‘utf-8‘)
            # print(item)
            # 返回數據給管道
            yield item

    # 重新發送請求    
    self.num += 1
    # 只對有主播的頁碼,進行發送請求
    if self.num <= self.pageCount:
        self.url = ‘https://m.douyu.com/api/room/mixList?page=‘ + str(self.num) + ‘&type=qmxx‘
        yield scrapy.Request(self.url, callback=self.parse)
    print ‘\n已爬完第%d頁,共%d頁,共爬取%d個主播\n‘%(self.num - 1,self.pageCount,self.n)


4 設置pipelines.py管道文件,利用images.ImagesPipeline類來請求圖片鏈接並處理下載好的圖片

# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don‘t forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html


# class DouyumeinvPipeline(object):
    # def process_item(self, item, spider):
    #     return item
import scrapy
from scrapy.pipelines import images
from scrapy.utils.project import get_project_settings
import os

class DouyumeinvPipeline(object):
    def process_item(self, item, spider):
        return item

class ImagesPipeline(images.ImagesPipeline):

    images_store = get_project_settings().get(‘IMAGES_STORE‘)
    # count用來統計實際下載並改名成功的圖片個數
    count = 0

    def get_media_requests(self, item, info):
        ‘‘‘
        get_media_requests的作用就是為每一個圖片鏈接生成一個Request對象,這個方法的輸出將作為item_completed的輸入中的results

        ‘‘‘

        # return [Request(x) for x in item.get(self.images_urls_field, [])]
        image_url = item[‘roomSrc‘]
        # print(‘=‘*60)
        # print(image_url)
        # print(item[‘nickname‘])
        # print(‘=‘*60)
        
        yield scrapy.Request(image_url)

    def item_completed(self, results, item, info):
      
        # results是一個元組,每個元組包括(success, imageinfoorfailure)。
        # 如果success=true,imageinfoor_failure是一個字典,包括url/path/checksum三個key。

      

        image_path = [x["path"] for ok,x in results if ok]
        # print(‘*‘*60)
        # 由於yield的原因,image_path的值為每次輸出一個列表[‘full/0c1c1f78e7084f5e3b07fd1b0a066c6c49dd30e0.jpg‘]
        # print(image_path[0])
        # print(item[‘nickname‘])
        # print(‘*‘*60)

        # 此處發現,不用再創建相應的文件夾,直接使用下面的字符串拼接,就可以生成一個文件夾
        old_file = self.images_store + ‘/‘ + image_path[0]
        new_file = self.images_store + ‘/full/‘ + item[‘nickname‘] + ‘.jpg‘
        # print(‘\n‘  + ‘-‘*60)
        # print(old_file)
        # print(new_file)
        # print(‘\n‘)
        # print(os.path.exists(old_file))
        # 判斷該文件及路徑是否存在
        
        # 如果圖片下載成功,則計數加1
        if os.path.exists(old_file):
            self.count += 1
        # print(‘\n‘)
        # print(‘-‘*60 + ‘\n‘)
        os.rename(old_file,new_file)
        item[‘imagesPath‘] = self.images_store + ‘/full/‘ + item[‘nickname‘]
        # print(os.listdir(‘/home/cc/pachong/2-scrapy框架/01.scrapy框架與Spider類/douyumeinv/douyumeinv/images/full/‘))
        print(‘#‘*60)
        print(‘已成功下載%d張圖片‘%(self.count))
        print(‘#‘*60)
        return item

5 設置settings.py文件
技術分享圖片

6 測試結果如下:
技術分享圖片

技術分享圖片

技術分享圖片

使用scrapy爬取手機版鬥魚主播的房間圖片及昵稱