創作內容

1 GP

網頁節點定位整理(CSS、Python 搭配 BeautifulSoup 套件)

作者:Jia│2020-05-09 22:23:51│巴幣:2│人氣:1693
最新版移至我新架設的部落格,能有更好的觀看體驗:
歡迎前往~

最近開始接觸爬蟲,因此順便把一些可能常用的網頁取得節點方式整理一下,
第一部分是純CSS,第二部分則是 Python 搭配 BeautifulSoup 套件。
如有任何錯誤或建議,歡迎底下留言~


純CSS
先上表格,後面還有範例。
tag定位 span font
id定位 #ID
class定位 .CLASS
屬性值 [name="NAME"]
屬性值(不等於) [name!="NAME"]
屬性值包含 [title*="TITLE"]
屬性值開頭 [title^="start"]
屬性值結尾 [title$="end"]
第1個子節點 ul li:first-child
最後1個子節點 ul li:last-child
第2個子節點 ul li:nth-child(2)
倒數第2個子節點 ul li:nth-last-child(2)
同一層往後尋找節點 #ID ~ i
同一層的"下一個"節點 #ID + *
同時尋找多種選擇器 #id1 , #id2




  
 
以下範例:
<!--HTML-->
<div>
    <span>
        <div><font>001</font></div>
        <font>002</font>
    </span>

    <div id="ID">003</div>
    <div class="CLASS CLASS2">004</div>

    <i name="NAME" style="STYLE">005</i>
    <i name="NAME2" style="STYLE">006</i>

    <div title="TITLE">007</div>
    <div title="start-TITLE">008</div>
    <div title="TITLE-end">009</div>

    <ul id="list">
        <li>1001</li>
        <li>1002</li>
        <li>1003</li>
        <li>1004</li>
    </ul>

</div>

# tag定位:
soup.select_one('span font')
# <font>001</font>
soup.select_one('span > font')
# <font>002</font>

# id定位:
soup.select_one('#ID')
soup.select_one('div#ID')
# <div id="ID">003</div>

# class定位:
soup.select_one('.CLASS')
soup.select_one('div.CLASS')
soup.select_one('div.CLASS.CLASS2')
# <div class="CLASS CLASS2">004</div>

# —————————————————————————
# 節點有某屬性:
soup.select_one('i[name]')
# <i name="NAME" style="STYLE">005</i>

# 屬性值:
soup.select_one('i[name="NAME"]')
soup.select_one('i[name="NAME"][style="STYLE"]')
# <i name="NAME" style="STYLE">005</i>

# 屬性值不等於:
soup.select_one('i[name!="NAME"]')
# <i name="NAME2" style="STYLE">006</i>

# 屬性值包含某字串:
soup.select_one('div[title*="TITLE"]')
# <div title="TITLE">007</div>

# 屬性值以某字串開頭:
soup.select_one('div[title^="start"]')
# <div title="start-TITLE">008</div>

# 屬性值以某字串結尾:
soup.select_one('div[title$="end"]')
# <div title="TITLE-end">009</div>

# —————————————————————————
# 第1個子節點:
soup.select_one('ul#list li:first-child')
# <li>1001</li>

# 最後1個子節點:
soup.select_one('ul#list li:last-child')
# <li>1004</li>

# 第2個子節點:
soup.select_one('ul#list li:nth-child(2)')
# <li>1002</li>

# 倒數第2個子節點:
soup.select_one('ul#list li:nth-last-child(2)')
# <li>1003</li>

# —————————————————————————
# 在同一層往後尋找節點
soup.select_one('#ID ~ i')
# <i name="NAME" style="STYLE">005</i>

# 在同一層的"下一個"節點
soup.select_one('#ID + *')
# <div class="CLASS CLASS2">004</div>

# 在同一層,往後尋找"下一個"節點
soup.select_one('#ID + div')
# <div class="CLASS CLASS2">004</div>

# 在同一層,往後尋找中間跳過一個節點的"下一個"節點
soup.select_one('#ID + * + i')
# <i name="NAME" style="STYLE">005</i>

# —————————————————————————
# 同時尋找多種選擇器
soup.select('#ID , .CLASS')
# [<div id="ID">003</div>, <div class="CLASS CLASS2">004</div>]



搭配 BeautifulSoup 套件
<!--HTML-->
<div>
    <span>標題</span>
    <span>副標題</span>
    <span>第二副標題</span>

    <div class="a" title="first" href="/link">這是一行句子</div>

    <a href="/link1">這是超連結1</div>
    <a href="/link2">這是超連結2</div>

    <div data-target="value">data屬性</div>

    <div class="CLASS CLASS2">多個class</div>
    
</div>

# 返回符合的單個節點(如有多個符合,則回傳第一個),當找不到則回傳None:
soup.select_one('span')
soup.find('span')
# <span>標題</span>

# 返回符合的全部節點(List),當找不到則回傳空List:
soup.select('span')
soup.find_all('span')
# [<span>標題</span>, <span>副標題</span>, <span>第二副標題</span>]

# —————————————————————————
# 取得節點的文字:
soup.select_one('div.a').text
# 這是一行句子
# 如果需要更多擷取方式,可使用get_text()

# 取得節點屬性的值:
soup.select_one('div.a').get('title')
# first
soup.select_one('div.a').get('class')
# ['a']
soup.select_one('div.a').get('href')
# /link

# 限制尋找節點數量:
soup.select("span", limit=2)
# [<span>標題</span>, <span>副標題</span>]

# —————————————————————————
# 有些較複雜的也可以改用 find 或 find_all 來尋找。
# 基本的
soup.find_all(title="first")
# [<div class="a" href="/link" title="first">這是一行句子</div>]

# 因為 class 在 Python 中是保留字,所以尋找class時改使用 class_:
soup.find_all(class_="CLASS")
# [<div class="CLASS CLASS2">多個class</div>]

# 當想比對全部class(注意順序)
soup.find_all(class_="CLASS CLASS2")
# [<div class="CLASS CLASS2">多個class</div>]

# 某些HTML的屬性直接寫的話,會發生錯誤(例如 data-* 這類的屬性),
# 改使用另一種方式即可:
soup.find_all(attrs={"data-target": "value"})
# [<div data-target="value">data屬性</div>]

# 以正規表示式比對超連結網址:
soup.find_all(href=re.compile("^/link\d"))
# [<a href="/link1">這是超連結1</a>, <a href="/link2">這是超連結2</a>]

# 以文字內容尋找(也可搭配正規表示式)
soup.find_all("div", string="這是一行句子")
soup.find_all("div", string=re.compile("句子"))
# [<div class="a" href="/link" title="first">這是一行句子</div>]


前面說的是以其節點往下尋找子節點,那如果要找父節點或同一層節點,使用以下方式:
<!--HTML-->
<div id="div2">
    <div id="div1">
        <p id="a">第一點</p>
        <p id="b">第二點</p>
        <p id="my">第三點</p>
        <p id="c">第四點</p>
        <p id="d">第五點</p>
    </div>
</div>

# 先以 <p id="my">第三點</p> 節點為基準
my_tag = soup.find(id="my")

# 函式名稱多加s,代表尋找多個

# 向上尋找父節點
my_tag.find_parent("div")
my_tag.find_parents("div")

# 在同一層往前尋找節點
my_tag.find_previous_sibling("p")
# <p id="b">第二點</p>
my_tag.find_previous_siblings("p")
# [<p id="b">第二點</p>, <p id="a">第一點</p>]

# 在同一層往後尋找節點
my_tag.find_next_sibling("p")
# <p id="c">第四點</p>
my_tag.find_next_siblings("p")
# [<p id="c">第四點</p>, <p id="d">第五點</p>]


在擷取網頁可能還需要的功能:
# 去除某個節點
node = soup.select_one("#my").extract()

# 去除多個節點
# 注意:前面已經將 #my 移除了
node = [t.extract() for t in soup.select("p")]



以上程式碼省略
import re
from bs4 import BeautifulSoup

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

(題外話:
(巴哈小屋的編輯文章系統真的不好用...

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

相關創作

同標籤作品搜尋:節點定位|CSS|BeautifulSoup|爬蟲|Python|網頁

留言共 1 篇留言

Hong
感謝分享~
希望有實作範例[e12]

05-15 15:35

Jia
麥來亂05-15 18:43
我要留言提醒:您尚未登入,請先登入再留言

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

前一篇:使用Python、Fla... 後一篇:「Python」、「新海...

追蹤私訊切換新版閱覽

作品資料夾

a4755063巴友
小說更新啦~歡迎來寒舍參觀看更多我要大聲說昨天12:09


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

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