Python爬蟲練習筆記——爬取單個網頁裏的所有圖片(入門)

最近閒着,想學一下爬蟲 (^-^)V ——[手動比耶]
先從簡單的練習開始吧~ 爬取單個網頁裏的所有圖片,這個沒有什麼難點,因爲不需要翻頁哈哈哈哈。

我很喜歡一些文章中的配圖,比如這篇,裏面就會有很多電影中的經典截圖。
在這裏插入圖片描述

第一步:分析網頁

首先需要了解要爬取網站的頁面,查看網頁源代碼。然後根據網頁源代碼的結構,想好代碼的步驟和思路。

在網頁中查看頁面的源代碼(F12)

  1. 先來看一下頁面的請求方式:
    在開發者模式的Network裏找到.html的請求,可以看到請求方式是GET請求,也沒有帶什麼特殊的請求參數之類的~ 比較簡單。
    (如果沒有看到.html的請求,刷新一下頁面就出來了)
    在這裏插入圖片描述

  2. 然後再看代碼結構:
    (不太熟悉html的小夥伴可以使用圈圈裏的小箭頭,點一下自己想要看的元素,然後右側就會自動跳轉到該元素對應的代碼區域的~四不四很簡單)

    結合“上下文”簡單分析一下就會發現:(有種做閱讀理解的感覺hhhhh)
    ① 這個網頁裏所有的圖片都是放在 <img> 標籤裏的 src 後面,src後面這個鏈接就是圖片的地址
    (可以複製下來在瀏覽器打開確認一下)
    ② 圖片上方的描述語是放在class="pictext"p 標籤裏的
    (曾打算過用這個描述語句作爲爬下來的圖片的名稱的)
    在這裏插入圖片描述
    這樣一來就很簡單了
    只需要先拿到網頁的 HTML 代碼,然後把頁面裏面所有<img> 標籤裏的 src 後面超鏈接的內容取出來就行了!

第二步:開始編程

1. 定義庫
  • 首先需要用 requests 庫來發出一個網絡請求:
import requests
  • 然後需要用 BeautifulSoup 來解析和提取 HTML 數據
from bs4 import BeautifulSoup

這裏也可以直接import bs4,但代碼中每次用的時候都要寫上包名bs4,如:bs4.BeautifulSoup 啥啥啥

from bs4 import BeautifulSoup 是直接將BeautifulSoup 類導入到當前命名空間直接使用,不需要再帶包名。因此建議用from bs4 import BeautifulSoup

  • 最後需要還需要用 urllib.request 來將網絡對象複製到本地文件
import urllib.request

感覺 urllib.request 和前面導入的 requests有點像呀~ 查了一下資料發現是這樣:

通常而言,在我們使用python爬蟲時,更建議用requests庫,因爲requests比urllib更爲便捷,requests可以直接構造get,post請求併發起,而urllib.request只能先構造get,post請求,再發起。

但是將網絡對象複製到本地文件這個功能需要通過 urllib.request.urlretrieve()函數來實現,所以兩個庫都導入了。

這個網頁比較簡單,導入這三個庫就夠用了~

2. 定義一個函數getMoviesImg()

① 獲取網站數據:
res = requests.get(url,params=params,headers=headers) 這樣獲取到的結果是一個 HTTP 狀態碼。
需要用.text 方法再來獲取一下這個結果裏的文本信息。

有的網站對於反爬蟲力度比較大,請求的時候可以構造一個請求頭加上,請求頭(Request Headers)在最前面開發者模式中的 Network 裏就可以找到。

今天爬取的這個頁面很簡單,就直接 GET 請求 url 即可,可以啥都不帶。

#獲取網站數據
url = requests.get('http://news.jstv.com/a/20171018/1508322421993.shtml')
#url.encoding = 'utf-8'  #如果需要用到頁面中的漢字內容,則需要進行解碼,否則中文會出現亂碼
html = url.text

ps:比如這個頁面↓,百度搜索“經典電影臺詞截圖”,請求的url就是由問號 ? 前面基本的url地址和後面的一大堆參數組成的,這時候就需要用到 params 了。
在這裏插入圖片描述

② 解析網頁:
BeautifulSoup4 是將複雜HTML文檔轉換成一個複雜的樹形結構,每個節點都是Python對象,之後就可以利用 soup 加標籤名輕鬆地獲取這些標籤的內容了。

參考beautifulsoup菜鳥教程

BeautifulSoup(markup,'html.parser')

  • markup 是被解析的html格式的內容
  • html.parser表示解析用的解析器
#解析網頁
soup = BeautifulSoup(html,'html.parser')

③ 獲取所有標籤內容:
完成了前面的工作,獲取標籤內容就變得很簡單了~

#獲取所有的img標籤
movie = soup.find_all('img')
#獲取src路徑
for i in movie:
	imgsrc = i.get('src')
  • 擴展一下~
bs = BeautifulSoup(html,"html.parser")

print(bs.title) 			# 獲取title標籤的所有內容
print(bs.title.name)		# 獲取title標籤的標籤名稱
print(bs.title.string)		# 獲取title標籤的文本內容
print(bs.head) 				# 獲取head標籤的所有內容
print(bs.div) 				# 獲取第一個div標籤中的所有內容
print(bs.div["id"]) 		# 獲取第一個div標籤的id的值
print(bs.a) 				# 獲取第一個a標籤的所有內容
print(bs.find_all("a"))	    # 獲取所有的a標籤的所有內容
print(bs.find(id="u1"))	    # 獲取id="u1"
for item in bs.find_all("a"): 
    print(item.get("href")) # 獲取所有的a標籤,並遍歷打印a標籤中的href的值
for item in bs.find_all("a"): 
    print(item.get_text())	# 獲取所有的a標籤,並遍歷打印a標籤的文本值

④ 將URL表示的網絡對象下載到本地:
我這裏用到的是 urlretrieve () 函數,它可以直接將遠程數據下載到本地。
urlretrieve(url, filename=None, reporthook=None, data=None)

url:外部或者本地url,url中建議不要含有中文,否則容易出錯。
finename:指定了保存本地路徑(如果參數未指定,urllib會生成一個臨時文件保存數據。)
reporthook:是一個回調函數,當連接上服務器、以及相應的數據塊傳輸完畢時會觸發該回調,我們可以利用這個回調函數來顯示當前的下載進度。
data:指 post 到服務器的數據,該方法返回一個包含兩個元素的(filename, headers)元組,filename 表示保存到本地的路徑,header 表示服務器的響應頭。

#將URL表示的網絡對象複製到本地文件
urllib.request.urlretrieve(imgsrc , filename )
第三步:執行

run run run!
在這裏插入圖片描述
(最後有個無傷大雅的小報錯,就不截圖啦)

等它都跑完就可以在指定目錄中看到網頁裏所有的圖片啦~
在這裏插入圖片描述
--------------------------------------------- 補充 ---------------------------------------------

第四步:優化一下吧

執行以後發現會存在兩個問題:

  1. 網頁中還有很多其它的圖片,也是放在img標籤裏的,需要把這些圖片過濾掉;
    在這裏插入圖片描述
  2. 有一些src是空的,.urlretrieve()函數就會報錯:ValueError: unknown url type: ''
    在這裏插入圖片描述
    想了一個比較簡單的解決辦法,就是隻下載符合要求的src鏈接。
    打印出所有的 src 路徑,就會發現網頁中所有想要的圖片的鏈接路徑都是以 “http://static.jstv.com/gather/hl/20171018/” 開頭的。
    在這裏插入圖片描述
    這樣的話就可以用.startswith()函數判斷之後再下載。
#判斷圖片src路徑是否以指定內容開頭(過濾頁面中的其它不想要的圖片)
	if imgsrc.startswith('http://static.jstv.com/gather/hl/20171018/'):
        ……

改改改,runrunrun
多好看~~~
在這裏插入圖片描述

最後附上並沒有多少行的完整代碼:

import requests
import urllib.request
from bs4 import BeautifulSoup

def getMoviesImg():
    url = requests.get('http://news.jstv.com/a/20171018/1508322421993.shtml')
    #獲取網站數據
    html = url.text
    #解析網頁
    soup = BeautifulSoup(html,'html.parser')
    #獲取所有的img標籤
    movie = soup.find_all('img')
    x = 1
    for i in movie:
        # 獲取src路徑
        imgsrc = i.get('src')
        #判斷圖片src路徑是否以指定內容開頭(過濾頁面中的其它不想要的圖片)
        if imgsrc.startswith('http://static.jstv.com/gather/hl/20171018/'):
            # print(imgsrc)
            #本地路徑
            filename = 'E:/download/movie/%s.jpg'%x
            #將URL表示的網絡對象複製到本地文件
            urllib.request.urlretrieve(imgsrc , filename)
            print('下載第%d張' % x)
            x += 1
    print('**下載完成!**')

getMoviesImg()

立兩個小小的flag在這裏:

  1. 下次想用網頁裏圖片的描述作爲對應圖片下載後的名稱。
  2. 以後再爬個好看的小說吧!

撒花!!!✿✿ヽ(°▽°)ノ✿

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