創作內容

1 GP

Beautiful Soup (下)

作者:Yotsuba│2020-05-27 12:50:09│巴幣:2│人氣:289
請你先點擊這個連結 : https://www.pythonscraping.com/pages/page3.html

針對這個網站,我們在意的資料大概有四項,包括 :

商品標題、商品描述、商品價格、商品圖片 (圖片連結)

我們的目的就是要爬取這些資訊




由於這個 HTML 結構又更複雜了,很難直接用肉眼去觀察原始碼

這時候我們需要一些工具幫助我們快速找到我們要的資料


import requests
from bs4 import BeautifulSoup

response = requests.get('http://pythonscraping.com/pages/page3.html')

soup = BeautifulSoup(response.text, 'html.parser')

print(soup.prettify())


取得 HTML 內容以後,可以使用 prettify() 這個函式,它會去幫你做基本的排版

執行結果




結果算是有些差強人意,沒有變得比較好看

畢竟因為礙於終端機的顯示大小,加上沒有語法高亮,還是難以閱讀

這個功能知道一下就好,還是可以看場合使用




你也可以在瀏覽器頁面,直接對著文字按下右鍵 -> 檢查

這個功能和 prettify() 一模一樣,可讀性更高

經過一番分析,我們可以得到以下程式碼 :


import requests
from bs4 import BeautifulSoup

# Get HTML and parse it
response = requests.get('http://pythonscraping.com/pages/page3.html')

soup = BeautifulSoup(response.text, 'html.parser')


# Print the gifts
tr_list = soup.find_all('tr', class_ = 'gift')

for tr in tr_list:
    print(tr.find('img').get('src').strip().replace('..', 'https://www.pythonscraping.com') + '\n')

    td_list = tr.find_all('td')

    for td in td_list:
        print(td.text.strip() + '\n')


執行結果




因為終端機大小的關係,沒辦法用成像表格那樣顯示,或者說 Description 太長了

所以就以 Image , Item Title , Description , Cost 這樣去顯示,程式比較好撰寫

那就從 Print the gifts 那行註解開始解說起


整個 HTML 總共有 6 個 <tr> 節點,不過我們只需要後面 5 個

因為第一個是大標題系列,我們不想要這些資料

tr_list = soup.find_all('tr', class_ = 'gift')

這行程式碼,剛好會回傳後面 5 個 <tr> 的,故稱作 tr_list


這裡有幾個重點

首先,我們要找到「全部」的 <tr> 節點,所以我們使用 find_all()

但是我們又不想爬取第 1 個 <tr>,只想要後面 5 個

我們就可以利用節點的 class 屬性過濾掉

因為第 1 個節點沒有 gift 屬性,後面 5 個都有

注意 ! class 是 Python 的保留字,Beautiful Soup 這邊定義它是 class_ !


接下來就可以用 for 去疊代每一個節點了

首先我們 print 出它的網址,這裡有點複雜

我們先找到 img 這個節點,然後用 get() 取出其中的 src 屬性

接著用 strip() 去除頭尾的空白 (沒使用的話會被換行)

由於取出來的字串會是 ../img/gifts/img1.jpg,所以我們再把 .. 換成網站的 Domain 就完成了


來做個 URL 解析好了

以 https://www.pythonscraping.com/img/gifts/img1.jpg 來說

https 是傳輸協定,www.pythonscraping.com 是網域,img/gifts/img1.jpg 是檔案

也就是說,用 https 傳輸協定到 www.pythonscraping.com 這個網域的 img/gifts/ 這個資料夾取得 img1.jpg 這個檔案


接著看到 td_list = tr.find_all('td') 這行

因為每個 <tr> 底下又包著許多 <td>,其實就是一些商品資訊

一樣用 find_all() 找出來,再去疊代 print 出來


Beautiful Soup 的用法實在太多太多了,希望大家可以不看原始碼,自己爬取一遍

可以不用每個用法都記沒關係,但是要用的時候可以多多翻閱官方文件,我自己也是要用才查詢


下一章節我會幫大家做個總結

引用網址:https://home.gamer.com.tw/TrackBack.php?sn=4796458
All rights reserved. 版權所有,保留一切權利

相關創作

留言共 2 篇留言

多古尼爾抱抱怪獸鮭魚
那個應該是域名(domain name)
DNS為域名系統
不過這不是重點就是了XD

05-27 19:52

Yotsuba
OK 感謝提醒 ! 我把它改掉了

也不能說不重要

雖然我想表達的意思一樣,但是出了語病,可能會造成別人誤解

再次感謝 !05-27 22:00
風蕭蕭荊軻醬
最後的for td in td_list:
print(td.text.strip() + '\n')
這邊找td_list裡面有td的項目不是會包含前面的圖片嗎
所以是因為加了.text不會在印出一次圖片ㄇ
有點看不太懂為啥不會再印出圖片網址

07-12 18:50

Yotsuba
<td><img src="../img/gifts/img1.jpg"></td>

以這個節點當例子好了 (其實每個結構都一樣)

img 是節點,src 是屬性,實際上 td 裡面沒有任何「文字」

所以不會重複印出圖片網址07-13 03:38
我要留言提醒:您尚未登入,請先登入再留言

1喜歡★happy819tw 可決定是否刪除您的留言,請勿發表違反站規文字。

前一篇:我為什麼會學 Pytho... 後一篇:Beautiful So...

追蹤私訊切換新版閱覽

作品資料夾

laxrc817喜歡看實況的巴友
我的實況台 https://www.youtube.com/channel/UCXgFa35QQUZSmYqGGao9tTw?sub_confirmation=1 惡靈古堡8村莊 實況 喜歡的話歡迎訂閱看更多我要大聲說59分前


face基於日前微軟官方表示 Internet Explorer 不再支援新的網路標準,可能無法使用新的應用程式來呈現網站內容,在瀏覽器支援度及網站安全性的雙重考量下,為了讓巴友們有更好的使用體驗,巴哈姆特即將於 2019年9月2日 停止支援 Internet Explorer 瀏覽器的頁面呈現和功能。
屆時建議您使用下述瀏覽器來瀏覽巴哈姆特:
。Google Chrome(推薦)
。Mozilla Firefox
。Microsoft Edge(Windows10以上的作業系統版本才可使用)

face我們了解您不想看到廣告的心情⋯ 若您願意支持巴哈姆特永續經營,請將 gamer.com.tw 加入廣告阻擋工具的白名單中,謝謝 !【教學】