φυβλαςのβλογ
บล็อกของ phyblas



[python] การสกัดข้อมูลจากหน้าเว็บด้วย beautifulsoup
เขียนเมื่อ 2018/03/23 00:05
แก้ไขล่าสุด 2021/09/28 16:42
ในตอนที่แล้วได้แนะนำการดึงข้อมูลจากหน้าเว็บมาแล้ว https://phyblas.hinaboshi.com/20180320

หน้าเว็บถูกเขียนด้วย html จำเป็นต้องนำมาสกัดแยกเพื่อหาข้อมูลจากในนั้นที่เราต้องการอีกที วิธีการหนึ่งที่นิยมใช้ก็คือทำด้วยมอดูล beautifulsoup

การติดตั้งทำได้ง่ายด้วย pip
pip install beautifulsoup4

หรือ conda
conda install beautifulsoup4

เวลาจะเรียกใช้ก็ให้ import ชื่อ bs4 ปกติจะใช้อยู่แค่ออบเจ็กต์ BeautifulSoup ตัวเดียว
from bs4 import BeautifulSoup


เริ่มสกัดซุปจากเว็บ
ขอยกตัวอย่างโดยใช้หน้าเว็บที่ได้เตรียมไว้สำหรับทดสอบโดยเฉพาะ (เห็นว่าเนื้อหาเกี่ยวกับซุปก็เลยใช้หัวข้อเป็นเรื่องอาหาร)

>> https://hinaboshi.com/súpđẹp.html

โค้ด html ของหน้าเว็บนี้เป็นดังนี้
<html>
<head><meta charset="UTF-8"><title>~หน้าทดสอบซุปสวย~</title></head>
<body>
<div class="klongyai">
    <div id="huakho"><img src="https://phyblas.hinaboshi.com/rup/thema/qb.png" width="180"><br>
    <h3>ว่าด้วยเรื่องของอาหย่อย</h3></div><br><br>
    <div class="klonglek" id="wali1">
        <a href="walidet/946641382021300"><img src="rup/rupprakopwalidet/946641382021300.jpg"></a>
        <h4 class="khokhwam">"ของอร่อยแบบนี้ไม่ว่าจะฤดูไหนมันก็อร่อยอยู่ดีแหละ"</h4>
        <span class="chue kirin">#โมริโนะ คิริง</span>
    </div>
    <br><br><div id="qb">/人◕ ‿‿ ◕人\</div><br><br>
    <div class="klonglek" id="wali2">
         <a href="walidet/1793364814015615"><img src="rup/rupprakopwalidet/1793364814015615.jpg"><h4 class="khokhwam">"ต่อให้เป็นของที่อร่อยแค่ไหนหากกินทุกวันก็ต้องเบื่"</h4><span  class="chue kazuma">#อาซึมะ คาซึมะ</span></a>
    </div>
</div>
<p align="center"><a href="https://hinaboshi.com">&lt;&lt;-- รวมคำแปลวลีเด็ดจากญี่ปุ่น --&gt;&gt;</a></p>
</body>
<style>#huakho,#qb {text-align:center}
.klongyai {width:800px;; background:#F8E290; margin:50px; padding:20px}
.chue {color: #12B6A6; font-weight:bold}
h4 {font-weight:100}</style>
</html>


เริ่มจากทำการอ่านเอาเนื้อความ html โดยใช้ requests จากนั้นก็สกัดซุปออกมาจาก html
import requests
url_naweb = 'https://hinaboshi.com/súpđẹp.html'
r = requests.get(url_naweb)
r.encoding = 'utf-8' # กำหนด encoding กันปัญหาการถอดรหัสผิดแบบ
sup = BeautifulSoup(r.text,'lxml')


จะได้ sup เป็นออบเจ็กต์ชนิด bs4.BeautifulSoup ซึ่งเก็บเอาเนื้อหาโค้ด html ในหน้าเว็บนั้นทั้งหมดไว้เพื่อใช้ในการสกัดข้อมูลข้างในอีกที

lxml ในที่นี้คือชื่อชนิดของตัวถอดข้อความ ปกติที่ใช้อ่าน html ธรรมดาคือ lxml, html.parser โดยที่ lxml จะใช้งานได้ดีกว่า แต่ต้องลงมอดูล lxml เสริมจึงจะใช้ได้ หากใครยังไม่ได้ลงไว้ก็ใช้ pip ลงได้ทันที
pip install lxml

อนึ่ง sup นั้นหาก print ออกมาแล้วจะได้เป็นข้อความเหมือนกับเป็นสายอักขระ แต่ตัวมันเองก็ไม่ใช่สายอักขระธรรมดา แต่เป็นชนิดออบเจ็กต์ในคลาส bs4.BeautifulSoup ซึ่งมีความสามารถทำอะไรได้มากมาย
type(sup) # ได้ bs4.BeautifulSoup


เข้าใจโครงสร้างแท็กของ html
ขออธิบายถึงโครงสร้าง html คร่าวๆพอให้ไปต่อได้ แต่จะไม่ลงลึกเพราะไม่ได้อยู่ในขอบเขตเนื้อหา

โครงสร้างโดยทั่วไปของ html นั้นประกอบไปด้วยแท็ก (tag) ต่างๆซึ่งก็คือกรอบที่ล้อมด้วย < > โดยภายในกรอบนี้จะเริ่มจากชนิดของแท็ก เช่น a, div, h3, img เป็นต้น

แล้วก็ตามด้วยส่วนระบุค่าแอตทริบิวต์ของแท็กซึ่งจะตามด้วย = แล้วตามด้วยค่า เช่น id="huakho", class="chue", src="qb.png", href="https://hinaboshi.com" เป็นต้น

แท็กบางชนิดเป็นแบบเดี่ยว เช่นแท็ก <img>, <br> เป็นต้น แต่แท็กส่วนใหญ่จะต้องมีแท็กเปิดและแท็กปิด โดยที่แท็กปิดจะขึ้นต้นด้วยสแลช / เช่น <a></a>, <div></div>, <h3></h3> แบบนี้

ระหว่างแท็กเปิดและแท็กปิดจะมีเนื้อหาใส่อยู่ด้านใน โดยเนื้อหานั้นอาจจะประกอบไปด้วยแท็กย่อยอีกที

เช่น
<head><meta charset="UTF-8"><title>"หน้าทดสอบซุปสวย"</title></head>

แบบนี้คือในแท็ก head มีเนื้อหาเป็น
<meta charset="UTF-8"><title>หน้าทดสอบซุปสวย</title>

ส่วน
<meta charset="UTF-8">

เป็นแท็กแบบเดี่ยว ส่วน
<title>"หน้าทดสอบซุปสวย"</title>

เป็นแท็กที่มีเนื้อหาภายในคือ
"หน้าทดสอบซุปสวย"

เพื่อที่จะเห็นโครงสร้างแท็กอย่างเป็นระเบียบชัดเจนอาจใช้เมธอด .prettify()
print(sup.prettify())


จะได้อะไรแบบนี้ออกมา แท็กยิ่งอยู่ย่อยด้านในก็จะร่นไปทีละช่อง ดูแล้วเข้าใจง่าย
<html>
 <head>
  <meta charset="utf-8"/>
  <title>
   ~หน้าทดสอบซุปสวย~
  </title>
 </head>
 <body>
  <div class="klongyai">
   <div id="huakho">
    <img src="https://phyblas.hinaboshi.com/rup/thema/qb.png" width="180"/>
    <br/>
    <h3>
     ว่าด้วยเรื่องของอาหย่อย
    </h3>
   </div>
   <br/>
   <br/>
   <div class="klonglek" id="wali1">
    <a href="walidet/946641382021300">
     <img src="rup/rupprakopwalidet/946641382021300.jpg"/>
    </a>
    <h4 class="khokhwam">
     "ของอร่อยแบบนี้ไม่ว่าจะฤดูไหนมันก็อร่อยอยู่ดีแหละ"
    </h4>
    <span class="chue kirin">
     #โมริโนะ คิริง
    </span>
   </div>
   <br/>
   <br/>
   <div id="qb">
    /人◕ ‿‿ ◕人\
   </div>
   <br/>
   <br/>
   <div class="klonglek" id="wali2">
    <a href="walidet/1793364814015615">
     <img src="rup/rupprakopwalidet/1793364814015615.jpg"/>
     <h4 class="khokhwam">
      "ต่อให้เป็นของที่อร่อยแค่ไหนหากกินทุกวันก็ต้องเบื่อ"
     </h4>
     <span class="chue kazuma">
      #อาซึมะ คาซึมะ
     </span>
    </a>
   </div>
  </div>
  <p align="center">
   <a href="https://hinaboshi.com">
    &lt;&lt;-- รวมคำแปลวลีเด็ดจากญี่ปุ่น --&gt;&gt;
   </a>
  </p>
 </body>
 <style>
  #huakho,#qb {text-align:center}
.klongyai {width:800px;; background:#F8E290; margin:50px; padding:20px}
.chue {color: #12B6A6; font-weight:bold}
h4 {font-weight:100}
 </style>
</html>


ในที่นี้แท็กเดี่ยวทั้งหมดจะถูกใส่ / เพิ่มต่อท้ายก่อน > แม้ว่าเวลาเขียนโดยทั่วไปจะไม่ได้จำเป็นต้องใส่ แต่พอใส่แบบนี้ก็จะแยกแยะได้ชัดเจนว่านี่เป็นแท็กเดี่ยวที่ไม่ต้องการคู่มาเป็นตัวปิด

แท็กใหญ่สุดจะเป็น <html> เสมอ และแท็กย่อยลงมาก็มักจะประกอบด้วย <head> และ <body> แล้วข้างในก็มีแท็กย่อยลงไปอีกเรื่อยๆ



ค้นหาแท็กที่ต้องการ
เมื่อเข้าใจโครงสร้างโดยภาพรวมแล้วต่อไปก็ทำการสกัดเอาข้อมูลภายใน คำสั่งที่น่าจะถูกใช้บ่อยที่สุดก็คือ .find_all() ซึ่งใช้สำหรับหาแท็กที่ต้องการจากเนื้อหาข้างในทั้งหมด ได้ออกมาเป็นลิสต์

เช่นลองหาแท็ก img ซึ่งเป็นแท็กรูปภาพ จะได้รูปทั้งหมด
print(sup.find_all('img'))
# ได้ [<img src="https://phyblas.hinaboshi.com/rup/thema/qb.png"  width="180"/>, <img  src="rup/rupprakopwalidet/946641382021300.jpg"/>, <img  src="rup/rupprakopwalidet/1793364814015615.jpg"/>]

แต่มีวิธีเขียนที่สะดวกกว่านั้น .find_all สามารถแทนด้วยการแค่ใส่วงเล็บเรียกโดยตรงได้ เช่นแบบนี้จะมีค่าเท่าเดิม
print(sup('img'))

ดังนั้นแค่ตัด .find_all ทิ้งไป ผลที่ได้ก็เหมือนเดิม

ถ้าลองหาแท็กที่เป็นแบบมีคู่ ก็จะได้เนื้อหาที่อยู่ข้างในติดมาทั้งหมด
print(sup('h4'))
# ได้ [<h4 class="khokhwam">"ของอร่อยแบบนี้ไม่ว่าจะฤดูไหนมันก็อร่อยอยู่ดีแหละ"</h4>,  <h4  class="khokhwam">"ต่อให้เป็นของที่อร่อยแค่ไหนหากกินทุกวันก็ต้องเบื่อ"</h4>]

หากรู้ว่าแท็กที่ต้องการหานั้นมีอันเดียว หรือต้องการให้หาแค่อันเดียวก็อาจเมธอด .find จะเป็นการค้นเอาเฉพาะแท็กนั้นอันแรกที่หาเจอ เช่น
print(sup.find('a'))
#  ได้ <a href="walidet/946641382021300"><img src="rup/rupprakopwalidet/946641382021300.jpg"/></a>

หรือมีวิธีการเขียนที่สะดวกกว่านั้น ก็คือพิมพ์จุด . แล้วต่อด้วยชื่อของแท็กนั้นเลย เช่น
print(sup.a)

แบบนี้จะเหมือนกับการใช้ .find

แท็กที่ได้ออกมานี้จะอยู่ในรูปของออบเจ็กต์ในคลาส bs4.element.Tag ซึ่งคุณสมบัติก็เกือบจะเหมือนกับ bs4.BeautifulSoup คือสามารถนำมาใช้ค้นหาแท็กย่อยภายในต่อไปได้อีก เช่น
print(sup.find_all('div')[2].find('h4'))
# หรือ print(sup('div')[2].h4)
# ได้ <h4 class="khokhwam">"ของอร่อยแบบนี้ไม่ว่าจะฤดูไหนมันก็อร่อยอยู่ดีแหละ"</h4>

หากทำแบบนี้เราก็สามารถค่อยๆไล่ค้นจากแท็กใหญ่ไปแท็กย่อยจนสุดได้ เช่นแบบนี้
print(sup.html.body.div.div.h3)
# ได้ <h3>ว่าด้วยเรื่องของอาหย่อย</h3>



ค้นหาจากแอตทริบิวต์
การค้นหานั้นนอกจากจะค้นจากชนิดแท็กแล้วก็ยังหาจากค่าแอตทริบิวต์ได้ด้วย โดยใส่ชื่อแอตทริบิวต์ที่ต้องการเป็นคีย์เวิร์ดแล้วใส่ค่าที่ต้องการ
print(sup.find(align='center'))
# ได้ <p align="center"><a href="https://hinaboshi.com">&lt;&lt;--  รวมคำแปลวลีเด็ดจากญี่ปุ่น --&gt;&gt;</a></p>

หรืออาจเขียนในรูปแบบดิกใส่ในค่า attrs แบบนี้ก็ได้
print(sup.find(attrs={'align':'center'}))

เพียงแต่ว่ากรณีที่แอตทริบิวต์ที่ต้องการหานั้นเป็น class วิธีแรกจะต้องเขียนเป็น class_ เนื่องจากคำว่า class เฉยๆเป็นคำสงวนของภาษาไพธอน
print(sup.find_all(class_='khokhwam'))
# ได้ [<h4 class="khokhwam">"ของอร่อยแบบนี้ไม่ว่าจะฤดูไหนมันก็อร่อยอยู่ดีแหละ"</h4>,  <h4  class="khokhwam">"ต่อให้เป็นของที่อร่อยแค่ไหนหากกินทุกวันก็ต้องเบื่อ"</h4>]

นอกจากนี้ class ยังมีความพิเศษอีกอย่างคือสามารถมีหลายค่าในเวลาเดียวกัน โดยเมื่อค่า class มีการเว้นวรรคจะถือว่าเป็นคนละตัวแยกกัน กรณีแบบนี้ขอแค่เข้าข่ายสักตัวก็จะค้นหาเจอ เช่น
print(sup.find_all(class_='chue'))
# ได้ [<span class="chue kirin">#โมริโนะ คิริง</span>,  <span class="chue kazuma">#อาซึมะ คาซึมะ</span>]

หากจะใช้ทั้งชนิดแท็กและค่าแอตทริบิวต์เป็นเงื่อนไขพร้อมกันก็ทำได้

เช่น หาแท็ก h4 ที่เป็น class ชื่อ khokhwam
print(sup.find('h4',class_='khokhwam'))
# ได้ <h4 class="khokhwam">"ของอร่อยแบบนี้ไม่ว่าจะฤดูไหนมันก็อร่อยอยู่ดีแหละ"</h4>


ดูค่าแอตทริบิวต์ของแท็ก
การจะเอาค่าแอตทริบิวต์ต่างๆในแต่ละแท็กนั้นทำได้โดยวิธีการแบบดิกชันนารี คือพิมพ์ ['ชื่อแอตทริบิวต์'] เช่น
img1 = sup.find_all('img')[1]
print(img1)
# ได้ <img src="rup/rupprakopwalidet/946641382021300.jpg"/>
print(img1['src'])
# ได้ rup/rupprakopwalidet/946641382021300.jpg


ดูชนิดของแท็ก
สามารถดูชนิดของแท็กได้โดยพิมพ์ .name ต่อท้าย เช่น
huakho = sup.find(class_='chue')
print(huakho) # ได้ <span class="chue kirin">#โมริโนะ คิริง</span>
print(huakho.name) # ได้ span


เอาเนื้อหาภายในแท็ก
หากต้องการเอาเนื้อหาภายในของแท็กโดยไม่รวมตัวแท็กเองให้ต่อท้ายด้วย .contents
print(sup.h4)
# ได้ <h4 class="khokhwam">"ของอร่อยแบบนี้ไม่ว่าจะฤดูไหนมันก็อร่อยอยู่ดีแหละ"</h4>
print(sup.h4.contents)
# ได้ ['"ของอร่อยแบบนี้ไม่ว่าจะฤดูไหนมันก็อร่อยอยู่ดีแหละ"']


หากต้องการสกัดเอาแค่ข้อความที่อยู่ในแท็กโดยไม่เอาส่วนตัวแท็กมาด้วยให้ต่อท้ายด้วย .text เช่น
print(sup.body.text)

ได้
ว่าด้วยเรื่องของอาหย่อย


"ของอร่อยแบบนี้ไม่ว่าจะฤดูไหนมันก็อร่อยอยู่ดีแหละ"
#โมริโนะ คิริง

/人◕ ‿‿ ◕人\

"ต่อให้เป็นของที่อร่อยแค่ไหนหากกินทุกวันก็ต้องเบื่อ"#อาซึมะ คาซึมะ


<<-- รวมคำแปลวลีเด็ดจากญี่ปุ่น -->>


นอกจากนี้ยังมี .children ซึ่งคล้าย .contents แต่จะออกมาเป็นในรูปแบบของอิเทอเรเตอร์ เหมาะสำหรับใช้ในวังวน for หรือถ้าจะแสดงทั้งหมดทันทีก็แปลงเป็นลิสต์
print(sup.find(id='wali1').children)
# ได้ <list_iterator object at 0x180f38d2e8>
print(list(sup.find(id='wali1').children))
# ได้ ['\n', <a href="walidet/946641382021300"><img  src="rup/rupprakopwalidet/946641382021300.jpg"/></a>, '\n',  <h4  class="khokhwam">"ของอร่อยแบบนี้ไม่ว่าจะฤดูไหนมันก็อร่อยอยู่ดีแหละ"</h4>,  '\n', <span class="chue kirin">#โมริโนะ คิริง</span>, '\n']


แท็กลูกและแท็กพ่อแม่
.contents หรือ .children จะแสดงแค่ส่วนประกอบที่อยู่ด้านในแท็กนั้นโดยตรง แต่ถ้าเป็น .descendants จะแสดงแท็กย่อยทั้งหมดไล่เรียงไปเลย โดยจะอยู่ในรูปของเจเนอเรเตอร์
print(len(list(sup.body.children))) # ได้ 5
print(len(list(sup.body.descendants))) # ได้ 46

a = sup.find(id='wali2').a
print(a)
for d in a.descendants:
    print(d.name)

ได้
<a href="walidet/1793364814015615"><img src="rup/rupprakopwalidet/1793364814015615.jpg"/><h4  class="khokhwam">"ต่อให้เป็นของที่อร่อยแค่ไหนหากกินทุกวันก็ต้องเบื่อ"</h4><span  class="chue kazuma">#อาซึมะ คาซึมะ</span></a>
img
h4
None
span
None

ในทางกลับกันหากต้องการแสดงแท็กพ่อแม่ของแท็กนั้นๆก็ทำได้โดยเติม .parent
print(sup.body.parent.name) # ได้ html
print(sup.html.parent.name) # ได้ [document]

หรือถ้าใช้ .parents จะได้แท็กที่อยู่ขั้นสูงไล่ขึ้นไปเรื่อยๆทั้งหมด
print([p.name for p in sup.find(id='wali1').parents])
# ได้ ['div', 'body', 'html', '[document]']

นอกจากนี้ยังมี .next_sibling, .previous_sibling, .next_siblings, .previous_siblings, .next_element, .previous_element, .next_elements, .previous_elements ที่เอาไว้ดูส่วนประกอบที่อยู่ถัดไปหรือก่อนหน้า

previous_ คือหาตัวก่อนหน้า next_ คือหาตัวที่อยู่ถัดไป กลุ่ม _sibling นั้นจะหาแท็กที่เป็นชนิดเดียวกัน ส่วนกลุ่ม _element จะหาส่วนประกอบใดๆที่อยู่ในระดับชั้นเดียวกัน สำหรับพวกที่มี s ต่อท้ายจะเป็นการหาทั้งหมด ส่วนที่ไม่มี s คือหาตัวเดียว



ใช้เรกูลาร์เอ็กซ์เพรชชัน
การค้นหาภายในนี้สามารถใช้เรกูลาร์เอ็กซ์เพรชชันได้ด้วย โดยใช้คำสั่ง re.compile

เรื่องการเขียนเรกูลาร์เอ็กซ์เพรชชัน มีเขียนถึงไว้แล้ว อ่านรายละเอียดได้ใน https://phyblas.hinaboshi.com/20160922

เช่นหาแท็กที่ชื่อชนิดมีตัว h ตามด้วยตัวเลข ได้แก่พวก h3 h4 ก็อาจเขียนแบบนี้
print(sup.find_all(re.compile(r'h\d')))
# ได้ [<h3>ว่าด้วยเรื่องของอาหย่อย</h3>, <h4 class="khokhwam">"ของอร่อยแบบนี้ไม่ว่าจะฤดูไหนมันก็อร่อยอยู่ดีแหละ"</h4>, <h4 class="khokhwam">"ต่อให้เป็นของที่อร่อยแค่ไหนหากกินทุกวันก็ต้องเบื่อ"</h4>]

หรือหาแท็กที่มี id ขึ้นต้นด้วย w
ww = sup.find_all(id=re.compile(r'w.+'))
print([w['id'] for w in ww]) # ได้ ['wali1', 'wali2']


การเขียนทับแก้ไขเนื้อหาข้างใน
ด้วยวิธีต่างๆที่กล่าวมานี้ นอกจากเราจะสามารถสืบค้นเนื้อหาได้แล้ว ยังสามารถแก้ไขเนื้อหาได้โดยตรงอีกด้วย โดยการใช้ = เพื่อป้อนค่าใหม่เข้าไปเลย ค่าที่แก้จะถูกนำไปแทนที่ทันที

แอตทริบิวต์ที่มีอยู่เขียนทับลงไปได้เลย หรือถ้าจะลบก็ใช้ del
print(sup.p)
# ได้ <p align="center"><a href="https://hinaboshi.com">&lt;&lt;-- รวมคำแปลวลีเด็ดจากญี่ปุ่น --&gt;&gt;</a></p>
sup.p['align'] = 'right'
print(sup.p)
# ได้ <p align="right"><a href="https://hinaboshi.com">&lt;&lt;-- รวมคำแปลวลีเด็ดจากญี่ปุ่น --&gt;&gt;</a></p>
del sup.p['align']
print(sup.p)
# ได้ <p><a href="https://hinaboshi.com">&lt;&lt;-- รวมคำแปลวลีเด็ดจากญี่ปุ่น --&gt;&gt;</a></p>


แอตทริบิวต์ที่ไม่มีจะใส่เพิ่มเข้าไปก็ได้
print(sup.a)
# ได้ <a href="walidet/946641382021300"><img src="rup/rupprakopwalidet/946641382021300.jpg"/></a>
sup.a['target'] = '_blank'
print(sup.a)
# ได้ <a href="walidet/946641382021300" target="_blank"><img src="rup/rupprakopwalidet/946641382021300.jpg"/></a>

สำหรับการลบแท็กให้ใช้เมธอด .unwrap() แต่ว่าเนื้อหาข้างในจะยังอยู่
print(sup.p)
# ได้ <p><a href="https://hinaboshi.com">&lt;&lt;-- รวมคำแปลวลีเด็ดจากญี่ปุ่น --&gt;&gt;</a></p>
sup.p.a.unwrap()
print(sup.p)
# ได้ <p>&lt;&lt;-- รวมคำแปลวลีเด็ดจากญี่ปุ่น --&gt;&gt;</p>

ถ้าจะลบเนื้อหาข้างในทั้งหมดก็อาจเข้าไปที่ .contents แล้วใส่ลิสต์ว่างไป ทั้งแท็กย่อยหรือข้อความก็จะหายหมด
sup.p.contents = []
print(sup.p) # ได้ <p></p>

ดังนั้นถ้าทำแบบนี้
sup.head.contents = []
sup.body.contents = []
sup.style.contents = []
print(sup)

แบบนี้หน้าเว็บของเราก็จะเหลือแต่ความว่างเปล่าแบบนี้
<html>
<head></head>
<body></body>
<style></style>
</html>


ตัวอย่างง่ายๆ
การใช้งานที่มักพบบ่อยก็คือใช้เพื่อค้นหา url ของรูปภาพที่ต้องการจากนห้าเว็บแล้วทำการโหลด

เช่นลองทำการโหลดรูปภาพสองรูปที่เป็นรูปประกอบวลีเด็ดอาจทำได้ดังนี้
url_naweb = 'https://hinaboshi.com/súpđẹp.html'
r = requests.get(url_naweb)
r.encoding = 'utf-8'
sup = BeautifulSoup(r.text,'lxml')
for klong in sup(class_='klonglek'):
    src = klong.img['src']
    chue_file = src.split('/')[-1]
    url_file = 'https://hinaboshi.com/'+src
    with open(chue_file,'wb') as f:
        f.write(requests.get(url_file).content)

ที่ควรระวังอย่างหนึ่งคือ url รูปที่อยู่ในเว็บนั้นมักจะเป็น url สัมพัทธ์สำหรับโยงภายในเว็บเพราะรูปมักจะฝากอยู่ในตัวเว็บเอง ดังนั้นต้องเติมชื่อเว็บไปข้างหน้าอีกทีจึงจะเป็น url เต็มจริงๆที่ต้องการเพื่อใช้โหลดรูป



beautifulsoup ยังมีรายละเอียดปลีกย่อยอื่นๆอีกพอสมควร แต่ในที่นี้แค่ยกตัวอย่างการใช้งานที่ใช้บ่อยเท่านั้น สำหรับรายละเอียดเพิ่มเติมกว่านี้ให้อ่านในเว็บทางการเอาได้

ภาษาอังกฤษ
https://www.crummy.com/software/BeautifulSoup/bs4/doc
ภาษาจีน
http://beautifulsoup.readthedocs.io/zh_CN/stable
ภาษาญี่ปุ่น
http://kondou.com/BS4

แหล่งอ้างอิงอื่นๆ
https://qiita.com/itkr/items/513318a9b5b92bd56185
https://qiita.com/neet-AI/items/d434f3a96223c12fbdd3
https://morvanzhou.github.io/tutorials/data-manipulation/scraping/2-01-beautifulsoup-basic


-----------------------------------------

囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧

ดูสถิติของหน้านี้

หมวดหมู่

-- คอมพิวเตอร์ >> เขียนโปรแกรม >> python

ไม่อนุญาตให้นำเนื้อหาของบทความไปลงที่อื่นโดยไม่ได้ขออนุญาตโดยเด็ดขาด หากต้องการนำบางส่วนไปลงสามารถทำได้โดยต้องไม่ใช่การก๊อปแปะแต่ให้เปลี่ยนคำพูดเป็นของตัวเอง หรือไม่ก็เขียนในลักษณะการยกข้อความอ้างอิง และไม่ว่ากรณีไหนก็ตาม ต้องให้เครดิตพร้อมใส่ลิงก์ของทุกบทความที่มีการใช้เนื้อหาเสมอ

สารบัญ

รวมคำแปลวลีเด็ดจากญี่ปุ่น
มอดูลต่างๆ
-- numpy
-- matplotlib

-- pandas
-- manim
-- opencv
-- pyqt
-- pytorch
การเรียนรู้ของเครื่อง
-- โครงข่าย
     ประสาทเทียม
maya
javascript
ความน่าจะเป็น
บันทึกในญี่ปุ่น
บันทึกในจีน
-- บันทึกในปักกิ่ง
-- บันทึกในฮ่องกง
-- บันทึกในมาเก๊า
บันทึกในไต้หวัน
บันทึกในยุโรปเหนือ
บันทึกในประเทศอื่นๆ
เรียนภาษาจีน
qiita
บทความอื่นๆ

บทความแบ่งตามหมวด



ติดตามอัปเดตของบล็อกได้ที่แฟนเพจ

  ค้นหาบทความ

  บทความแนะนำ

การสร้างแบบจำลองสามมิติเป็นไฟล์ .obj วิธีการอย่างง่ายที่ไม่ว่าใครก็ลองทำได้ทันที
รวมรายชื่อนักร้องเพลงกวางตุ้ง
ภาษาจีนแบ่งเป็นสำเนียงอะไรบ้าง มีความแตกต่างกันมากแค่ไหน
ทำความเข้าใจระบอบประชาธิปไตยจากประวัติศาสตร์ความเป็นมา
เรียนรู้วิธีการใช้ regular expression (regex)
หลักการเขียนทับศัพท์ภาษาจีนกวางตุ้ง
การใช้ unix shell เบื้องต้น ใน linux และ mac
หลักการเขียนทับศัพท์ภาษาจีนกลาง
g ในภาษาญี่ปุ่นออกเสียง "ก" หรือ "ง" กันแน่
ทำความรู้จักกับปัญญาประดิษฐ์และการเรียนรู้ของเครื่อง
ค้นพบระบบดาวเคราะห์ ๘ ดวง เบื้องหลังความสำเร็จคือปัญญาประดิษฐ์ (AI)
หอดูดาวโบราณปักกิ่ง ตอนที่ ๑: แท่นสังเกตการณ์และสวนดอกไม้
พิพิธภัณฑ์สถาปัตยกรรมโบราณปักกิ่ง
เที่ยวเมืองตานตง ล่องเรือในน่านน้ำเกาหลีเหนือ
บันทึกการเที่ยวสวีเดน 1-12 พ.ค. 2014
แนะนำองค์การวิจัยและพัฒนาการสำรวจอวกาศญี่ปุ่น (JAXA)
เล่าประสบการณ์ค่ายอบรมวิชาการทางดาราศาสตร์โดยโซวเคนได 10 - 16 พ.ย. 2013
ตระเวนเที่ยวตามรอยฉากของอนิเมะในญี่ปุ่น
เที่ยวชมหอดูดาวที่ฐานสังเกตการณ์ซิงหลง
บันทึกการเที่ยวญี่ปุ่นครั้งแรกในชีวิต - ทุกอย่างเริ่มต้นที่สนามบินนานาชาติคันไซ
หลักการเขียนทับศัพท์ภาษาญี่ปุ่น
ทำไมจึงไม่ควรเขียนวรรณยุกต์เวลาทับศัพท์ภาษาต่างประเทศ
ทำไมถึงอยากมาเรียนต่อนอก
เหตุผลอะไรที่ต้องใช้ภาษาวิบัติ?

ไทย

日本語

中文