Python抓取花瓣網高清美圖

一:前言

嘀嘀嘀,上車請刷卡。昨天看到了不錯的圖片分享網——花瓣,裏面的圖片質量還不錯,所以利用selenium+xpath我把它的妹子的欄目下爬取了下來,以圖片欄目名稱給文件夾命名分類保存到電腦中。這個妹子主頁http://huaban.com/boards/favorite/beauty 是動態加載的,如果想獲取更多內容可以模擬下拉,這樣就可以更多的圖片資源。這種之前爬蟲中也做過,但是因爲網速不夠快所以我就抓了19個欄目,一共500多張美圖,也已經很滿意了。

先看看效果:


Paste_Image.png

Paste_Image.png

二:運行環境

  • IDE:Pycharm
  • Python3.6
  • lxml 3.7.2
  • Selenium 3.4.0
  • requests 2.12.4

三:實例分析

1.這次爬蟲我開始做的思路是:進入這個網頁http://huaban.com/boards/favorite/beauty然後來獲取所有的圖片欄目對應網址,然後進入每一個網頁中去獲取全部圖片。(如下圖所示)


Paste_Image.png

Paste_Image.png

2.但是爬取獲取的圖片分辨率是236x354,圖片質量不夠高,但是那個時候已經是晚上1點30之後了,所以第二天做了另一個版本:在這個基礎上再進入每個縮略圖對應的網頁,再抓取像下面這樣高清的圖片。


Paste_Image.png

四:實戰代碼

1.第一步導入本次爬蟲需要的模塊

__author__ = '布咯咯_rieuse'
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium import webdriver
import requests
import lxml.html
import os

2.下面是設置webdriver的種類,就是使用什麼瀏覽器進行模擬,可以使用火狐來看它模擬的過程,也可以是無頭瀏覽器PhantomJS來快速獲取資源,['--load-images=false', '--disk-cache=true']這個意思是模擬瀏覽的時候不加載圖片和緩存,這樣運行速度會加快一些。WebDriverWait標明最大等待瀏覽器加載爲10秒,set_window_size可以設置一下模擬瀏覽網頁的大小。有些網站如果大小不到位,那麼一些資源就不加載出來。

# SERVICE_ARGS = ['--load-images=false', '--disk-cache=true']
# browser = webdriver.PhantomJS(service_args=SERVICE_ARGS)
browser = webdriver.Firefox()
wait = WebDriverWait(browser, 10)
browser.set_window_size(1400, 900)

3.parser(url, param)這個函數用來解析網頁,後面有幾次都用用到這些代碼,所以直接寫一個函數會讓代碼看起來更整潔有序。函數有兩個參數:一個是網址,另一個是顯性等待代表的部分,這個可以是網頁中的某些板塊,按鈕,圖片等等...

def parser(url, param):
    browser.get(url)
    wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, param)))
    html = browser.page_source
    doc = lxml.html.fromstring(html)
    return doc

4.下面的代碼就是解析本次主頁面http://huaban.com/boards/favorite/beauty/ 然後獲取到每個欄目的網址和欄目的名稱,使用xpath來獲取欄目的網頁時,進入網頁開發者模式後,如圖所示進行操作。之後需要用欄目名稱在電腦中建立文件夾,所以在這個網頁中要獲取到欄目的名稱,這裏遇到一個問題,一些名稱不符合文件命名規則要剔除,我這裏就是一個 * 影響了。

def get_main_url():
    print('打開主頁搜尋鏈接中...')
    try:
        doc = parser('http://huaban.com/boards/favorite/beauty/', '#waterfall')
        name = doc.xpath('//*[@id="waterfall"]/div/a[1]/div[2]/h3/text()')
        u = doc.xpath('//*[@id="waterfall"]/div/a[1]/@href')
        for item, fileName in zip(u, name):
            main_url = 'http://huaban.com' + item
            print('主鏈接已找到' + main_url)
            if '*' in fileName:
                fileName = fileName.replace('*', '')
            download(main_url, fileName)
    except Exception as e:
        print(e)

Paste_Image.png

5.前面已經獲取到欄目的網頁和欄目的名稱,這裏就需要對欄目的網頁分析,進入欄目網頁後,只是一些縮略圖,我們不想要這些低分辨率的圖片,所以要再進入每個縮略圖中,解析網頁獲取到真正的高清圖片網址。這裏也有一個地方比較坑人,就是一個欄目中,不同的圖片存放dom格式不一樣,所以我這樣做

img_url = doc.xpath('//*[@id="baidu_image_holder"]/a/img/@src')
img_url2 = doc.xpath('//*[@id="baidu_image_holder"]/img/@src')

這就把兩種dom格式中的圖片地址都獲取了,然後把兩個地址list合併一下。img_url +=img_url2
在本地創建文件夾使用filename = 'image\{}\'.format(fileName) + str(i) + '.jpg'表示文件保存在與這個爬蟲代碼同級目錄image下,然後獲取的圖片保存在image中按照之前獲取的欄目名稱的文件夾中。

def download(main_url, fileName):
    print('-------準備下載中-------')
    try:
        doc = parser(main_url, '#waterfall')
        if not os.path.exists('image\\' + fileName):
            print('創建文件夾...')
            os.makedirs('image\\' + fileName)
        link = doc.xpath('//*[@id="waterfall"]/div/a/@href')
        # print(link)
        i = 0
        for item in link:
            i += 1
            minor_url = 'http://huaban.com' + item
            doc = parser(minor_url, '#pin_view_page')
            img_url = doc.xpath('//*[@id="baidu_image_holder"]/a/img/@src')
            img_url2 = doc.xpath('//*[@id="baidu_image_holder"]/img/@src')
            img_url +=img_url2
            try:
                url = 'http:' + str(img_url[0])
                print('正在下載第' + str(i) + '張圖片,地址:' + url)
                r = requests.get(url)
                filename = 'image\\{}\\'.format(fileName) + str(i) + '.jpg'
                with open(filename, 'wb') as fo:
                    fo.write(r.content)
            except Exception:
                print('出錯了!')
    except Exception:
        print('出錯啦!')


if __name__ == '__main__':
    get_main_url()

五:總結

這次爬蟲繼續練習了Selenium和xpath的使用,在網頁分析的時候也遇到很多問題,只有不斷練習才能把自己不會部分減少,當然這次爬取了500多張妹紙還是挺養眼的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章