動(dòng)態(tài)網(wǎng)頁爬取圖片——花瓣網(wǎng)

今天我們來爬取一個(gè)圖片網(wǎng)站花瓣網(wǎng),寫一個(gè)比較簡(jiǎn)單的圖片下載的爬蟲;

迪麗熱巴

圖片太多了,只截了這些圖片,大概幾千張;
對(duì),沒錯(cuò),就是你們喜歡的胖迪,
1、首先分析一下花瓣網(wǎng)圖片的加載方式
打開花瓣網(wǎng)首頁,搜索“迪麗熱巴”,

第一頁加載的20張圖片

下拉加載出第二頁的圖片時(shí)彈出登錄框,只有登錄賬號(hào)才可以繼續(xù)加載后面的所有圖片;


第二頁加載的20張圖片

可以看出,花瓣網(wǎng)的圖片加載是異步加載的方式,這時(shí)我們可以選擇selenium模擬登錄網(wǎng)頁模仿瀏覽器的操作不斷的下拉加載出所有的圖片;
2、主要思想:
首先要登錄賬號(hào),輸入要搜索的圖片,每次下拉加載出當(dāng)前頁面的圖片后,提取對(duì)于圖片的url存到一個(gè)列表里,由于每頁圖片是20張,所以我這里在下載圖片的時(shí)候也是每次存20個(gè)url就去下載對(duì)應(yīng)的這20張圖片;
3、準(zhǔn)備工作:
安裝selenium的庫(kù),pip或者下載到本地安裝都OK;
下面是安裝Phantomjs或者Chrome

chromedriver的安裝路徑
phantomjs的安裝路徑

具體下載可自行百度,或者參考下面的博客,這里感謝這位博主
在Windows下安裝PIP+Phantomjs+Selenium
4、下面直接上代碼

from selenium import webdriver
import time
import os
import requests


class Huaban():

    #獲取圖片url并存到列表urls_list
    def get_picture_url(self, content):
        global path
        path = "E:\spider\pictures\huaban" + '\\' + content
        # 保存圖片到磁盤文件夾 file_path中,默認(rèn)為當(dāng)前腳本運(yùn)行目錄下的文件夾
        if not os.path.exists(path):
            os.makedirs(path)
        url = "http://huaban.com"
        # 使用Chrome瀏覽器模擬打開網(wǎng)頁,但是要把下載的chromedriver.exe放在python的文件路徑下,
        # 調(diào)試好之后換成PhantomJs,速度應(yīng)該會(huì)快一點(diǎn)
        # driver = webdriver.PhantomJs()
        # 下拉滑動(dòng)瀏覽器屏幕,具體下拉多少根據(jù)自己實(shí)際情況決定
        driver = webdriver.PhantomJS()
        #driver = webdriver.Chrome()
        # 設(shè)置全屏
        driver.maximize_window()
        driver.get(url)
        time.sleep(8)

        # 點(diǎn)擊登錄、呼起登錄窗口
        driver.find_elements_by_xpath('//a[@class="login btn wbtn"]')[0].click()
        # sign in the username
        try:
            driver.find_elements_by_xpath('//input[@name="email"]')[0].send_keys('花瓣賬號(hào)')
            print('user success!')
        except:
            print('user error!')
        time.sleep(3)
        # sign in the pasword
        try:
            driver.find_elements_by_xpath('//input[@name="password"]')[0].send_keys('賬號(hào)密碼')
            print('pw success!')
        except:
            print('pw error!')
        time.sleep(3)
        # click to login
        try:
            driver.find_elements_by_xpath('//a[@class="btn btn18 rbtn"]')[0].click()
            print('click success!')
        except:
            print('click error!')
        time.sleep(3)
        #搜索圖片
        driver.find_elements_by_xpath('//input[@placeholder="搜索你喜歡的"]')[0].send_keys(content)
        driver.find_elements_by_xpath('//form[@id="search_form"]/a')[0].click()
        time.sleep(5)
        i = 0
        page = 1
        global name
        global store_path
        global urls_list
        urls_list = []
        #獲取圖片的總數(shù)
        pictures_count = driver.find_elements_by_xpath('//a[@class="selected"]/i')[0].text
        print(pictures_count)
        pages = int(int(pictures_count) / 20)
        print(pages)
        #匹配到圖片url所在的元素
        url_elements = driver.find_elements_by_xpath('//span[@class="stop"]/../img')
        #遍歷圖片元素的列表獲取圖片的url
        for url_element in url_elements:
            picture_url = url_element.get_attribute("src")[:-3] + "658"
            #防止獲取重復(fù)的圖片url
            if picture_url not in urls_list:
                urls_list.append(picture_url)
        while page <= pages:
            while len(urls_list) < 20*page:
                driver.execute_script("window.scrollBy(0,1000)")
                time.sleep(3)
                url_elements = driver.find_elements_by_xpath('//span[@class="stop"]/../img')
                for url_element in url_elements:
                    picture_url = url_element.get_attribute("src")[:-3] + "658"
                    if picture_url not in urls_list:
                        urls_list.append(picture_url)
            print("第%s頁" % page)

            for download_url in urls_list[20*(page-1):20*page]:
                i += 1
                name = content + "_" + str(i)
                store_path = name + '.jpg'
                self.store(download_url)
            page += 1
        #最后一頁
        print("第%s頁" % int(page))

        while len(urls_list) < int(pictures_count):
            driver.execute_script("window.scrollBy(0,1000)")
            time.sleep(3)
            url_elements = driver.find_elements_by_xpath('//span[@class="stop"]/../img')
            for url_element in url_elements:
                picture_url = url_element.get_attribute("src")[:-3] + "658"
                if picture_url not in urls_list:
                    urls_list.append(picture_url)
        for download_url in urls_list[20*(page-1): ]:
            i += 1
            name = content + "_" + str(i)
            store_path = name + '.jpg'
            self.store(download_url)
    #存儲(chǔ)圖片到本地
    def store(self, picture_url):
        picture = requests.get(picture_url)
        f = open(path + '\\'+ store_path, 'wb')
        f.write(picture.content)
        print('正在保存圖片:' + picture_url)
        print('文件:' + name)


if __name__ == "__main__":
    content = '迪麗熱巴'
    huaban = Huaban()
    huaban.get_picture_url(content)

下面打印的結(jié)果可以看出一共有7265張圖片


爬取結(jié)果

小結(jié):
1、對(duì)于剛開始用selenium的同學(xué)可以先選擇chromedriver,雖然這個(gè)有界面瀏覽器可能爬起來比較慢,但是可以通過報(bào)錯(cuò)或者看下瀏覽器暫停的界面判斷出是哪里的問題(比如時(shí)長(zhǎng)暫停的時(shí)間太短了,沒有加載出元素,又或者在加載中...)
2、其實(shí)這么簡(jiǎn)單的一個(gè)爬蟲,里面的坑還不少的,
比如,本地的思路是每次獲取記載的url,再遍歷下載url列表里的圖片,但是如果你是直接獲取圖片url所在的元素并存到列表里,后面再取出相應(yīng)的url下載圖片,雖然看起來回避之前的過程要簡(jiǎn)單一點(diǎn),但是再運(yùn)行到一半(大概幾百?gòu)埡?,這個(gè)具體看運(yùn)氣咯)就會(huì)報(bào)錯(cuò):

元素報(bào)錯(cuò)

selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document
大概意思是說:意思就是Element已經(jīng)過時(shí),沒有和當(dāng)前頁面進(jìn)行綁定,主要是頁面刷新或者跳轉(zhuǎn)引起的,需要重新獲取一次元素。
修改的方法:
獲取元素之后,使用元素之前要重新花去一次元素
所以這里選擇了獲取元素后直接取url存到列表就比較穩(wěn)定了;
3、這里還有一個(gè)調(diào)試比較麻煩的就是,每次下拉滑動(dòng)的距離以及每次停留的時(shí)間大小,太大或大小都有可能導(dǎo)致提前結(jié)束爬蟲;
4、這里其實(shí)還有一個(gè)思路就是:最開始的分析可以看出,每次加載出一頁(20張)圖片,就會(huì)有一個(gè)對(duì)應(yīng)的url,我們可以通過構(gòu)造這個(gè)每頁的url獲取所有的圖片,這里只是提供一個(gè)思路,有興趣的同學(xué)可以簡(jiǎn)單嘗試一下是否可行;
5、最開始爬的時(shí)候可以先選擇一些圖片總數(shù)比較少的搜索詞,這樣可以比較快的看到效果,盡快調(diào)通,然后再試一些比較多的圖片;
6、這里爬數(shù)量比較多的圖片,可能速度稍微有點(diǎn)慢,用scrapy或者多線程的可能會(huì)比較快一點(diǎn);

以上是小弟個(gè)人見解,如有錯(cuò)誤請(qǐng)麻煩指出,多謝!

最后編輯于
?著作權(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)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,323評(píng)論 25 708
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,650評(píng)論 4 61
  • 那口無名無姓的井,埋不了三爺爺?shù)幕辍?人死以后,土藏身,井埋魂,這是妻子老家的規(guī)矩。一星期前我們?cè)谡憬拥饺隣敔敳?..
    文案搖滾幫閱讀 593評(píng)論 0 2
  • 近期參加了一檔關(guān)于思維的收費(fèi)課程,系統(tǒng)探討模型化思維。所有的內(nèi)容是基于下面這句話的,思維方向決定了做事方式,做事方...
    知行菜根閱讀 530評(píng)論 0 1
  • “你在外面是不是有人?”丈夫葉風(fēng)問到。黃萍剛到家,鞋子還沒脫。家里像往常一樣飄散著酒精的味道。 “你說什么?今晚煲...
    涼風(fēng)有刃閱讀 677評(píng)論 0 0

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