引言
大家好!這一期的文章來跟大家講講如何使用 Python Scrapy 框架實現(xiàn)對網(wǎng)頁上圖片的爬取并大量下載。我們以網(wǎng)易旗下的陰陽師手游為例,給大家演示一下游戲壁紙的抓取過程。
第一步:分析網(wǎng)頁 html 結(jié)構(gòu)
首先,我們打開陰陽師手游的官網(wǎng),進入到游戲壁紙下載頁面:
將網(wǎng)頁下拉,我們還能看到更多的排成三列的壁紙圖片:
按F12打開控制臺,Shift + Ctrl + C 組合鍵開啟查看網(wǎng)頁元素的模式,然后將鼠標(biāo)移動到某一張壁紙上面,選擇一個分辨率按鈕點擊,我們可以看到相對應(yīng)的圖片標(biāo)簽:
知道了圖片url的信息,并不代表這些元素一定包含在網(wǎng)頁的靜態(tài)頁面里。為了確保我們的爬蟲能夠從網(wǎng)頁中拿到這個標(biāo)簽,我們來右鍵點擊頁面,查看網(wǎng)頁源代碼:
進入網(wǎng)頁源碼后,將頁面往下拉,我們可以看到一個個 img 標(biāo)簽以相同的形式分裝在不斷重復(fù)的 div 里面:
每一個壁紙的圖片地址,都封裝在一個 item 下的 cover 下的 mask 中,我們只需要用 CSS 選擇器或者 XPath 選擇器匹配這些標(biāo)簽就能夠順利獲取圖片地址。好,很有精神!接下來讓我們開啟一個爬蟲項目來爬取這些壁紙吧。
第二步:使用 Scrapy 框架構(gòu)建爬蟲程序
配置 setting.py
工欲善其事,必先利其器。首先我們在 settings.py 文件中配置好IMAGE相關(guān)的屬性:
[圖片上傳失敗...(image-1e4ed8-1601099802566)]
IMAGES_URLS_FIELD 定義了我們之后獲取圖片URL的字段,我們將這個字段名設(shè)置為 image_url。
IMAGE_STORE 給出了圖片保存的目錄位置,我們把爬到的圖片放在 [項目位置]/images/yys 文件夾下。
IAMGES_EXPIRES 給出了不重復(fù)爬取圖片的天數(shù),定為90天。
items.py 文件下創(chuàng)建圖片 item 類
打開 items.py 文件,新建一個類,命名為 WallpaperYYSItem。這里一定需要一個 image_url 字段,之后會通過 ImagesPipeline 對該字段中的圖片地址請求下載。
class WallpaperYYSItem(scrapy.Item):
image_url = scrapy.Field()
創(chuàng)建 Spider 文件
在你的項目目錄下,通過 scrapy genspider [crawler_name] [url] 開啟一個爬蟲文件:
scrapy genspider wallpaperYYS https://yys.163.com/media/picture.html
打開 spiders/wallpaperYYS.py,我們將 WallpaperyysSpider 類下的相關(guān)屬性改為:
[圖片上傳失敗...(image-5cd931-1601099802566)]
parse 函數(shù)書寫
接下來就是我們的重頭戲了,定義 parse 函數(shù)。這里的幾個關(guān)鍵步驟為:
-
response.css('.item .cover .mask')用CSS選擇器獲取全部包含img標(biāo)簽的節(jié)點,并對其做遍歷操作。 - 分析網(wǎng)頁源碼的時候我們會看到,一張圖片有多種分辨率,這里我們根據(jù)需求來獲取分辨率最大的那一張。由于這里的圖片是以分辨率大小升序或降序排列的,那么第一張或者最后一張有可能是分辨率最大的圖片。因此我們獲取第一張和最后一張,比較其大小,將較大的那張設(shè)為
image_url。 - 創(chuàng)建一個
wallpaper_item,給其中的image_url賦值,注意我們一定要把image_url放在一個列表里!
def parse(self, response):
_getSize = lambda x: int(x[0]) + int(x[1])
image_nodes = response.css('.item .cover .mask')
for image in image_nodes:
wallpaperF = image.css('a:nth-child(1)')
wallpaperL = image.css('a:nth-last-child(1)')
sizeF = _getSize(wallpaperF.xpath('text()').extract_first().split('x'))
sizeL = _getSize(wallpaperL.xpath('text()').extract_first().split('x'))
if sizeF > sizeL:
image_url = wallpaperF.xpath('@href').extract_first()
else:
image_url = wallpaperL.xpath('@href').extract_first()
wallpaper_item = WallpaperYYSItem()
wallpaper_item['image_url'] = [image_url]
yield wallpaper_item
創(chuàng)建自定義的 Pipeline
在 pipelines.py 文件中繼承 ImagesPipeline 創(chuàng)建一個新的 YYSImagesPipeline。這里其實什么也不需要改,使用原來有的功能就行。
class YYSImagesPipeline(ImagesPipeline):
def item_completed(self, results, item, info):
return item
最后,在 settings.py 文件中將 YYSImagesPipeline 加入 ITEM_PIPELINES:
ITEM_PIPELINES = {
'WallpaperCrawler.pipelines.WallpapercrawlerPipeline': 300,
'WallpaperCrawler.pipelines.YYSImagesPipeline': 1,
}
第三步:運行爬蟲項目
該配置的都已經(jīng)配置好了,接下來只需一行命令,就能輕易地將600多張高清壁紙收入囊中。在命令行中輸入 scrapy crawl wallpaperYYS,爬蟲就能開始爬取。
經(jīng)過不到一分鐘的時間,我們打開對應(yīng)的文件夾,就能看到600多張高清壁紙都靜靜地躺在那里啦:
全文完,作者@VelvetExodus。此篇為原創(chuàng)文章,轉(zhuǎn)載請注明出處:
Scrapy 爬取網(wǎng)站圖片與壁紙 -- 爬取網(wǎng)易陰陽師壁紙篇