利用Beautifulsoup爬取網頁圖片
Beautifulsoup
Beautifulsop是一個python模組,該模組用於接收一個HTML或XML字元,然後將其進行格式化,之後便可以使用他提供的方式快速查詢指定的元素(如圖片,文字等),從而使得在html或xml中查詢指定元素比起用正則表示式更簡單。
所用庫:
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”標籤的中的全部原始碼,儲存在
3. 想獲得所有書名只獲得book_list還夠的,因為我們還需要知道書名儲存的子標籤,開啟瀏覽器檢視網頁原始碼即可知。
可以看到書名是儲存在id = “book”標籤的子標籤中,該子標籤的class = “title”,根據這個來獲得子標籤的內容。這時有人會問了,為什麼是根據class = “title”來定位到這個子標籤呢?為什麼不是根據target = “_blank”來定位呢?這個問題先放一放,等會兒再來解答。
book_list_name = book_list.find_all(attrs={"class":"title"})
獲取到這些子標籤。
for book_one
輸出標籤中的內容(.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原始碼可以看到:
結果:
圖片下載到了本地路徑下。