มาดึงข้อมูลเบอร์มงคลจากเว็บกัน ตอน 3 ตอนสุดท้าย (เทียบคะแนนเว็บอื่น)

Perasut Rungcharassang
5 min readApr 24, 2020

--

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

หลังจากเราดึงข้อมูลเบอร์มงคลจากเว็บ somjade มาเก็บไว้เป็นไฟล์ GoodNumber.csv จาก ตอน 2 หน้าตาเป็นแบบนี้ครับ (ดูรูปที่ 1) เราจะนำเบอร์มือถือทุกเบอร์ที่ดึงไปลองเทียบคะแนนจากอีก 2 เว็บ

รูปที่ 1 หน้าตาข้อมูลที่นำมาใส่ในตาราง

เป้าหมาย

  1. ใช้ pandas อ่านไฟล์ GoodNumber.csv นำเบอร์มือถือทั้งหมดมาเก็บไว้ในตัวแปรเตรียมนำไปใช้กับเว็บอื่น ๆ เพื่อเปรียบเทียบคะแนน
  2. นำเบอร์มือถือจากข้อ 1 ไปวิเคราะห์จากเว็บ berthongsuk โดยใช้วิธีดึงคะแนนเหมือน ตอน 2
  3. นำเบอร์มือถือจากข้อ 1 ไปวิเคราะห์จากเว็บ berlnw โดยใช้ selenium, webdriver, และ xpath เพื่อดึงคะแนนออกมา (ส่วนนี้น่าสนุกสุดครับ)
  4. นำคะแนนจากทั้ง 3 เว็บมาใส่ตารางบันทึกเป็นไฟล์ csv เพื่อนำไปใช้งานต่อ

มาเริ่มกันเลย

เช่นเคยผมจะเขียนโค้ดสำหรับ 1 เบอร์ก่อนเพราะจะอธิบายง่ายกว่า ส่วนท้ายของบทความจะใส่โค้ดเต็มให้ทำได้ทุกเบอร์ครับ

เริ่มจากมาเขียนคำสั่งให้อ่านไฟล์ GoodNumber.csv กันก่อน
เราจะใช้ คำสั่ง .read_csv(‘ ชื่อไฟล์ ’) ของ pandas ตามโค้ดบรรทัดที่ 2
ค่าที่เก็บไว้ในตัวแปรชื่อ GoodNumber เป็นชนิด DataFrame
แต่เราต้องการเพียงเบอร์มือถือจากคอลัมน์ที่ชื่อ Number และแถวที่ 1 (เบอร์แรกนั่นเอง)จากโค้ดบรรทัดที่ 3 เราสามารถเรียกใช้ค่าในตารางดังนี้ GoodNumber[ชื่อคอลัมน์][แถวที่ต้องการ-1] มาเก็บในตัวแปรชื่อ Number ชนิดของตัวแปรคือ str (string) ตามด้านล่าง
ทีนี้เกิดปัญหาขึ้นแล้วสิครับ สังเกตค่าที่ได้เป็น “‘0839455228’” มีทั้ง “ ” และ ‘ ’ ที่เป็นแบบนี้เพราะตอนบันทึก csv ผมต้องการให้แสดงผลใน excel มีเลข 0 (ศูนย์) ด้านหน้าตรงนี้ก็แล้วแต่ความต้องการของแต่ละคนเลย อาจไม่เหมือนกันได้นะแต่จะมีปัญหาเมื่อนำไปใช้งาน ผมจึงตัด “ ” ออกใช้คำสั่งง่าย ๆ ตามโค้ดบรรทัดที่ 5 Number[1:-1] หมายถึง จะเอาตัวที่ 2 เป็นต้นไปจนถึงตัวก่อนสุดท้าย ผลที่ได้ตามนี้ครับ**หมายเหตุ**
1. เราสามารถเขียนโค้ดต่อกันใน 1 บรรทัดได้เลยครับ ดูที่โค้ดบรรทัดที่ 6
บรรทัดที่ 8 ผมเก็บคะแนนของทุกเบอร์ใน GoodNumber จากคอลัมน์ Score ไว้ในตัวแปร Score แล้วเก็บคะแนนของเบอร์แรกในตัวแปรชื่อ ScoreSomjade เพื่อเอาไปใส่ในตารางเทียบคะแนนตอนท้ายบทความ

เป้าหมายแรกเสร็จแล้วครับ ตอนนี้เรามีเบอร์มือถือที่ต้องการ พร้อมที่จะนำไปใส่ในเว็บอื่น ๆ เพื่อเทียบคะแนนกันแล้ว Let’s go

ดึงคะแนนจากเว็บ berthongsuk

เนื่องจากเว็บ berthongsuk เข้าถึงหน้าเว็บที่แสดงคะแนนได้ง่าย ๆ ดังนี้ https://berthongsuk.in.th/วิเคราะห์เบอร์มงคล?num=เบอร์มือถือ10หลัก เช่น https://berthongsuk.in.th/วิเคราะห์เบอร์มงคล/?num=0839455228 
(ดูรูปที่ 2) เราจึงใช้วิธีเดียวกันกับตอนที่แล้วได้ครับ (ย้อนกลับไปดูส่วนท้าย ๆ ตอน 2)
รูปที่ 2 หน้าเว็บคะแนนของ berthongsuk และ html
เนื่องจากคะแนนของเว็บนี้มีเพียง 970 ผมอยากให้เป็นแบบเดียวกันกับเว็บ somjade จึงเติม /1000 มาด้วยในโค้ดบรรทัดที่ 11 จากนั้นเก็บคะแนนที่ได้ไว้ในตัวแปรชื่อ ScoreBerthong ผลตามด้านล่างครับ

ผ่านเป้าหมายที่ 2 ไปอย่างรวดเร็ว เพราะวิธีละเอียดเราทำในตอนที่แล้ว จะแตกต่างกันที่ตำแหน่ง tag ของคะแนนในหน้าเว็บ หากเราเปลี่ยนเว็บก็ต้องมาหา tag กันใหม่ เป้าหมายต่อไปจะเป็นวิธีการใหม่ครับ เราต้องโหลดบางอย่างเพิ่มเติม ต้อง install library ใหม่ด้วย พร้อมลุยต่อรึยัง… ถ้าพร้อมแล้วไปกันเลย

ดึงคะแนนจากเว็บ berlnw

การนำเบอร์มือถือมาต่อท้าย url ของเว็บ เพื่อเข้าถึงหน้าแสดงคะแนน ดูจะเป็นวิธีที่สะดวกดีนะครับ แต่บางเว็บ เช่น เว็บ berlnw ทำไม่ได้ต้องใส่เบอร์ในช่องค้นหาเอง แล้วกดคลิกเท่านั้น (ดูรูปที่ 3) สังเกตที่ช่องแสดง url หลังจากคลิกปุ่มวิเคราะห์ไม่มีเบอร์ต่อท้าย (ดูรูปที่ 4)
รูปที่ 3 หน้าแรกเว็บ berlnw
รูปที่ 4 หน้าเว็บหลังจากกดวิเคราะห์เบอร์
ด้วยเหตุนี้เราจึงต้องการตัวช่วย เพื่อกรอกข้อมูลในช่องให้เรา พร้อมคลิกปุ่มอัตโนมัติ นำไปหาหน้าเว็บที่มีคะแนนปรากฏอยู่นั่นเอง
สิ่งที่ต้องเตรียมพร้อมเพิ่มเติมก่อนไปลุยต่อ
1. โหลด ChromeDriver ได้ที่ https://chromedriver.chromium.org/downloads จะได้มาเป็นไฟล์ .zip ให้แตกไฟล์ออกมาจะได้ chromedriver.exe
2. ติดตั้ง library ที่ชื่อ selenium ทำเหมือน ตอน 1(ดูรูปที่ 5)
**หมายเหตุ**
1. เมื่อเราใช้ selenium กับ webdriver เราไม่จำเป็นต้องใช้ requests แล้ว
2. หากต้องการใช้ browser ตัวอื่นที่ไม่ใช่ Chrome สามารถหาวิธีใน google ได้ครับ
รูปที่ 5 ติดตั้ง selenium library

ไปกันต่อครับ

เริ่มจากบรรทัดที่ 1 import webdriverบรรทัดที่ 2-3 จะเป็นการตั้งค่า option ถ้าเราต้องการกรอกข้อมูลหลายครั้ง คงไม่อยากให้ popup เด้งตลอดเราสามารถทำได้โดยเปิด comment ในบรรทัดที่ 3 (ลบเครื่องหมาย # ออก)จะเป็นการตั้งค่า option ให้ไม่เด้ง browser ขึ้นมาตอนรันในโค้ดบรรทัดที่ 7 เราจะใส่ที่อยู่ตัว chromedriver.exe ที่เราโหลดไว้ (เปลี่ยนตามเครื่องผู้ใช้ครับ อย่า copy ไปนะ ^ ^) ของผมอยู่ที่ '/Users/55728646/PycharmProjects/GoodNumber/chromedriver' และบรรทัดสุดท้ายเราจะใส่ url เว็บที่เราต้องการกรอกข้อมูล นั่นคือ "https://www.berlnw.com/"
เมื่อเรารันโค้ด บรรทัดที่ 7 จะทำให้ปรากฏ Chrome browser เด้งขึ้นมาและนำเราไปยังหน้าเว็บที่ใส่ไว้ในโค้ดบรรทัดที่ 9 (ดูรูปที่ 6)
รูปที่ 6 Chrome popup
เราสามารถดูหน้าตาของ wd ได้โดยใช้คำสั่ง wd.page_source ซึ่งตรงกับ html ของหน้าเว็บตามรูปที่ 7
ต่อมาเราจะหาว่า ช่องกรอกเบอร์มือถือของเว็บนี้อยู่ที่ path ไหนทำได้โดย
1. คลิกขวาที่ช่อง "กรอกเบอร์มือถือ" เลือก Inspect ตามรูปที่ 7
2. หลังจากนั้นมาคลิกขวาที่แถบสีเทา ที่ปรากฏอยู่หน้าขวามือ เลือก copy -> copy XPath ตามรูปที่ 8 จะได้ xpath เป็น //*[@id="inputUsernameEmail"]
รูปที่ 7 หน้า html ของเว็บ berlnw
รูปที่ 8 copy XPath
แล้วใช้ .find_element_by_xpath('ใส่ xpath ที่ได้มา') มาเก็บไว้ในตัวแปร searchboxต่อมาจะใช้ .send_keys('เบอร์ที่ต้องการกรอก') ใส่เบอร์ที่ต้องการกรอกลงไปอัตโนมัติที่ช่องนั้น หากยังจำกันได้เราเก็บเบอร์ไว้ในตัวแปรชื่อ Number แล้วครับ แทนที่โค้ดในบรรทัดที่ 2 เป็น searchbox.send_keys(Number) ได้เลยสังเกตว่า เบอร์ที่ใส่ต้องเป็นชนิด str นะคือมี ' ' หรือ " " ครอบเบอร์อยู่
เราทำแบบเดียวกันในการหา xpath ของปุ่ม " วิเคราะห์ " จะได้ xpath เป็น //*[@id="indexhoro"]/form/buttonต่อมาใช้ .click() เพื่อสั่งกดปุ่มอัตโนมัติ
ผลที่ได้ตามรูปที่ 9
รูปที่ 9 แสดงการกรอกและกดปุ่มอัตโนมัติ

ในที่สุดเราก็ได้เห็นหน้าแสดงคะแนนของเว็บ berlnw ซักทีครับ (ดูรูปที่ 10) เหนื่อยกันไม๊ พักตรงนี้ก่อนได้นะ ใครไม่เหนื่อยมาต่อกันเลย อีกนิดเดียวจะจบแล้วจ้า

รูปที่ 10 หน้าแสดงผลคะแนน
เมื่อเจอหน้าคะแนนแล้ว เชื่อว่าผู้อ่านที่น่ารักที่อ่านจนถึงตรงนี้ น่าจะรู้แล้วว่าผมจะทำอะไรต่อไป ใช่ครับถึงเวลาดึงคะแนนกัน แต่ เอ๊ะ!!! เหมือนมีอะไรแปลก ๆ นะ หน้าตาไม่เหมือนเดิมเพราะเราไม่ได้ใช้ requests แล้วของเว็บ Berthongsuk เราใช้ requests และตอน BeautifulSoup ก็ใช้เป็น r2.text
แต่เว็บ Berlnw เราใช้ webdriver ซึ่งเก็บ html ไว้ในตัวแปร wd เราจะใช้ wd.page_source ดู html ของเว็บ (ดูโค้ดบรรทัดที่ 4 ด้านล่าง) สังเกตว่า wd.page_source จะเปลี่ยนจากตอนแรกไป เพราะเราเปลี่ยนหน้าเว็บไปแล้ว
ส่วนวิธีหา tag ที่มีคะแนนอยู่ทำเหมือนเดิม น่าจะคุ้นเคยกันบ้างแล้วขอไม่ลงรายละเอียดนะครับ ครั้งนี้เราได้เป็น tag <p>  class = 'horoReadable' เก็บไว้ในตัวแปร d3 (ดูโค้ดบรรทัดที่ 5 ด้านล่าง)ในโค้ดบรรทัดที่ 6 จะยุ่งยากนิดหน่อยครับ เพราะ d3.text มีข้อความปนอยู่กับคะแนน จึงต้องลบคำและช่องว่างรวมถึง '\n' โดยประยุกต์ใช้คำสั่งแทนที่ .replace('ตัวที่ต้องการแทน','แทนด้วยตัวนี้')
สุดท้ายจะได้คะแนนเพียงอย่างเดียว เก็บในตัวแปร ScoreBerlnw

เป้าหมายที่ 3 Completed!!! ตอนนี้เรามีคะแนนจากเว็บทั้ง 2 มาเทียบกับเว็บ somjade แล้วครับ มาสร้างตารางให้ดูง่าย ๆ สบายตากัน

เริ่มจากหัวตารางก่อนเลย ผมต้องการหัวตารางเป็น 
เบอร์มือถือ | คะแนนจากsomjade | คะแนนจากBerthongsuk | คะแนนจากBerlnw
โดยเบอร์มือถือและคะแนน เราเก็บไว้ในตัวแปร Number ScoreSomjade ScoreBerthong และ ScoreBerlnw ตามลำดับ ผมเอาทั้ง 4 ค่ามาเก็บไว้ในตัวแปรชื่อ rows และกำหนดชื่อหัวตารางเป็นชื่อเดียวกันกับใน head (โค้ดบรรทัดที่ 1-2) เขียนตำแหน่งตัวแปรให้สอดคล้องกับตำแหน่งชื่อคอลัมน์ครับเราจะใช้ DataFrame ของ pandas สร้างรูปแบบตารางตามโค้ดบรรทัดที่ 4 เก็บในตัวแปร df หลังจากนั้นบันทึกเป็นไฟล์ csv ด้วยคำสั่ง df.to_csv ตามโค้ดบรรทัดที่ 5 ให้ชื่อว่า CompareScore.csv จะได้ไฟล์ csv ตามรูปที่ 11
รูปที่ 11 ไฟล์ CompareScore.csv (1 เบอร์)

ยินดีด้วยครับ 👏👏👏 เราบรรลุครบทั้ง 4 เป้าหมายแล้ว จะได้มองง่าย ๆ ว่าคะแนนในเบอร์เดียวกัน แต่ละเว็บให้คะแนนเท่าไหร่บ้าง

สุดท้ายผมแปะโค้ดฉบับสมบูรณ์ ที่ดึงทุกเบอร์จากหน้าเว็บที่ต้องการอัตโนมัติ โดยรวมโค้ดการดึงข้อมูลทั้ง 2 เว็บไว้ด้วยกัน(ทำพร้อมกันนั่นเอง) ผู้อ่านสามารถนำโค้ดไปวางใน “พื้นที่เขียนโค้ด” ในโปรแกรม PyCharm (จากตอน 1)ได้เลย หากผู้อ่านต้องการใช้กับเว็บอื่น ๆ ก็สามารถนำไปประยุกต์ใช้ได้ครับ อาจแตกต่างกันที่ url tag xpath หรือรูปแบบของข้อความที่เราต้องตัดบ้างเติมบ้างตามต้องการสิ่งที่เพิ่มเติมขึ้นมา
1. บรรทัดที่ 5, 7, 54 และ 55 เป็นคำสั่งจับเวลาการคำนวณ
2. บรรทัดที่ 10 ใช้ len() หาจำนวนเบอร์ที่มีในไฟล์ csv เพื่อใช้กำหนดจำนวนครั้งที่วน loop ให้ทำงานอัตโนมัติ
3. บรรทัดที่ 12 เป็นคำสั่งวน loop ตัด " " หัวท้ายออกไปครับ ทำกับทุกเบอร์
4. บรรทัดที่ 15 และ 52 เก็บผลที่รันในแต่ละรอบ ไว้ในตัวแปรชื่อ rows เอาไปใช้ตอนสร้างตารางด้วย DataFrame ในบรรทัดที่ 58
**หมายเหตุ**
หากต้องการทดลองเทียบคะแนนเพียง 10 เบอร์แรก สามารถเปลี่ยน Number บรรทัดที่ 17 เป็น Number[0:10] ได้ครับ
รูปที่ 12 ตัวอย่างไฟล์เมื่อดึงมา 10 เบอร์แรก (อาจจะไม่เหมือนกัน เพราะเว็บสุ่มลำดับการแสดงผล)
รูปที่ 13 เป็นไฟล์ csv ที่ถูกสร้างขึ้นเมื่อรันโค้ด CompareScore.py ด้านบนครับ
รูปที่ 12 ไฟล์ GoodNumber.csv (10 เบอร์)
รูปที่ 13 ไฟล์ CompareScore.csv (10 เบอร์)

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

แล้วเจอกันใหม่ครับทุกคน

ดูตอนที่เกี่ยวข้อง:

  1. มาดึงข้อมูลเบอร์มงคลจากเว็บกัน ตอน 1 (เตรียมความพร้อม)
  2. มาดึงข้อมูลเบอร์มงคลจากเว็บกัน ตอน 2 (วิธีทำแบบละเอียด)
  3. มาดึงข้อมูลเบอร์มงคลจากเว็บกัน ตอน 3 (เทียบคะแนนเว็บอื่น)

--

--