『Scrapy』爬取斗魚主播頭像


分析目標

爬取的是斗魚主播頭像,示范使用的URL似乎是個移動接口(下文有提到),理由是網頁主頁屬於動態頁面,爬取難度陡升,當然爬取斗魚主播頭像這么惡趣味的事也不是我的興趣......

目標URL如下,

http://capi.douyucdn.cn/api/v1/getVerticalRoom?limit=20&offset=150

這是一個json形式文件(所謂json形式的文件實際就是把字典作為字符串保存起來),limit參數表示一次加載多少條目,offset表示偏移量,即加載的第一條項目相對於初始條目的位次數。

形式如下(這不是查看源碼,而是數據本身就是這樣,好像是個移動端接口),

形式和我之前保存的json相同,是字典的格式,key有error和data,data的value是list,中間的元素是房間的信息dict,這里列舉了前兩個房間。

我們需要爬取的是主播名字('nickname')和頭像('vertical_src')。

item

import scrapy


class DouyuItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    nickname = scrapy.Field()
    imagelink = scrapy.Field()

  

spider

這里使用了json包的方法去解析str字符串為dict。

import scrapy
import json
from douyu.items import DouyuItem

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

    def parse(self, response):
        # .load和磁盤交互,.loads處理字符串
        data_list = json.loads(response.body.decode('utf-8'))['data']
        if not len(data_list):
            return

        for data in data_list:
            item = DouyuItem()
            item['nickname'] = data['nickname']
            item['imagelink'] = data['vertical_src']
            yield item

        self.offset += 20
        yield scrapy.Request(self.baseURL + str(self.offset), callback=self.parse)

  

pipelines

取消settings.py注釋,

這里面我們繼承了一個新的用於下載二進制文件的管線類,並改寫了兩個方法,用於,

  • 下載二進制文件
  • 根據下載結果(成功與否)將圖片重命名為主播名

下載文件的方法會自動讀取settings.py的字段,而且這個字段默認setting.py是沒有的,所以需要在文件中手動添加,位置無所謂,

import os
import scrapy
from scrapy.pipelines.images import ImagesPipeline
from douyu.settings import IMAGES_STORE

# 新的管線類,用於處理二進制文件
class DouyuPipeline(ImagesPipeline):

    # 二進制下載,電影視頻實際都可以,會自動調用download模組的函數
    def get_media_requests(self, item, info):
        image_link = item['imagelink']
        yield scrapy.Request(image_link)
    
    # 這個方法會在一次處理的最后調用(從返回item也可以推理出)
    # result表示下載的結果狀態
    def item_completed(self, results, item, info):
        # print(results)
        # [(True, {'url': 'https://rpic.douyucdn.cn/acrpic/170827/3034164_v1319.jpg',
        # 'checksum': '7383ee5f8dfadebf16a7f123bce4dc45', 'path': 'full/6faebfb1ae66d563476449c69258f2e0aa24000a.jpg'})]
        image_path = [x['path'] for ok,x in results if ok]
        os.rename(IMAGES_STORE + image_path[0], IMAGES_STORE + item['nickname'] + '.jpg')
        return item

重命名函數os.rename比win下的重命名強多了,它可以對路徑重命名達到修改文件位置的功效(內部原理貼近操作系統層面了,到底是os庫的函數233)。

運行如下命令,

 scrapy crawl DouyuSpider

結束即可查看圖片,結果和下面類似,

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM