Scrapy是一個(gè)適用爬取網(wǎng)站數(shù)據(jù)、提取結(jié)構(gòu)性數(shù)據(jù)的應(yīng)用程序框架,它可以通過(guò)定制化的修改來(lái)滿(mǎn)足不同的爬蟲(chóng)需求。
首先在終端創(chuàng)建項(xiàng)目
# win4000為項(xiàng)目名 $ scrapy startproject win4000
該命令將創(chuàng)建下述項(xiàng)目目錄。
查看項(xiàng)目目錄
進(jìn)入spiders文件夾,根據(jù)模板文件創(chuàng)建爬蟲(chóng)文件
$ cd win4000/win4000/spiders # pictures 為 爬蟲(chóng)名 $ scrapy genspider pictures "win4000.com"
1.引擎(Scrapy):核心組件,處理系統(tǒng)的數(shù)據(jù)流處理,觸發(fā)事務(wù)。
2.調(diào)度器(Scheduler):用來(lái)接受引擎發(fā)出的請(qǐng)求, 壓入隊(duì)列中, 并在引擎再次請(qǐng)求的時(shí)候返回。由URL組成的優(yōu)先隊(duì)列, 由它來(lái)決定下一個(gè)要抓取的網(wǎng)址是什么,同時(shí)去除重復(fù)的網(wǎng)址。
3.下載器(Downloader):用于下載網(wǎng)頁(yè)內(nèi)容, 并將網(wǎng)頁(yè)內(nèi)容返回給Spiders。
4.爬蟲(chóng)(Spiders):用于從特定的網(wǎng)頁(yè)中提取自己需要的信息, 并用于構(gòu)建實(shí)體(Item),也可以從中提取出鏈接,讓Scrapy繼續(xù)抓取下一個(gè)頁(yè)面
5.管道(Pipeline):負(fù)責(zé)處理Spiders從網(wǎng)頁(yè)中抽取的實(shí)體,主要的功能是持久化實(shí)體、驗(yàn)證實(shí)體的有效性、清除不需要的信息。當(dāng)頁(yè)面被Spiders解析后,將被發(fā)送到項(xiàng)目管道。
6.下載器中間件(Downloader Middlewares):位于Scrapy引擎和下載器之間的框架,主要是處理Scrapy引擎與下載器之間的請(qǐng)求及響應(yīng)。
7.爬蟲(chóng)中間件(Spider Middlewares):介于Scrapy引擎和爬蟲(chóng)之間的框架,主要工作是處理Spiders的響應(yīng)輸入和請(qǐng)求輸出。
8.調(diào)度中間件(Scheduler Middewares):介于Scrapy引擎和調(diào)度之間的中間件,從Scrapy引擎發(fā)送到調(diào)度的請(qǐng)求和響應(yīng)。
Scrapy基本爬取流程可以描述為UR2IM(URL-Request-Response-Item-More URL):
1.引擎從調(diào)度器中取出一個(gè)鏈接(URL)用于接下來(lái)的抓??;
2.引擎把URL封裝成一個(gè)請(qǐng)求(Request)傳給下載器;
3.下載器把資源下載下來(lái),并封裝成應(yīng)答包(Response);
4.爬蟲(chóng)解析Response;
5.解析出實(shí)體(Item),則交給實(shí)體管道進(jìn)行進(jìn)一步的處理;
6.解析出的是鏈接(URL),則把URL交給調(diào)度器等待抓取。
首先查看目標(biāo)頁(yè)面,可以看到包含多個(gè)主題,選取感興趣主題,本項(xiàng)目以“風(fēng)景”為例(作為練習(xí),也可以通過(guò)簡(jiǎn)單修改,來(lái)爬取所有模塊內(nèi)圖片)。
在“風(fēng)景”分類(lèi)頁(yè)面,可以看到每頁(yè)包含多個(gè)專(zhuān)題,利用開(kāi)發(fā)者工具,可以查看每個(gè)專(zhuān)題的URL,拷貝相應(yīng)XPath,利用Xpath的規(guī)律性,構(gòu)建循環(huán),用于爬取每個(gè)專(zhuān)題內(nèi)容。
# 查看不同專(zhuān)題的XPath # /html/body/div[3]/div/div[3]/div[1]/div[1]/div[2]/div/div/ul/li[1]/a # /html/body/div[3]/div/div[3]/div[1]/div[1]/div[2]/div/div/ul/li[2]/a
利用上述結(jié)果,可以看到li[index]中index為專(zhuān)題序列。因此可以構(gòu)建Xpath列表如下:
item_selector = response.xpath('/html/body/div[3]/div/div[3]/div[1]/div[1]/div[2]/div/div/ul/li/a/@href')
利用開(kāi)發(fā)者工具,可以查看下一頁(yè)的URL,拷貝相應(yīng)XPath用于爬取下一頁(yè)內(nèi)容。
# 查看“下一頁(yè)”的XPath # /html/body/div[3]/div/div[3]/div[1]/div[2]/div/a[5]
因此可以構(gòu)建如下XPath:
next_selector = response.xpath('//a[@class="next"]')
點(diǎn)擊進(jìn)入專(zhuān)題,可以看到具體圖片,通過(guò)查看圖片XPath,用于獲取圖片地址。
# 構(gòu)建圖片XPath response.xpath('/html/body/div[3]/div/div[2]/div/div[2]/div[1]/div/a/img/@src').extract_first()
可以通過(guò)標(biāo)題和圖片序列構(gòu)建圖片名。
# 利用序號(hào)XPath構(gòu)建圖片在列表中的序號(hào) index = response.xpath('/html/body/div[3]/div/div[2]/div/div[1]/div[1]/span/text()').extract_first() # 利用標(biāo)題XPath構(gòu)建圖片標(biāo)題 title = response.xpath('/html/body/div[3]/div/div[2]/div/div[1]/div[1]/h1/text()').extract_first() # 利用圖片標(biāo)題title和序號(hào)index構(gòu)建圖片名 name = title + '_' + index + '.jpg'
同時(shí)可以看到,在專(zhuān)題頁(yè)面下,包含了多張圖片,可以通過(guò)點(diǎn)擊“下一張”按鈕來(lái)獲取下一頁(yè)面URL,此處為了簡(jiǎn)化爬取過(guò)程,可以通過(guò)觀察URL規(guī)律來(lái)構(gòu)建每一圖片詳情頁(yè)的URL,來(lái)下載圖片。
# 第一張圖片詳情頁(yè)地址 # http://www.win4000.com/wallpaper_detail_45401.html # 第二張圖片詳情頁(yè)地址 # http://www.win4000.com/wallpaper_detail_45401_2.html
因此可以通過(guò)首頁(yè)地址和圖片序號(hào)來(lái)構(gòu)建每一張圖片詳情頁(yè)地址。
# 第一張圖片詳情頁(yè)地址 first_url = response.url # 圖片總數(shù) num = response.xpath('/html/body/div[3]/div/div[2]/div/div[1]/div[1]/em/text()').extract_first() num = int(num) for i in range(2,num+1): next_url = '.'.join(first_url.split('.')[:-1]) + '_' + str(i) + '.html'
定義Item字段(Items.py)
本項(xiàng)目用于下載圖片,因此可以?xún)H構(gòu)建圖片名和圖片地址字段。
# win4000/win4000/items.py import scrapy class Win4000Item(scrapy.Item): # define the fields for your item here like: # name = scrapy.Field() url = scrapy.Field() name = scrapy.Field()
編寫(xiě)爬蟲(chóng)文件(pictures.py)
代碼詳解見(jiàn)代碼注釋。
# win4000/win4000/spiders/pictures.py import scrapy from win4000.items import Win4000Item from urllib import parse import time class PicturesSpider(scrapy.Spider): name = 'pictures' allowed_domains = ['win4000.com'] start_urls = ['http://www.win4000.com/zt/fengjing.html'] start_urls = ['http://www.win4000.com/zt/fengjing.html'] # cookie用于模仿瀏覽器行為 cookie={ "t":"29b7c2a8d2bbf060dc7b9ec00e75a0c5", "r":"7957", "UM_distinctid":"178c933b40e9-08430036bca215-7e22675c-1fa400-178c933b40fa00", "CNZZDATA1279564249":"1468742421-1618282415-%7C1618282415", "XSRF-TOKEN":"eyJpdiI6Ik8rbStsK1Fwem5zR2YzS29ESlI2dmc9PSIsInZhbHVlIjoiaDl5bXp5b1VvWmdSYklWWkEwMWJBK0FaZG9OaDA1VGQ2akZ0RDNISWNDM0hnOW11Q0JTVDZFNlY4cVwvSTBjQlltUG9tMnFUcWd5MzluUVZ0NDBLZlJuRWFuaVF0U3k0XC9CU1dIUzJybkorUEJ3Y2hRZTNcL0JqdjZnWjE5SXFiNm8iLCJtYWMiOiI2OTBjOTkzMTczYWQwNzRiZWY5MWMyY2JkNTQxYjlmZDE2OWUyYmNjNDNhNGYwNDAyYzRmYTk5M2JhNjg5ZmMwIn0%3D", "win4000_session":"eyJpdiI6Inc2dFprdkdMTHZMSldlMXZ2a1cwWGc9PSIsInZhbHVlIjoiQkZHVlNYWWlET0NyWWlEb2tNS0hDSXAwZGVZV05vTmY0N0ZiaFdTa1VRZUVqWkRmNWJuNGJjNkFNa3pwMWtBcFRleCt4SUFhdDdoYnlPMGRTS0dOR0tkdmVtVDhzUWdTTTc3YXpDb0ZPMjVBVGJzM2NoZzlGa045Qnl0MzRTVUciLCJtYWMiOiI2M2VmMTEyMDkxNTIwNmJjZjViYTg4MjIwZGIxNTlmZWUyMTJlYWZhNjk5ZmM0NzgyMTA3MWE4MjljOWY3NTBiIn0%3D" } def start_requests(self): """ 重構(gòu)start_requests函數(shù),用于發(fā)送帶有cookie的請(qǐng)求,模仿瀏覽器行為 """ yield scrapy.Request('http://www.win4000.com/zt/fengjing.html', callback=self.parse, cookies=self.cookie) def parse(self,response): # 獲取下一頁(yè)的選擇器 next_selector = response.xpath('//a[@class="next"]') for url in next_selector.xpath('@href').extract(): url = parse.urljoin(response.url,url) # 暫停執(zhí)行,防止網(wǎng)頁(yè)的反爬蟲(chóng)程序 time.sleep(3) # 用于爬取下一頁(yè) yield scrapy.Request(url, cookies=self.cookie) # 用于獲取每一專(zhuān)題的選擇器 item_selector = response.xpath('/html/body/div[3]/div/div[3]/div[1]/div[1]/div[2]/div/div/ul/li/a/@href') for item_url in item_selector.extract(): item_url = parse.urljoin(response.url,item_url) #print(item_url) time.sleep(3) # 請(qǐng)求專(zhuān)題頁(yè)面,并利用回調(diào)函數(shù)callback解析專(zhuān)題頁(yè)面 yield scrapy.Request(item_url,callback=self.parse_item, cookies=self.cookie) def parse_item(self,response): """ 用于解析專(zhuān)題頁(yè)面 """ # 由于Scrapy默認(rèn)并不會(huì)爬取重復(fù)頁(yè)面, # 因此需要首先構(gòu)建首張圖片實(shí)體,然后爬取剩余圖片, # 也可以通過(guò)使用參數(shù)來(lái)取消過(guò)濾重復(fù)頁(yè)面的請(qǐng)求 # 首張圖片實(shí)體 item = Win4000Item() item['url'] = response.xpath('/html/body/div[3]/div/div[2]/div/div[2]/div[1]/div/a/img/@src').extract_first() index = response.xpath('/html/body/div[3]/div/div[2]/div/div[1]/div[1]/span/text()').extract_first() item['name'] = response.xpath('/html/body/div[3]/div/div[2]/div/div[1]/div[1]/h1/text()').extract_first() + '_' + index + '.jpg' yield item first_url = response.url num = response.xpath('/html/body/div[3]/div/div[2]/div/div[1]/div[1]/em/text()').extract_first() num = int(num) for i in range(2,num+1): next_url = '.'.join(first_url.split('.')[:-1]) + '_' + str(i) + '.html' # 請(qǐng)求其余圖片,并用回調(diào)函數(shù)self.parse_detail解析頁(yè)面 yield scrapy.Request(next_url,callback=self.parse_detail,cookies=self.cookie) def parse_detail(self,response): """ 解析圖片詳情頁(yè)面,構(gòu)建實(shí)體 """ item = Win4000Item() item['url'] = response.xpath('/html/body/div[3]/div/div[2]/div/div[2]/div[1]/div/a/img/@src').extract_first() index = response.xpath('/html/body/div[3]/div/div[2]/div/div[1]/div[1]/span/text()').extract_first() item['name'] = response.xpath('/html/body/div[3]/div/div[2]/div/div[1]/div[1]/h1/text()').extract_first() + '_' + index + '.jpg' yield item
修改配置文件settings.py
修改win4000/win4000/settings.py
中的以下項(xiàng)。
BOT_NAME = 'win4000' SPIDER_MODULES = ['win4000.spiders'] NEWSPIDER_MODULE = 'win4000.spiders' # 圖片保存文件夾 IMAGES_STORE = './result' # Crawl responsibly by identifying yourself (and your website) on the user-agent # 用于模仿瀏覽器行為 USER_AGENT = 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:87.0) Gecko/20100101 Firefox/87.0' # Obey robots.txt rules ROBOTSTXT_OBEY = False # Configure a delay for requests for the same website (default: 0) # See https://docs.scrapy.org/en/latest/topics/settings.html#download-delay # See also autothrottle settings and docs # 下載時(shí)延 DOWNLOAD_DELAY = 3 # Disable cookies (enabled by default) # 是否啟用Cookie COOKIES_ENABLED = True # Configure item pipelines # See https://docs.scrapy.org/en/latest/topics/item-pipeline.html ITEM_PIPELINES = { 'win4000.pipelines.Win4000Pipeline': 300, }
修改管道文件pipelines.py用于下載圖片
修改win4000/win4000/pipelines.py
文件。
from itemadapter import ItemAdapter from scrapy.pipelines.images import ImagesPipeline import scrapy import os from scrapy.exceptions import DropItem class Win4000Pipeline(ImagesPipeline): def get_media_requests(self, item, info): # 下載圖片,如果傳過(guò)來(lái)的是集合需要循環(huán)下載 # meta里面的數(shù)據(jù)是從spider獲取,然后通過(guò)meta傳遞給下面方法:file_path yield scrapy.Request(url=item['url'],meta={'name':item['name']}) def item_completed(self, results, item, info): # 是一個(gè)元組,第一個(gè)元素是布爾值表示是否成功 if not results[0][0]: with open('img_error_name.txt','a') as f_name: error_name = str(item['name']) f_name.write(error_name) f_name.write('\n') with open('img_error_url.txt','a') as f_url: error_url = str(item['url']) f_url.write(error_url) f_url.write('\n') raise DropItem('下載失敗') return item # 重命名,若不重寫(xiě)這函數(shù),圖片名為哈希,就是一串亂七八糟的名字 def file_path(self, request, response=None, info=None): # 接收上面meta傳遞過(guò)來(lái)的圖片名稱(chēng) filename = request.meta['name'] return filename
編寫(xiě)爬蟲(chóng)啟動(dòng)文件begin.py
在win4000
目錄下創(chuàng)建begin.py
# win4000/begin.py from scrapy import cmdline cmdline.execute('scrapy crawl pictures'.split())
進(jìn)入begin.py
所在目錄,運(yùn)行程序,啟動(dòng)scrapy進(jìn)行爬蟲(chóng)。
$ python3 begin.py
本項(xiàng)目?jī)H用于測(cè)試用途。
Enjoy coding.
到此這篇關(guān)于Python爬蟲(chóng)之教你利用Scrapy爬取圖片的文章就介紹到這了,更多相關(guān)python中用Scrapy爬取圖片內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
標(biāo)簽:中山 呼和浩特 畢節(jié) 湖州 江蘇 駐馬店 衡水 股票
巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《Python爬蟲(chóng)之教你利用Scrapy爬取圖片》,本文關(guān)鍵詞 Python,爬蟲(chóng),之教,你,利用,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問(wèn)題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。