top of page

2023 Web Scraping Guideline เก็บข้อมูลจากหน้าเวป ลง Excel ด้วย Python ได้ในบทเรียนเดียว!

Updated: Nov 23, 2022

ในปัจจุบันข้อมูลที่มีอยู่มากมายบนเวปไซต์ต่างๆ กำลังกลายเป็นหนึ่งในแหล่งข้อมูลที่สำคัญที่ช่วยสร้างความได้เปรียบทางด้านข้อมูล ทำให้การตัดสินใจต่างๆ ทำได้อย่างมีประสิทธิภาพมากยิ่งขึ้น เช่น การเก็บข้อมูลตลาด E-Commerce เพื่อเรียนรู้สินค้าขายดี หรือ ข้อมูลลูกค้าบน Social Media ที่บ่งบอกถึง Insight ของกลุ่มลูกค้า จะดีกว่าไหม ถ้าเราสามารถเก็บข้อมูลจำนวนมากนี้ จัดการให้อยู่ในรูปแบบที่ใช้งานได้ง่าย และนี่คือ สิ่งที่ Web Scraping ช่วยทำให้เกิดขึ้นได้!


วันนี้ซิปป้าได้เรียบเรียงขั้นตอนการทำ Web Scraping ด้วย Python เอาไว้ เป็น Guideline สำหรับทุกคนที่สนใจทำ Web Scraping เพื่อนำข้อมูลจากเวปไซต์ต่างๆ มาสร้างความได้เปรียบทางด้านข้อมูล ที่ทำตามแล้วได้ผลงานทันที และถ้าทำตัวอย่างนี้ได้ สามารถทำได้กับทุกเวปไซต์เลย! เป็นยังไงมาดูกัน!



 


หัวข้อในบทความนี้


 

Web Scraping เทคนิคการดึงข้อมูลจากหน้าเวป


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


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


องค์ประกอบข้อมูล website ประกอบไปด้วย 2 อย่าง

  1. ข้อมูลส่วนต่างๆ ที่นำมาประกอบบนหน้าเวป ไม่ว่าจะเป็นข้อความ, ลิ้งค์, ภาพ หรือข้อมูลอื่นๆ

  2. HTML หรือโค้ดที่นำข้อมูลต่างๆ มาแปะในจุดต่างๆ ที่จะเป็นโค้ดที่ตัว browser นำมาใช้เพื่อกำหนดตำแหน่งต่างๆ ของข้อมูล

โดย Web Scraping คือ เทคนิคในการทำความเข้าใจตัวพื้นฐานของ HTML ของเวปไซต์ และใช้คำสั่งเพื่อดึงข้อมูลที่ต้องการที่อยู่ใน HTML ออกมา


 

HTML และ HTML Tag


HTML Tag เป็นส่วนย่อยของโค้ด HTML ซึ่งทำหน้าที่เป็นเหมือนโฟลเดอร์ ที่ใช้เก็บข้อมูลต่างๆ เอาไว้ โดยมีโครงสร้างที่ซ้อนๆ กันในลักษณะเดียวกันกับโฟลเดอร์บนคอมพิวเตอร์ ซึ่งในการดึงข้อมูลที่ต้องการ จะต้องอาศัยการระบุตำแหน่งของ HTML Tag ที่ต้องการ ผ่านการระบุรายละเอียดของ HTML Tag ที่ต้องการ ที่ประกอบด้วย ชื่อ และ attribute ต่างๆ


โดยหลักการที่สำคัญที่สุดในการทำ Web Scraping คือ การระบุตำแหน่งที่อยู่ของ HTML Tag ที่เก็บข้อมูลเอาไว้ ให้ Python หรือเครื่องมือที่กำลังใช้งาน สามารถเข้าไปยังตำแหน่งของ Tag ที่ต้องการ ก่อนที่จะส่งคำสั่งดึงข้อมูลจากตำแหน่งนั้นออกมา และนำไปจัดรูปแบบให้อยู่ในรูปแบบตารางต่อไป


โดยใน HTML Tag ใดๆ จะมีข้อมูลเบื้องต้นอยู่ 3 อย่างที่ประกอบไปด้วย

  1. ชื่อ Tag โดยจะเป็นข้อมูลแรกที่เห็นอยู่ด้านซ้ายสุดของ Tag

  2. ชื่อ Attribute โดยจะเป็นข้อมูลที่เขียนไว้หน้า = ซึ่ง Attribute เป็นเหมือนค่าต่างๆ ที่สามารถใช้เพื่อตั้งค่าการทำงานของ Tag นั้นๆ

  3. Value ของ Attribute ใดๆ โดยจะระบุหลัง = คู่กับ Attribute เป็นค่าที่มีการตั้งไว้แตกต่างกัน เพื่อบันทึกข้อมูลที่แตกต่างกัน

โดยข้อมูลของ 1) ชื่อ Tag จะต้องมีอยู่ในทุก Tag แต่ 2) Attribute และ 3) Value ของ Attribute จะมีหรือไม่มีก็ได้ แล้วแต่ Tag


 

เริ่มต้นที่ Request-Response Cycle

ในการทำ Web Scraping เริ่มต้นจากการส่งคำสั่งเพื่อขอข้อมูลจากเวปไซต์มาใช้งานกับ Python โดยเราจะทำการเลียนแบบกระบวนการที่เรียกว่า request-response cycle หรือคือการขอข้อมูลของ website จาก server นั่นเอง


โดย request คือ กระบวนการขอข้อมูลจาก server ที่เปรียบเสมือนเวลาที่เรานำลิ้งค์ของ website ไปวางในช่อง url หรือ เวลาที่เรากดลิ้งค์ของ website


และ response คือ กระบวนการส่งข้อมูลจาก server กลับมายัง browser ของเรา โดย browser จะทำการตีความข้อมูลที่ได้รับโดยเฉพาะ HTML ที่ browser จะอ่านโค้ด HTML แล้ว นำข้อมูลที่ได้รับมาเรียงกันเป็นหน้าเวปที่สวยงาม


ติดตั้ง และนำคำสั่ง requests มาใช้

requests เป็นชุดคำสั่งที่รวมคำสั่งสำหรับการส่งคำสั่งทำงานกับ server เพื่อทำงานกับข้อมูลของเวปไซต์ โดยเราจะใช้เพื่อขอข้อมูลของเวปไซต์ที่ต้องการ


สำหรับ requests เป็น Library หรือชุดคำสั่งสำเร็จรูปซึ่งหากเราต้องการใช้งานจะต้องติดตั้งผ่าน !pip install บน Jupyter Notebook โดยการติดตั้งทำครั้งเดียวเพื่อดาวน์โหลดคำสั่งนี้มาบันทึกไว้บนคอมพิวเตอร์


In [1]:
!pip install requests

หากมีการติดตั้งเรียบร้อยจะมีข้อความแจ้งประมาณนี้ที่บอกว่า Requirement already satisfied อาจมีรายละเอียดที่แตกต่างกันไปบ้าง หากยังไม่เคยติดตั้งจะปรากฏเป็นหลอดแสดงเปอร์เซ็นต์การดาวน์โหลด


Requirement already satisfied: requests ...

เมื่อมีคำสั่ง requests แล้วจะต้องมีการนำเข้าคำสั่ง requests มาใช้งาน ต้องทำทุกครั้งเมื่อเปิดไฟล์คำสั่งเมื่อต้องการใช้งาน


In [2]:
import requests

requests ข้อมูลจากเวปไซต์ที่ต้องการ

การขอข้อมูลจากเวปไซต์ที่ต้องการจะทำผ่านคำสั่ง requests.get() ที่ระบุตัว url ของเวปไซต์เป็น string object ใส่เป็น argument โดยจะได้ข้อมูลออกมาเป็น response object ที่มี HTTP Code กำกับ สำหรับเวปไซต์ที่มีการส่งข้อมูลกลับมาเรียบร้อยจะมี HTTP Code 200 ส่งกลับมา


สร้าง string object ที่เก็บลิ้งค์ที่ต้องการขอข้อมูลไว้ในตัวแปร url


In [3]:
url = 'https://www.checkraka.com/house/quicksearch_order=update%2CDESC&page=1'
url

ใช้คำสั่ง requests.get() ระบุเวปไซต์ที่ต้องการเป็น argument เพื่อ request ข้อมูล โดยจะได้ข้อมูลมาในรูปแบบของ response object


In [4]:
data = requests.get(url)
data
Out [4]:
<Response [200]>    

ข้อมูลที่ได้จากการ request ข้อมูล


สำหรับ response object ที่ได้รับมาหลังรันคำสั่ง requests.get() จะใช้คำสั่ง .text เพื่อดึง HTML ของเวปไซต์ที่ได้รับมาให้ออกมาอยู่ใน string object เพื่อนำไปใช้งานต่อ


สำหรับเวปไซต์ใดๆ ก็ตามที่จะนำมาทำงานด้วยในลักษณะนี้ จะต้องเช็คก่อนว่า ข้อมูลที่เราต้องการนั้นอยู่ใน HTML ที่ปรากฏขึ้นมาหรือไม่ โดยการใช้ search ง่ายๆ ผ่าน browser หรือ กด ctrl + f


เพราะสำหรับการทำงานของบาง website จะไม่สามารถทำการขอข้อมูลลักษณะนี้ เพื่อให้ได้ข้อมูลที่พร้อมใช้ ซึ่งจะเหมาะกับชุดคำสั่งในรูปแบบอื่นๆ


In [5]:
data.text
Out [5]:
'\t<!DOCTYPE html>\r\n<html lang="th">\r\n<head>\r\n\t<title>บ้านใหม่ทุกโครงการ เรียงตามข้อมูลล่าสุด หน้าละ 10 โครงการ ราคา-โปรโมชั่นล่าสุด | เช็คราคา.คอม</title>...</html>'

เมื่อเช็คเรียบร้อยว่ามีข้อมูลที่กำลังต้องการดึงจากเวปไซต์ในข้อมูลที่ได้มาจาก response object เราก็จะได้ HTML ที่พร้อมสำหรับการทำ Web Scraping แล้ว


 

ดึงข้อมูลด้วย BeautifulSoup


เมื่อได้ HTML ที่พร้อมใช้จากการทำ requests.get() มาแล้ว เราจะนำ HTML นี้มาใช้งานกับชุดคำสั่ง BeautifulSoup ที่จะช่วยแปลงข้อมูลเป็น object ที่เหมาะกับการทำ web scraping ที่รวบรวมคำสั่งเพื่อการระบุตำแหน่งของ Tag ที่เราต้องการดึงข้อมูลให้ง่ายกว่าการทำงานกับ string object


ติดตั้ง และนำคำสั่ง BeautifulSoup มาใช้

ติดตั้งผ่าน !pip install เช่นเดียวกัน และหากมีการติดตั้งไว้เรียบร้อยแล้วจะมีข้อความแจ้งประมาณว่า Requirement already satisfied ที่อาจมีรายละเอียดต่างจากตัวอย่างบ้าง แต่หากยังไม่เคยติดตั้ง จะมีแถบดาวน์โหลดข้อมูลขึ้นมา


In [6]:
!pip install bs4
Requirement already satisfied: bs4 ...

เช่นเดียวกันคำสั่ง bs4 เมื่อต้องการนำมาใช้งาน จะต้อง import เข้ามา ในทุกครั้งที่เปิด Jupyter Notebook ขึ้นมาใหม่


แปลง HTML ที่อยู่ในรูปแบบของ String เป็น Beautifulsoup

สำหรับการจัดการข้อมูล HTML โดยเฉพาะการทำ web scraping การใช้งาน BeautifulSoup object จะช่วยให้เราสามารถเข้าถึงคำสั่งในการดึงข้อมูลที่ต้องการได้ง่ายๆ ใช้เพียงไม่กี่คำสั่ง ซึ่งจะง่ายกว่าการดึงข้อมูลจาก HTML ที่อยู่ในรูปแบบของ String


โดยการแปลงข้อมูล HTML ที่อยู่ในรูปแบบของ String ให้เป็น BeautifulSoup Object ทำได้ผ่านคำสั่ง bs4.BeautifulSoup() ที่รับ HTML ที่อยู่ในรูปแบบ String และสร้างข้อมูลใหม่เป็น BeautifulSoup Object ที่เก็บข้อมูล HTML เอาไว้


การแปลงข้อมูล HTML ที่อยู่ในรูปแบบของ String เป็น BeautifulSoup Object ด้วยคำสั่ง bs4.BeautifulSoup() เราจะได้ HTML ที่เก็บอยู่ใน BeautifulSoup Object


In [7]:
soup = bs4.BeautifulSoup(data.text)
soup
Out [7]:
<!DOCTYPE html>
<html lang="th">
<head>
<title>บ้านใหม่ทุกโครงการ เรียงตามข้อมูลล่าสุด หน้าละ 10 โครงการ ราคา-โปรโมชั่นล่าสุด | เช็คราคา.คอม</title>
...
</body>
</html>

เมื่อ HTML ที่พร้อมใช้อยู่ในรูปแบบของ BeautifulSoup Object แล้ว เราจะสามารถใช้คำสั่งต่างๆ เพื่อทำการระบุข้อมูลที่อยู่ใน HTML ออกมาได้อย่างแม่นยำ และตรงกับข้อมูลที่ต้องการได้ง่าย


 

การค้นหา "Tag ที่เก็บ 1 รายการ" เอาไว้


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


โดยหลักการหา "Tag ที่เก็บ 1 รายการ" ให้เจอ ต้องเล่าย้อนไปถึงการเลือกหน้าเวปไซต์ที่เหมาะกับการดึงข้อมูลหรือทำ web scraping นั่นคือหน้าเวปที่มีการแสดงข้อมูลใน pattern หน้าตาซ้ำๆ อย่างเวป E-Commerce ที่มีหลายๆ สินค้าเรียบเรียงกันใน 1 หน้า, Social Media ที่มีโพสท์/ข้อความแต่ละอันเรียบเรียงกันด้วยโครงสร้างซ้ำๆ เดิม หรือเวปเปรียบเทียบราคาที่ใช้เป็นตัวอย่าง ที่มีการแสดงข้อมูลแต่ละสินค้าอยู่ในโครงสร้างคล้ายๆกัน


หน้าเวปไซต์เหล่านี้มักมีการใช้โครงสร้างของโค้ด หรือ HTML ที่มีลักษณะซ้ำๆ กันเช่นเดียวกัน ทำให้เราสามารถเลือก "Tag ที่เก็บ 1 รายการ" ระบุรายละเอียดของ Tag นั้น และใช้คำสั่งเพื่อดึงข้อมูลที่มีโครงสร้าง Tag คล้ายๆ กัน เพื่อดึงข้อมูลจากทุกรายการออกมาได้ในภายหลัง


โดย "Tag ที่เก็บ 1 รายการ" จะเป็น Tag ที่เมื่อระบุได้เหมาะสมจะต้องมีคุณสมบัติอยู่ 2 อย่าง
  1. จะต้องครอบคลุมพื้นที่การแสดงผลของข้อมูล 1 รายการ ที่เปรียบเทียบอยู่กับข้อมูลทั้งหมดในหน้าเวปนั้น

  2. ข้อมูลที่เหมาะสมจะมีโครงสร้างที่เหมือนกันในทุกรายการ สามารถใช้รายละเอียดเดียว ดึงข้อมูลได้ทุกรายการ


และการระบุ Tag ที่ต้องการเราจะระบุข้อมูล 3 อย่างได้แก่
  1. ชื่อ Tag

  2. Attribute ที่ต้องการระบุ

  3. Value ของ Attribute นั้นๆ

In [8]:
all_unit_tag = 'div'
all_unit_attribute = 'class'
all_unit_value = 'content c44'

ค้นหา Tag ที่ต้องการ ด้วย .find()

เมื่อได้รายละเอียดของ "Tag ที่เก็บ 1 รายการ" แล้ว เราจะทำการให้ Python เข้าไปค้นหา Tag นั้นจากข้อมูลจากทั้งเวป หรือข้อมูล HTML ที่อยู่ใน BeautifulSoup Object นั่นเอง ผ่านคำสั่ง .find() ที่จะมีการค้นหา Tag ตามรายละเอียดที่กำหนด โดยจะเลือกหยิบ Tag แรกที่เจอ โดยมีลำดับการค้นหาจาก Tag ที่อยู่ด้านบนของ HTML ทั้งหมดไล่ลงมาด้านล่าง โดยเราจะกำหนดรายละเอียดของ Tag ทั้ง 3 อย่างในลักษณะนี้ (ชื่อ tag, {ชื่อ attribute:ค่า attribute}) และนำข้อมูลนี้กำหนดเป็น argument สำหรับคำสั่ง .find()


โดยจะได้ข้อมูลเป็น HTML แค่ในส่วนที่ตรงกับรายละเอียดของ Tag ที่ต้องการ หรือการตัด HTML มาแค่ส่วนที่ค้นหานั่นเอง ซึ่งทำให้การจัดการกับข้อมูลง่ายขึ้น แทนที่จะต้องทำงานกับข้อมูลทั้งเวปไซต์ ก็จะเหลือการทำงานกับข้อมูลแค่ส่วนที่เป็น 1 ข้อมูล


In [9]:
first_unit_element = soup.find(all_unit_tag,{all_unit_attribute:all_unit_value})
first_unit_element
<div class="content c44">
...
<div class="name"><a href="/house/sansiri/siri-place/1450457/" target="_blank">สิริ เพลส แอร์พอร์ต ภูเก็ต (Siri Place Airport)</a></div>
...
</li>
</ul>
</div>

เมื่อเราได้ข้อมูล Tag ที่เก็บ 1 รายการเอาไว้ เราก็จะนำข้อมูลนี้ไปสกัดหาข้อมูลที่เป็นส่วนประกอบของ 1 รายการต่อไป เช่น ชื่อสินค้า และราคา


 

ค้นหา Tag ที่เก็บข้อมูลที่ต้องการใน "Tag ที่เก็บ 1 รายการ"


เมื่อได้ข้อมูล Tag ที่เก็บ 1 รายการมาเรียบร้อย เราจะทำการระบุข้อมูลส่วนที่ต้องการจากข้อมูลทั้งหมด เช่น ชื่อสินค้า จากสินค้า 1 รายการ ซึ่งเราสามารถทำได้ในลักษณะเดียวกันกับการดึง 1 รายการจาก เวปไซต์ ผ่านคำสั่ง .find()


โดยเริ่มต้นจากการค้นหา 1) ชื่อ Tag 2) Attribute 3) และ Value ของ Attribute ที่เหมาะสม ที่ครอบคลุมพื้นที่การแสดงผลของข้อมูลที่ต้องการดึง และมีโครงสร้างที่เหมือนกันในแต่ละข้อมูล สามารถใช้รายละเอียดเดียว ข้อมูลที่ต้องการได้จากทุกข้อมูล


กำหนดรายละเอียด Tag สำหรับชื่อรายการสินค้า

ซึ่ง Tag ที่ต้องการ อาจมีแค่ชื่อ Tag โดยไม่มี Attribute และ Value ของ Attribute ที่เหมาะสมก็ได้


In [10]:
title_tag = 'a'

ค้นหา Tag จากใน Tag ของ 1 รายการสินค้า

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


และผลลัพธ์ที่ได้ เราจะได้ข้อมูลเป็นส่วนที่ย่อยลงจาก Tag ที่เก็บ 1 รายการมาอีกที ทำให้เราได้ข้อมูลที่ตรงกับที่ต้องการมากยิ่งขึ้น โดยข้อมูลนี้จะยังอยู่ใน Tag Object ที่จะต้องส่งคำสั่งสกัดข้อมูลออกมาอีกครั้ง


In [11]:
first_name_element = first_unit_element.find(title_tag)
first_name_element
Out [11]:
<a href="/house/sansiri/siri-place/1450457/" target="_blank">สิริ เพลส แอร์พอร์ต ภูเก็ต (Siri Place Airport)</a>

สกัดข้อมูลที่ต้องการออกจาก Tag

เมื่อได้ Tag ที่เก็บข้อมูลของ 1 รายการ ที่ต้องการไว้เรียบร้อย เราจะใช้คำสั่งต่างๆ เพื่อดึงข้อมูลออกมาจาก Tag โดยหากข้อมูลที่เก็บอยู่เป็นข้อมูลที่เป็น Text หรือข้อความ ที่เราสามารถ copy จากหน้าเวปผ่านการลากเมาส์ครอบ แล้ว copy ออกมาได้ เราจะใช้คำสั่ง .text เพื่อดึงข้อมูลส่วนนั้นออกมาให้อยู่ในรูปแบบของ String Object


In [12]:
first_name_element.text
Out [12]:
'สิริ เพลส แอร์พอร์ต ภูเก็ต (Siri Place Airport)'

 

การค้นหาข้อมูลเพิ่มเติมจาก 1 รายการ


ใน Tag ที่เก็บ 1 รายการไม่ได้มีเพียงแค่ข้อมูลอย่างเดียว แต่ประกอบไปด้วยข้อมูลหลายอย่างของสินค้าใน 1 รายการนั้น ซึ่งเมื่อนำไปใช้จริง หากต้องการดึงข้อมูลหลายอย่างออกมา เราจะใช้การดึงข้อมูลทีละอย่าง ผ่านการระบุ 1) ชื่อ Tag 2) Attribute 3) Value ของ Attribute จนครบข้อมูลที่ต้องการ


กำหนดรายละเอียด Tag สำหรับราคารายการสินค้า

สำหรับข้อมูลตัวอย่างเราจะดึงข้อมูลราคามาเพิ่มเติม ซึ่งเช่นเดียวกันป็นการดึงข้อมูลชื่อรายการสินค้า เราจะระบุรายละเอียดที่เหมาะสมก่อน


In [13]:
price_tag = 'div'
price_attribute = 'class'
price_value = 'price'

ดึง Tag ที่ต้องการจาก Tag รายการสินค้า

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


In [14]:
first_price_element = first_unit_element.find(price_tag,{price_attribute:price_value})
first_price_element
Out [14]:
<div class="price">เริ่มต้น 1.99 ลบ. <span>(ณ. วันที่ 25/7/2022)</span></div>

เทคนิคการสกัดข้อความให้ได้แค่ส่วนใน Tag ปัจจุบัน

สำหรับ Tag ที่เลือกมา จะสังเกตเห็นว่าข้อความที่เก็บอยู่ใน Tag มีแค่บางส่วนเท่านั้นที่เป็นข้อมูลที่ตรงกับสิ่งที่ต้องการ หรือคือเป็นราคา ซึ่งข้อมูลที่ต้องการอยู่ในส่วนของ Tag ที่ดึงมา ไม่รวมส่วนของข้อความที่อยู่ใน Tag ที่อยู่ใน Tag ที่เลือกมาอีกที (Tag ที่ชื่อว่า span) สำหรับกรณีนี้ เราสามารถดึงข้อความจาก Tag ปัจจุบันอย่างเดียว โดยไม่ดึงข้อความอื่นๆ ใน Tag ออกมาได้ด้วยคำสั่ง .find() โดย กำหนด text=True เพื่อดึงข้อความเฉพาะส่วนที่สนใจ


In [15]:
first_price_element.find(text=True)
Out [15]:
'เริ่มต้น 1.99 ลบ. '

เมื่อสามารถระบุข้อมูลทุกอย่างที่ต้องการได้จาก 1 รายการ เราจะทำการบันทึกข้อมูลเหล่านี้ลงใน Dictionary ซึ่งข้อมูลใน 1 Dictionary จะกลายเป็นข้อมูล 1 แถวที่เราจะรวบรวมขึ้นเป็นตารางอีกที


 

บันทึกข้อมูล 1 รายการลง Dictionary


Dictionary เป็นโครงสร้างข้อมูลที่มีการเก็บข้อมูลคล้ายคลึงกับการเก็บข้อมูลสำหรับข้อมูล 1 แถว นั่นคือ 1 แถวมีข้อมูลที่หลากหลายจากหลายคอลัมน์ ที่มีความแตกต่างกัน ตามคอมลัมน์ของข้อมูลนั้นๆ


ใน Dictionary ก็จะมีการเก็บข้อมูลที่มีการระบุสิ่งที่เรียกว่า key-value pair สำหรับการบันทึกข้อมูลที่เก็บได้มาคู่กับ key ที่ข้อมูลนี้จะถูกนำไปสร้างเป็นคอลัมน์ในอนาคตนั่นเอง


สร้าง Dictionary สำหรับการบันทึกข้อมูล

โดยการบันทึกข้อมูลลง Dictionary สำหรับเป็นตัวแทนของข้อมูล 1 แถว เริ่มต้นจากการสร้าง Dictionary ที่ไม่มีข้อมูลขึ้นมาก่อน


In [16]:
data_dict = dict()

บันทึกข้อมูลที่ต้องการลง Dictionary ตามข้อมูลที่เก็บมา

และทำการนำข้อมูลที่ดึงมาได้ใส่เข้าไปใน Dictionary โดยมีการกำหนด key ที่ต้องการเก็บข้อมูลนั้นๆ (หรือจินตนาการว่าสิ่งนี้คือ คอลัมน์ของตารางในอนาคต) เช่น ชื่อรายการสินค้าเก็บไว้ใน key ที่ชื่อว่า title และราคาเก็บไว้ใน key ที่ชื่อว่า price จะสามารถเขียนเป็นคำสั่งได้ในลักษณะนี้


In [17]:
data_dict['title'] = first_name_element.text
data_dict['price'] = first_price_element.text

เมื่อบันทึกข้อมูลลง Dictionary แล้ว เราก็จะได้ข้อมูลของ 1 แถวมาเก็บไว้เรียบร้อย


In [18]:
data_dict
Out [18]:
{'title': 'สิริ เพลส แอร์พอร์ต ภูเก็ต (Siri Place Airport)',
 'price': 'เริ่มต้น 1.99 ลบ. (ณ. วันที่ 25/7/2022)'}

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


 

การดึงข้อมูลทุกรายการที่มีอยู่บนหน้าเวป


เมื่อเราสามารถกำหนด Tag ที่เก็บข้อมูล 1 รายการได้เหมาะสม เราสามารถใช้รายละเอียดของ Tag ที่เก็บข้อมูล 1 รายการมาใช้สำหรับการดึงทุกรายการที่อยู่บ้านหน้าเวปได้ผ่านคำสั่ง .find_all() โดยมีการใช้งาน การกำหนด argument ลักษณะเดียวกับการใช้งาน .find()


ดึงทุกรายการด้วย .find_all()

โดยเราจะได้ข้อมูลของทุกรายการมาอยู่ในรูปแบบของ List ที่เก็บ Tag ต่างๆ เอาไว้


In [19]:
all_unit_element = soup.find_all(all_unit_tag,{all_unit_attribute:all_unit_value})
all_unit_element 
Out [19]:
[<div class="content c44">
 ...
 <div class="name"><a href="/house/sansiri/siri-place/1450457/" target="_blank">สิริ เพลส แอร์พอร์ต ภูเก็ต (Siri Place Airport)</a></div>
...
</ul>
</div>]

ใช้ For Loop เข้าไปทำงานกับทีละรายการ ดึงข้อมูล และบันทึกลง List

และเมื่อได้ Tag ที่เก็บข้อมูลแต่ละรายการเอาไว้ เราก็จะทำการดึงข้อมูลทีละรายการออกมา และนำข้อมูลแต่ละรายการมาสกัดหาข้อมูลที่ต้องการนั่น คือ ชื่อสินค้าในแต่ละรายการ และราคาของสินค้าชิ้นนั้น


ซึ่งข้อมูลของสินค้าแต่ละรายการจะถูกบันทึกลง Dictionary เป็นตัวแทนของข้อมูลแต่ละแถว ซึ่งข้อมูลแต่ละแถวต้องถูกบันทึกลงข้อมูล List อีกครั้ง ผ่านการใช้คำสั่ง .append() เพื่อบันทึกข้อมูลแต่ละแถวซ้อนกัน ก่อนนำไปสร้างเป็นตาราง


ดังนั้นการทำงานกับทุกรายการที่อยู่ในรูปแบบของ List จึงต้องมีการสร้าง List ใหม่ที่ไม่มีข้อมูลเพื่อใช้บันทึกข้อมูลของแต่ละรายการที่จะเกิดขึ้น และใช้ For Loop เข้าไปดึงข้อมูลแต่ละรายการออกจาก List ของรายการทั้งหมด


In [20]:
data_list = []
for unit in all_unit_element:
    data_dict = dict()
    data_dict['title'] = unit.find(title_tag).text
    data_dict['price'] = unit.find(price_tag,{price_attribute:price_value}).text
    data_list.append(data_dict)

ข้อมูลสุดท้ายที่จะได้ คือ List ของ Dictionary ที่เก็บข้อมูลทุกรายการไว้ใน List ที่มีแต่ละรายการเก็บไว้ใน Dictionary ซึ่งเป็นรูปแบบที่พร้อมเปลี่ยนให้เป็นตาราง


In [21]:
data_list
Out [21]:
  [{'title': 'สิริ เพลส แอร์พอร์ต ภูเก็ต (Siri Place Airport)',
  'price': 'เริ่มต้น 1.99 ลบ. (ณ. วันที่ 25/7/2022)'},
 ...,
 {'title': 'พฤกษ์ลดา ทางด่วนรามอินทรา-จตุโชติ (Prueklada Ramindra Expressway-Chatuchot)',
  'price': '6 - 9 ลบ. (ณ. วันเปิดตัว)'}]

 

การเข้าถึงทุกหน้าเวปที่อยู่บนเวปไซต์


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


การใช้ While Loop สร้างเงื่อนเปลี่ยนตัวเลข เพื่อใช้สร้างเป็น url

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


In [22]:
page = 1
while page < 369:
    print(page)
    page += 1

เราจะเห็นตัวเลขแสดงขึ้นมาตามการเปลี่ยนแปลงที่เกิดขึ้นใน while loop ซึ่งเราจะนำตัวเลขที่เปลี่ยนแปลงนี้ไปประกอบเป็น url ที่มีการเปลี่ยนหน้าไปเรื่อยๆ


1
2
3
...
368

การประกอบตัวเลขเข้ากับ url เพื่อสร้าง url ของแต่ละหน้า

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


In [23]:
page = 1
while page < 369:
    url = 'https://www.checkraka.com/house/?quicksearch_order=update%2CDESC&page=' + str(page)
    print(url)
    page += 1

While Loop เมื่อใส่คำสั่งในการสร้าง url เข้าไป ก็จะปรากฏเป็นหน้าเวปแต่ละหน้าที่รันเลขตามหน้าเลขจนครบทั้งเวปไซต์



 

การเก็บข้อมูลจากทั้งเวปไซต์


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


ประกอบคำสั่งให้เก็บข้อมูลได้จากทั้งเวปไซต์

โดยส่วนนี้จะมีการจัดเรียงคำสั่งต่างๆ ในส่วนต่างๆ ดังนี้ และเพิ่มส่วนของการ print() ข้อความที่แจ้งว่ากำลังทำงานกับหน้าไหนอยู่เพื่อติดตามผล


In [24]:
#ที่เก็บข้อมูลของทั้งเวปไซต์
data_list = []

#การเข้าถึงลิ้งค์ของทุกเวปไซต์
page = 1
while page < 369:
    url = 'https://www.checkraka.com/house/?quicksearch_order=update%2CDESC&page=' + str(page)
    print(url)
    page += 1
    
    #ดึงข้อมูลของ 1 หน้าเวป
    data = requests.get(url)
    
    #แปลงเป็น BeautifulSoup
    soup = bs4.BeautifulSoup(data.text)
    
    #รายละเอียดข้อมูล 1 รายการ
    all_unit_tag = 'div'
    all_unit_attribute = 'class'
    all_unit_value = 'content c44'
    
    #รายละเอียดข้อมูลชื่อสินค้าในรายการนั้นๆ
    title_tag = 'a'

    #รายละเอียดข้อมูลราคาในสินค้ารายการนั้นๆ
    price_tag = 'div'
    price_attribute = 'class'
    price_value = 'price'
    
    
    #ดึงทุกรายการ
    all_unit_element = soup.find_all(all_unit_tag,{all_unit_attribute:all_unit_value})
    
    
    #ดึงข้อมูลทีละรายการบันทึกลง List
    for unit in all_unit_element:
        data_dict = dict()
        data_dict['title'] = unit.find(title_tag).text
        data_dict['price'] = unit.find(price_tag,{price_attribute:price_value}).text
        data_list.append(data_dict)
    
    #แจ้งเบื้องต้นว่าทำงานถึงหน้าไหน
    print('Completed page no. ...', page)
Scraping page no. ... 1
Scraping page no. ... 2
Scraping page no. ... 3
...
Scraping page no. ... 368

ข้อมูล List ของ Dictionary ที่เก็บข้อมูลทั้งเวปไซต์

ข้อมูลจากการเก็บข้อมูลมาจากทั้งเวปไซต์ จะอยู่ในรูปแบบของ List ของ Dictionary ที่ List เป็นตัวแทนของข้อมูลแต่ละแถวที่เรียงซ้อนกัน และ Dictionary ข้างในแต่ละตัวเป็นตัวแทนของข้อมูลที่จะอยู่ในแต่ละแถวของตาราง


In [25]:
data_list
Out [25]:
[{'title': 'สิริ เพลส แอร์พอร์ต ภูเก็ต (Siri Place Airport)',
  'price': 'เริ่มต้น 1.99 ลบ. '},
  ...]  


 

บันทึกข้อมูลลง DataFrame


สำหรับการบันทึกข้อมูลลง Excel สามารถทำได้ผ่านการแปลงข้อมูลให้อยู่ใน DataFrame Object ที่สร้างผ่านการใช้ Pandas Library ซึ่งเราสามารถติดตั้ง และนำมาใช้งานได้ง่ายๆ ผ่านคำสั่ง !pip install


ติดตั้ง และนำ Pandas มาใช้งาน


Pandas เป็น Library ที่รวบรวมคำสั่งสำหรับการทำงานกับข้อมูลตารางไว้อย่างหลากหลาย สามารถติดตั้งผ่าน !pip install ได้เลย


In [26]:
!pip install pandas
Requirement already satisfied: pandas ...

เมื่อติดตั้งแล้ว สามารถนำเข้ามาใช้งานได้ผ่าน import โดยจะนิยมตั้งชื่อเล่นให้ Pandas ผ่านคำสั่ง as ให้เป็นชื่อ pd


In [27]:
import pandas as pd

แปลงข้อมูลเป็น DataFrame

สำหรับข้อมูลที่ต้องใช้สำหรับการบันทึกออกไปเป็น Excel จะต้องเตรียมข้อมูลให้อยู่ในรูปแบบของ DataFrame เสียก่อน ซึ่งข้อมูลที่เราจัดเก็บมาในรูปแบบของ List ของ Dictionary ส่วนนี้ สามารถแปลงเป็น DataFrame ได้ผ่านคำสั่ง .DataFrame() ที่รับ argument เป็นข้อมูล List ของ Dictionary ที่เก็บข้อมูลของแต่ละรายการเอาไว้ได้เลย ซึ่งจะได้ผลลัพธ์เป็นข้อมูลที่อยู่ใน DataFrame Object ซึ่งสามารถแปลงเป็น Excel ได้ในภายหลัง


In [28]:
data_df = pd.DataFrame(data_list)
data_df
Out [28]:

 

บันทึกข้อมูลลง Excel

สำหรับการบันทึกข้อมูลในตาราง DataFrame ลง Excel เราจะมีประเด็นที่สำคัญที่สุดคือการสร้างที่อยู่สำหรับการบันทึกไฟล์ โดยเราจะทำการสร้าง String Object ที่เก็บที่อยู่ไฟล์โดยสำหรับที่อยู่ไฟล์ของ Window OS จะมีการใช้สัญลักษณ์ \ ซึ่งจะมีปัญหาต่อการใช้งาน ซึ่งจะต้องทำการแปลง String Object ที่เก็บที่อยู่เป็น Raw String ผ่านการเติม r'' ไว้ด้านหน้า String อีกประเด็นสำคัญที่ต้องเช็คคือ ที่อยู่ของไฟล์ Excel ที่ต้องการบันทึกจะต้องเป็นที่อยู่ของไฟล์ Excel ไม่ใช่ ที่อยู่ของโฟลเดอร์ที่เก็บไฟล์ Excel ที่ต้องการ โดยเราจะกำหดนชื่อไฟล์ Excel ที่ต้องการบันทึกลงไปในที่อยู่ที่กำหนด และใส่นามสกุลไฟล์ .xlsx ซึ่งเป็นนามสกุลของ Excel


In [29]:
file_location = r'C:\Users\acer\Desktop\youtube\00 web scraping\00 material\Condo.xlsx'

เมื่อเตรียมที่อยู่เรียบร้อย เราจะบันทึก DataFrame ลงไปใน Excel ด้วยคำสั่ง .to_excel() และใส่ที่อยู่ที่เป็น Raw String ลงเป็น argument


In [30]:
data_df.to_excel(file_location)

เมื่อรันคำสั่งบันทึกลง Excel จะมีการสร้างไฟล์ Excel ตามชื่อ และที่อยู่ที่กำหนดไว้ สามารถนำข้อมูลไปใช้งานต่อผ่าน Excel หรือใช้ Python จัดการต่อ ก็สามารถทำตามต้องการได้เลย!



 

หลักการทำงานกับเวปอื่น


สำหรับการปรับใช้งานกับเวปอื่นที่สนใจ สามารถใช้หลักการค้นหา 1 รายการข้อมูล และสกัดข้อมูลที่ต้องการได้ลักษณะเดียวกัน โดยใช้การเปลี่ยนลิ้งค์เป็นลิ้งค์ที่สนใจ, เปลี่ยนรายละเอียดของ 1 รายการ และเปลี่ยน หรือเพิ่มเติมรายละเอียดของ Tag ที่เก็บข้อมูลส่วนต่างๆ เพื่อสกัด และบันทึกข้อมูลลง Excel ได้ตามโครงสร้างของเวปได้เลย!


 

เรียนพื้นฐานการเก็บข้อมูลจากเวปไซต์ และควบคุมการทำงานบน Browser


แอดซิปป้าขอฝากคอร์ส Web Scraping with Python ที่จะรวบรวมคำสั่งสำคัญของ BeautifulSoup, Selenium สำหรับการใช้เพื่อควบคุมการทำงานของ Browser และการเก็บข้อมูลจากเวปไซต์ด้วยตัวอย่างจริงจากเวป E-Commerce และ Social Media ให้มีผลงานติดตัวทันทีหลังเรียนจบ!



2,159 views0 comments

Комментарии


bottom of page