ในตอนที่แล้วได้แนะนำการดึงข้อมูลจากหน้าเว็บมาแล้ว
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"><<-- รวมคำแปลวลีเด็ดจากญี่ปุ่น -->></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">
<<-- รวมคำแปลวลีเด็ดจากญี่ปุ่น -->>
</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"><<-- รวมคำแปลวลีเด็ดจากญี่ปุ่น -->></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"><<-- รวมคำแปลวลีเด็ดจากญี่ปุ่น -->></a></p>
sup.p['align'] = 'right'
print(sup.p)
# ได้ <p align="right"><a href="https://hinaboshi.com"><<-- รวมคำแปลวลีเด็ดจากญี่ปุ่น -->></a></p>
del sup.p['align']
print(sup.p)
# ได้ <p><a href="https://hinaboshi.com"><<-- รวมคำแปลวลีเด็ดจากญี่ปุ่น -->></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"><<-- รวมคำแปลวลีเด็ดจากญี่ปุ่น -->></a></p>
sup.p.a.unwrap()
print(sup.p)
# ได้ <p><<-- รวมคำแปลวลีเด็ดจากญี่ปุ่น -->></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