1. 程式人生 > >利用Beautifulsoup爬取網頁圖片

利用Beautifulsoup爬取網頁圖片

Beautifulsoup

Beautifulsop是一個python模組,該模組用於接收一個HTMLXML字元,然後將其進行格式化,之後便可以使用他提供的方式快速查詢指定的元素(如圖片,文字等),從而使得在htmlxml中查詢指定元素比起用正則表示式更簡單。

所用庫:

form bs4 import BeautifulSoup

常用方法及相關函式:

下面這篇文章對BeautifulSoup的講解非常詳細,推薦:

Beautifulsoup使用舉例:

這裡使用Beautifulsoup爬取豆瓣圖書的書名

先上程式碼:

from urllib import  request
from bs4 import BeautifulSoup

def getHtmlCode(url):
    headers = {
        'User-Agent' : 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko)  Chrome/56.0.2924.87 Mobile Safari/537.36'
    }
    url1 = request.Request(url, headers = headers)
    page = request.urlopen(url1).read().decode()
    return page
def getImg(page):
    soup = BeautifulSoup(page,'html.parser')                       #按照html格式解析頁面
    book_list = soup.find(attrs={"id":"book"})                     #找到id為book的標籤,這是包含所有書名資訊的最底層標籤
    book_list_name = book_list.find_all(attrs={"class":"title"})   #獲取id為book標籤下class為title的標籤
    for book_one in book_list_name:
        print(book_one.string)
url = 'http://www.douban.com/tag/%E5%B0%8F%E8%AF%B4/?focus=book'
page = getHtmlCode(url)
getImg(page)

輸出結果:

 

用瀏覽器檢視豆瓣讀書的首頁:

 

可以看到,輸出的就是豆瓣讀書首頁的所有書名。

程式碼講解:

這裡重點講解Beautifulsoup的使用。

1.首先使用Beautifulsoup()把獲取的網頁原始碼交給Beautifulsoup處理。

soup = BeautifulSoup(page,'html.parser')

2. 我們開啟瀏覽器檢視網頁原始碼,找到包含所有書名的最近的以及標籤。

 

可以看到書名都儲存在一個id = “book”的標籤中,且該標籤是包含所有書名最近的一層。

book_list = soup.find(attrs={"id":"book"})

該程式碼獲取id = “book”標籤的中的全部原始碼,儲存在

book_list中。

3. 想獲得所有書名只獲得book_list還夠的,因為我們還需要知道書名儲存的子標籤,開啟瀏覽器檢視網頁原始碼即可知。

 

可以看到書名是儲存在id = “book”標籤的子標籤中,該子標籤的class = “title”,根據這個來獲得子標籤的內容。這時有人會問了,為什麼是根據class = “title”來定位到這個子標籤呢?為什麼不是根據target = “_blank”來定位呢?這個問題先放一放,等會兒再來解答。

book_list_name = book_list.find_all(attrs={"class":"title"})

獲取到這些子標籤。

for book_one

in book_list_name:print(book_one.string)

輸出標籤中的內容(.string是獲取標籤內容而不是標籤屬性)。

現在我們返回來思考上面提出問題,為什麼不用target = “_blank”來定位到這些包含書名標籤,其實答案很簡單,就是唯一標識,class = “title”這個屬性只有這些子標籤包含,而target = “_blank”並不是唯一標識。

那麼又問了,我是怎麼知道class = “title”就是唯一標識,target = “_blank”不只有一種標籤擁有呢?

答案是,我也不知道!準確的說是我一開始也不知道,我不可能通過檢視網頁原始碼來確定其他種類的標籤(不包含書名的標籤)是否也包含這個屬性,這樣做太花費時間和精力了,所以我是通過實驗來確定的。

這裡做個實驗:把book_list_name = book_list.find_all(attrs={"class":"title"})換成book_list_name = book_list.find_all(attrs={"target":"_blank"})看會輸出什麼?

實驗結果:

 

可以看到除了輸出書名外還輸出了None,為什麼呢?可以猜測一下,應該是id = “book”標籤下的子標籤中除了含有書名的標籤外,還有其他標籤包含了target = “_blank”這個屬性,但是這個標籤中並沒有內容,所以輸出None

檢視瀏覽器原始碼,看看我們的猜測是否正確:

 

果然如此,說明我們的猜測是正確的,使用target = “_blank”這個屬性定位標籤會造成二義性。

如果覺得爬取書名太小兒科了,還想爬取書的所有圖片儲存在本地路徑中,這裡給出原始碼,有了上面的講解,相信下面的程式碼讀起來就不難了吧。

原始碼:(對上述原始碼稍加修改)

from urllib import  request
from bs4 import BeautifulSoup

def getHtmlCode(url):
    headers = {
        'User-Agent' : 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Mobile Safari/537.36'
    }
    url1 = request.Request(url, headers = headers)
    page = request.urlopen(url1).read().decode()
    return page
def getImg(page):
    soup = BeautifulSoup(page,'html.parser')                #按照html格式解析頁面
    book_list = soup.find(attrs={"id":"book"})              #找到id為book的標籤,這是包含所有書名資訊的最底層標籤
    book_list_img = book_list.find_all('img')  
    x = 0
    for book_one in book_list_img:
        book_img_url = book_one.get('src')
        print(book_img_url)
        request.urlretrieve(book_img_url, 'E:\python_spider_fild\%s.jpg' %x)
        x += 1
url = 'http://www.douban.com/tag/%E5%B0%8F%E8%AF%B4/?focus=book'
page = getHtmlCode(url)
getImg(page)

 

分析:

這裡只需額外講解一個方法:book_img_url = book_one.get('src')

該方法是獲取book_one標籤中的src屬性的內容,src屬性內容是對應圖書的圖片的url, 從瀏覽器中檢視html原始碼可以看到:

  

結果:

 

圖片下載到了本地路徑下。