使用Scrapy爬取百度圖片

最近在做畢業(yè)設(shè)計(jì),需要從網(wǎng)上下載圖片,就研究了一下怎么使用Scrapy來(lái)爬取百度圖片。任務(wù)很簡(jiǎn)單,拿到圖片的url。現(xiàn)在進(jìn)入百度圖片,默認(rèn)都是懶加載的(可以調(diào)回翻頁(yè)模式),就是往下翻頁(yè)面,當(dāng)沒(méi)有圖片時(shí)候,就會(huì)發(fā)起一個(gè)請(qǐng)求,然后返回一個(gè)響應(yīng)里面包含了即將展示圖片的url,如此循環(huán)。

1. 環(huán)境配置和儲(chǔ)備知識(shí)

我的環(huán)境是Mac OS,安裝了Anaconda,這個(gè)是真的好用沒(méi)話說(shuō),再也不用煩瑣python環(huán)境了,安裝各種需要的庫(kù)在終端輸入命令即可。關(guān)于這個(gè)可以在網(wǎng)上搜索,很有必要細(xì)入了解一下。然后就是安裝Scrapy引擎了,命令行直接conda install scrapy后即可,詳細(xì)內(nèi)容自己搜索。當(dāng)然你之前已有python環(huán)境并通過(guò)其他方法配置好scrapy就不用管這些了。
關(guān)于scrapy的相關(guān)知識(shí)可以參考官方文檔,英語(yǔ)基礎(chǔ)不好的話,網(wǎng)上也有大量博客可以參考。我就不在累述。

2. 分析百度圖片

打開(kāi)開(kāi)發(fā)者工具(我用的Chrome)后,搜索柯南,仔細(xì)觀察右邊的窗口,其中有一個(gè)返回json里面就包含了圖片的url。

image.png

把返回的json內(nèi)容復(fù)制到在線json解析工具里,看一下結(jié)構(gòu)??梢钥吹?code>data字段是一個(gè)數(shù)組,每一項(xiàng)里包含了圖片的一些信息,當(dāng)然,主要包含url即可??梢钥吹接?code>thumbURL和middleURL等,根據(jù)自己需要選一個(gè),就是圖片尺寸不同。

image.png

OK,我們已經(jīng)知道了怎么拿到圖片的url了,我們回過(guò)頭再來(lái)分析之前那個(gè)請(qǐng)求連接,向下翻網(wǎng)頁(yè),每次請(qǐng)求的時(shí)候我們復(fù)制一下連接看一下。

image.png

可以看到pn這個(gè)參數(shù)在有規(guī)律的疊加。其實(shí)你把這個(gè)連接復(fù)制到瀏覽器看一下,返回的json包含即將展示的圖片,大概30張。所以我們需要請(qǐng)求更多張圖片,就直接爬取多個(gè)連接,參數(shù)自己設(shè)置,按照這個(gè)規(guī)律來(lái)。

3. 編寫(xiě)爬蟲(chóng)

關(guān)于下載圖片和文件,Scrapy已經(jīng)幫我們做了很多的工作,以致于你只要寫(xiě)少量的代碼即可。
新建Scrapy項(xiàng)目(我就命名CrawlPictures了),然后新建spider(我就命名image了),在Items.py文件中修改自己的Item,新建一個(gè)屬性存儲(chǔ)圖片url。

class CrawlpicturesItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    IMG_URL = scrapy.Field()

接著編寫(xiě)爬蟲(chóng),為了方便爬取多個(gè)關(guān)鍵字,我在spiders目錄下新建了一個(gè)keys.json文件用來(lái)配置即將爬取的關(guān)鍵字。

image.png

下面是我的爬蟲(chóng)image的代碼,在構(gòu)造函數(shù)__init__的時(shí)候,我讓它讀取到keys.json里的關(guān)鍵字信息,然后每個(gè)關(guān)鍵字去構(gòu)建幾個(gè)請(qǐng)求(一個(gè)請(qǐng)求大概30張,前面分析的),你想下載更多的直接更改range(0, 61, 30)。然后把所有的連接存到spiderstart_urls屬性里。在parse函數(shù)里,對(duì)于每一個(gè)圖片url,新生成一個(gè)item,賦值圖片的urlitem屬性IMG_URL。剩下的事就交給引擎。

import scrapy
import json
from CrawlPictures.items import CrawlpicturesItem

class ImageSpider(scrapy.Spider):
    name = 'image'
    allowed_domains = ['image.baidu.com']

    def __init__(self):
        super(ImageSpider, self).__init__()
        with open("CrawlPictures/spiders/keys.json", 'r') as file_keys:
            keys = json.load(file_keys)
            for key in keys["keys"]:
                for pn in range(0, 61, 30):
                    url = 'http://image.baidu.com/search/acjson?tn=resultjson_com&ipn=rj&queryWord={word}&word={word}&pn={pn}'.format(word=key, pn=pn)
                    self.start_urls.append(url)

    def parse(self, response):
        images = json.loads(response.body)['data']
        for image in images:
            item = CrawlpicturesItem()
            try:
                item['IMG_URL'] = [image['middleURL']]
                yield item
            except Exception as e:
                print(e)
    

最后,我們就要配置pipeline的一些設(shè)置了,Scrapy提供了處理圖片的'pipeline'。我們只需打開(kāi)它。并設(shè)置處理圖片的一些設(shè)置。打開(kāi)settings.py文件。

#打開(kāi)image pipeline
ITEM_PIPELINES = {
    'scrapy.pipelines.images.ImagesPipeline': 1
}
#IMG_URL是在item.py文件中添加的圖片的url屬性
IMAGES_URLS_FIELD = 'IMG_URL'
#設(shè)置存放圖片的路徑
IMAGES_STORE = './filepath'

4. 執(zhí)行和結(jié)果

終端執(zhí)行命令scrapy crawl image??梢钥吹綀D片已經(jīng)爬取下來(lái)了。

image.png

5. 注意

我并沒(méi)有爬取很多圖片,然而我一直在測(cè)試,結(jié)果就被反爬取機(jī)制給限制了,爬取不到圖片了。這個(gè)需要在settings.py文件里設(shè)置一下USER_AGENT。網(wǎng)上搜一下,有很多解決辦法。
我也是看了官方文檔,并從網(wǎng)上搜尋很多博客參考(鏈接1)(鏈接2)。感謝所有為別人學(xué)習(xí)提供方便的人。以后有時(shí)間多學(xué)習(xí)Scrapy再寫(xiě)寫(xiě)文章。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容