1. 程式人生 > >用python爬蟲爬取網頁桌布圖片(彼岸桌面網唯美圖片)

用python爬蟲爬取網頁桌布圖片(彼岸桌面網唯美圖片)

今天想給我的電腦裡面多加點桌布,但是嫌棄一個個儲存太慢,於是想著寫個爬蟲直接批量爬取,因為爬蟲只是很久之前學過一些,很多基礎語句都不記得了,於是直接在網上找了個有基礎操作語句的爬蟲程式碼,在這上面進行修改以適應我的要求和爬取的網頁需求

注意:這次爬取的網頁的圖片是靜態的,沒有爬取js,而且之前爬蟲就學了一點也沒很深入,所以程式碼寫的很醜,而且因為寫這個主要是為了給電腦爬個桌布,所以側重功能,一些地方能簡單解決的就簡單解決了,在此建議想好好學習爬蟲的還是多多鑽研,不要取巧

下面程式碼來自上面的參考文章:

import requests
from bs4 import BeautifulSoup
import
os def getHtmlurl(url): #獲取網址 try: r=requests.get(url) r.raise_for_status() r.encoding=r.apparent_encoding return r.text except: return "" def getpic(html): #獲取圖片地址並下載 soup =BeautifulSoup(html,'html.parser') all_img=soup.find('ul',class_='pli'
)find_all('img') for img in all_img: src=img['src'] img_url=src print (img_url) root='D:/pic/' path = root + img_url.split('/')[-1] try: #建立或判斷路徑圖片是否存在並下載 if not os.path.exists(root): os.mkdir(root) if
not os.path.exists(path): r = requests.get(img_url) with open(path, 'wb') as f: f.write(r.content) f.close() print("檔案儲存成功") else: print("檔案已存在") except: print("爬取失敗") def main(): url='http://www.ivsky.com/bizhi/yourname_v39947/' html=(getHtmlurl(url)) print(getpic(html)) main()

這上面的程式碼中有基本的網頁資訊獲取,圖片下載操作,我們主要工作就是依據網頁原始碼資訊以及自己的個人要求編寫爬取網頁圖片的程式碼。

首先點開網站,按F12觀察原始碼資訊:
這裡寫圖片描述
定位頁面中一個圖片,可以看到它的在網頁原始碼中的位置,然後我們往上面拉,看它的的路徑:
這裡寫圖片描述
需要注意一點,這個網頁中每頁圖片中都有個我們並不需要的:
這裡寫圖片描述
它點開之後是另一個展示一組圖片的頁面,所以我們要排除它的干擾:

soup =BeautifulSoup(html,'html.parser')
all_img=soup.find('div',class_='list').find('ul').find_all("a",attrs={'href':re.compile('^((?!http).)*$'),'target':'_blank'})

這裡用了BeautifulSoup庫,通過find_all()方法的標籤屬性篩選。我們對比上面兩種圖片連結原始碼的不同,可以看到我們需要的圖片的a標籤的href屬性的值裡面是沒有http的,但是干擾圖片中有,所以我們用一個正則來篩選href標籤值中不含有http的並且target屬性的值為_blank的a標籤,得到的是這一頁中包含我們需要連結的所有a標籤資訊的列表。不知道你有沒有注意到,img標籤中的連結看上去才是能滿足我們需求的,而a標籤中的連結資訊還不完整,我們為什麼要提取它後面會說到

用for語句提取每一條資訊:

for img in all_img:

       title=img['title']
       if title.find(u"女") != -1:
        print("不符合要求,跳過")
        continue

上面是提取每個圖片的名字,並對其進行篩選。因為我並不想要人物圖片,經過觀察,發現大多人物圖片名稱都包含“女”字,於是以此來進行篩選。這裡可以用正則表示式,能進行更多樣更細緻的篩選。另外,這段語句我是放在整個迴圈的最前面,但是按照程式碼的邏輯性以及美觀性是不應該放在這裡的,具體原因我後面會說到。
這裡回顧之前我們為什麼要提取一個非圖片下載連結的問題,原因就是別忘了我們是要把圖片下載下來作為桌布使用的,這就對圖片的解析度有要求。我們把滑鼠放在圖片對應的href上,顯示的解析度是很低的。這就是網頁展示高解析度圖片使用的一種方法,套圖,以此使頁面瀏覽更快速更省流,我們為了爬取更高解析度的圖片,還需後面的操作。
我們點選此圖片,會出來一個新頁面,頁面的連結如下:
這裡寫圖片描述
仔細觀察,會發現新的連結就是在網站連結之後加上了我們之前在a標籤的href屬性中提取的值
然後看頁面原始碼,定點陣圖片:
這裡寫圖片描述
然而現在我們依舊不可以直接獲取下載連結。我們可以看到a標籤的href屬性的值類似於我們在之前頁面看到的值,說明後面還有更大解析度的圖片,現在圖片的解析度雖然說勉強能用,但是既然要爬,我們乾脆就爬個解析度最大的。於是和之前一樣,再次點選新圖片,又出來一個新的頁面,連結圖片我就不放了,依然和之前一樣是網站連結加上href中的值。
我們這時候定位新頁面上的圖片原始碼:
這裡寫圖片描述
好啦,現在我們就可以直接獲取圖片a標籤中的連結資訊進行下載了。
我們之前的兩次跳轉大致操作是類似的,我們可以將這些語句寫入到新方法中:

def getimgurl(img):
    href=img['href']
    url="http://www.netbian.com"+href
    #print(url)
    htm=getHtmlurl(url)
    soup=BeautifulSoup(htm,'html.parser')
    return soup

注意兩次對頁面資訊處理後的soup資訊中圖片連結提取的操作是不同的,這個要寫在新方法外面:

soup1=getimgurl(img)
im1=soup1.find('div',id='main').find('div',class_='endpage').find('div',class_='pic').find('p').find('a')
soup2=getimgurl(im1)
im2=soup2.find('div',id='main').find('table').find('a')

提取連結:

       img_url = im2['href']
       print (img_url)

這裡就是我們最終的連結,輸出連結,便於之後的對於各個圖片爬取狀態的定位。然後回想開頭那次按圖片名稱進行的篩選,我當時說放在裡對程式碼的邏輯性和美觀性有影響就是這個。按理說應該要輸出每個圖片的連結之後,在輸出對應的爬取狀態,但是因為爬取圖片連結我們需要多次處理,這個需要時間,如果將篩選放在爬取連結之後,會很浪費時間,大家可以嘗試一下兩者在爬取多個圖片的時間差距,因為我重點主要放在程式碼的功能而不是程式碼本身,所以我將篩選放在了最前面,篩選不通過這個圖片直接跳過,節省時間。
單純為了學習的,如果有篩選資訊,可以放在連結之後,這樣輸出資訊會看的很舒服。如果覺得時間太長,可以考慮多執行緒爬取。
然後就是自定義圖片名字和路徑。圖片名字我們之前已經提取出來儲存在title裡面,網頁上的圖片有些名字中有空格,有些有逗號,我覺得這樣看起來不太舒服,就將空格和逗號都替換掉了:

       root='/home/suwex/test2/'
       title=title.replace(',','|')
       title=title.replace(' ','|')
       path = root + title

之後圖片的下載操作就是如參考程式碼一樣。
這一切結束之後,可以發現我們只爬取了一頁圖片,這當然不是我們所需要的。

前方取巧警告!

回去觀察最開始的網頁的跳轉頁數後的連結資訊變化,發現只需要在頁面連結的index_後面加上對應的數字就行了,於是,我們在主函式中加上一個迴圈,迴圈鍵入連結資訊:

for i in range(1,10):
      if i==1:
        url='http://www.netbian.com/weimei/index.htm'
      else:
        url='http://www.netbian.com/weimei/index_' + str(i) +'.htm'
      html=(getHtmlurl(url))
      print(str(i)+" : ")
      print(getpic(html))

if判斷是因為第一頁的index後面沒有數字,所以要單獨拿出來操作一下。輸出i值,是為了讓輸出資訊更為明晰,也便於在爬取失敗後找到對應圖片查詢失敗原因。

這種頁面跳轉方式我是非常不推薦大家使用的,一般寫爬蟲的時候我們需要的是自動跳轉,自動爬取下一步的連結。一種方式就是通過定位網頁中下一頁按鈕的原始碼進行跳轉:
這裡寫圖片描述
最後,一切順利的話完成桌布爬取,我們可能會發現在爬取過程中有圖片爬取失敗了,找到這個圖片,我們發現這個圖片的最大分辨度是需要會員才能下載的,而我們連登陸都沒有。我是直接放棄掉這幾個圖片的,不過會員不說,這裡面涉及到的登入功能也是在大部分爬蟲編寫過程中不可或缺的,這也是很重要的大家要好好學習鑽研。
很多東西我這個簡單的爬蟲程式碼裡面都沒有寫到,這只是個最基本的最簡單的,而且寫的不太規範。主要側重在功能上了。大家編寫自己的爬蟲的時候可以試著把cookie資訊加上,還有一些網站的登入之類的。

以上,大家看下來的話應該有點發現了,寫爬蟲基本的語句技巧掌握是一方面,更不可或缺的是對你想爬取的頁面的原始碼的分析,爬蟲沒有通用的,每個爬蟲都是對相應頁面和功能的量身定製,網上的各種程式碼雖好但不是你需要的,學習爬蟲時,語句不熟練的話,也不要像我一樣直接找個模板修改,可以比照著編寫,慢慢就熟練了。

最後附上完整原始碼:

import requests
from bs4 import BeautifulSoup
import os
import re

def getHtmlurl(url):         #獲取網址
    try:
       r=requests.get(url)
       r.raise_for_status()
       r.encoding=r.apparent_encoding
       return r.text
    except:
        return ""

def getimgurl(img):
    href=img['href']
    url="http://www.netbian.com"+href
    #print(url)
    htm=getHtmlurl(url)
    soup=BeautifulSoup(htm,'html.parser')
    return soup

def getpic(html): #獲取圖片地址並下載
    soup =BeautifulSoup(html,'html.parser')
    all_img=soup.find('div',class_='list').find('ul').find_all("a",attrs={'href':re.compile('^((?!http).)*$'),'target':'_blank'})

    for img in all_img:
       title=img['title']
       if title.find(u"女") != -1 :
        print("不符合要求,跳過")
        continue

       soup1=getimgurl(img)
       im1=soup1.find('div',id='main').find('div',class_='endpage').find('div',class_='pic').find('p').find('a')
       soup2=getimgurl(im1)
       im2=soup2.find('div',id='main').find('table').find('a')

       img_url = im2['href']
       print (img_url)

       #root='/home/suwex/圖片/'
       root='/home/suwex/test2/'
       title=title.replace(',','|')
       title=title.replace(' ','|')
       path = root + title

       try:                              #建立或判斷路徑圖片是否存在並下載
           if not os.path.exists(root):
               os.mkdir(root)
           if not os.path.exists(path):
               r = requests.get(img_url)
               with open(path, 'wb') as f:
                   f.write(r.content)
                   f.close()
                   print("檔案儲存成功")
           else:
               print("檔案已存在")
       except:
           print("爬取失敗")



def main():
    for i in range(1,10):
      if i==1:
        url='http://www.netbian.com/weimei/index.htm'
      else:
        url='http://www.netbian.com/weimei/index_' + str(i) +'.htm'
      html=(getHtmlurl(url))
      print(str(i)+" : ")
      print(getpic(html))
main()