福利向---Scrapy爬蟲爬取多級圖片網站
阿新 • • 發佈:2018-12-16
1.目標站分析
目標站網址為https://52zfl.vip/zhaifuli/list_2_1.html
每頁網址有若干連結,點選每個連結,是每部圖片資源的詳情頁面,由於圖片數量較多,涉及到翻頁操作。
通過分析頁面html程式碼,提取有用部分如下:
<article class="excerpt excerpt-one">
<header>
<h2><a target="_blank" href="/zhaifuli/2018/0509/5141.html" title="微博女神閆盼盼12月VIP大尺度套圖[60P]">微博女神閆盼盼12月VIP大尺度套圖[60P]</ a>
</h2>
</header>
</article>
用xpath程式碼可分別匹配為
- 一級頁面內所有含二級頁面名稱和連結的程式碼塊:
response.xpath('//article[@class="excerpt excerpt-one"]')
- 每個程式碼塊中的名稱:
xpath('./header/h2/a/text()').extract()[0]
- 每個程式碼塊中的連結:
'https://52zfl.vip'+xpath('./header/h2/a/@href').extract()[0]
- 每個二級頁面中圖片的連結:
<article class ="article-content">
<p>
<img alt="微博女神閆盼盼2018年3月VIP大尺度套圖" src="https://www.images.zhaofulipic.com:8819/allimg/180509/150F52E1-0.jpg">
</p>
<p>
<img alt="微博女神閆盼盼2018年3月VIP大尺度套圖" src="https://www.images.zhaofulipic.com:8819/allimg/180509/150F55936-1.jpg">
</p>
<p>
< img alt="微博女神閆盼盼2018年3月VIP大尺度套圖" src="https://www.images.zhaofulipic.com:8819/allimg/180509/150F55560-2.jpg">
</p>
<p>
<img alt="微博女神閆盼盼2018年3月VIP大尺度套圖" src="https://www.images.zhaofulipic.com:8819/allimg/180509/150F5E27-3.jpg">
</p>
</article>
- 每個二級頁面下一頁的網址格式:如本頁面為
https://52zfl.vip/zhaifuli/2018/0509/5141.html
則下一頁為https://52zfl.vip/zhaifuli/2018/0509/5141_1.html
2.建立爬蟲專案
切換至目標資料夾
scrapy startproject img
建立名為img的爬蟲專案
3.編寫爬蟲檔案
直接上原始碼,分析見註釋:
# -*- coding: utf-8 -*-
import scrapy
# 匯入item中結構化資料模板
from img.items import ImgItem
import time
class XhSpider(scrapy.Spider):
# 爬蟲名稱,唯一
name = "xh"
# 允許訪問的域
allowed_domains = ["52zfl.vip"]
# 初始URL
start_urls = ['https://52zfl.vip/zhaifuli/list_2_1.html']
def parse(self, response):
items = []
#存放當前一級頁面下所有二級頁面資訊
if response.url.startswith("https://52zfl.vip/zhaifuli/list_2_"):
# 如果圖片地址以https://52zfl.vip/zhaifuli/list_2_開頭,才取其名字及地址資訊
allPics = response.xpath('//article[@class="excerpt excerpt-one"]')
#匹配一級頁面內所有含二級頁面名稱和連結的程式碼塊
for pic in allPics:
# 分別處理每個圖片,取出名稱及地址
item = ImgItem()
name = pic.xpath('./header/h2/a/text()').extract()[0]
addr = pic.xpath('./header/h2/a/@href').extract()[0]
count = self.findpage(name)
#定義一個findpage()函式,計算當前二級頁面存在多少張圖片
items.append(item)
for page_item in items:
#取每個二級頁面資訊,分別使用parse_page()函式進行抓取圖片地址
index = 1;#當前圖片計數
while count > 0:
if index == 1:
next_url = page_item['page_url']
else:
b = page_item['page_url']
next_url = b[:b.find('.html')]+"_%s.html" % index
count -= 4
index += 1
yield scrapy.Request(url=next_url, meta={'item_1': page_item},
callback=self.parse_page)
for i in range(1, 92):
# 取得所有一級頁面網址,呼叫parse()函式,獲取二級頁面資訊
all_pages = 'https://52zfl.vip/zhaifuli/list_2_%s.html' % i
yield scrapy.Request(url=all_pages, callback=self.parse)
def parse_page(self, response):
#獲取每個二級頁面內圖片地址和其他資訊
items = response.meta['item_1']
infos = response.xpath('//article[@class="article-content"]/p/img')
print(len(infos))
current_milli_time = lambda: int(round(time.time() * 1000))
for info in infos:
item = ImgItem()
images_urls = info.xpath('@src')[0].extract()
item['pic_url'] = images_urls
item['name'] = items['name']
item['pic_name'] = str(current_milli_time())
item['list_url'] = items['list_url']
item['page_url'] = items['page_url']
print(item)
yield item
def findpage(self,name):
co = name[name.find('[') + 1:name.find(']') - 1]
if co.isdigit():
return int(co)
else:
return self.findpage(name[name.find(']')+1:])