使用scrapy爬取手機版鬥魚主播的房間圖片及昵稱
阿新 • • 發佈:2018-07-16
發現 對手 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爬取手機版鬥魚主播的房間圖片及昵稱