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

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

แคสเปอร์จึงถือกำเนิดขึ้น โดยสำรวจผู้ค้าปลีกรถยนต์ใช้แล้วทางออนไลน์ เช่น AutoTrader, CarsDirect, CarGuru, Carvana, Lowbook และ KSL เพื่อค้นหาข้อมูลการขายรถยนต์ใช้แล้วโดยใช้แพ็คเกจ Selenium ของ Python แม้ว่าปัจจุบันจะค้นหาเฉพาะรถยนต์ในโพรโว พื้นที่ยูทาห์ แต่แคสเปอร์จะให้คะแนนรถแต่ละคันเพื่อสร้างรายงาน CSV ของตลาดปัจจุบัน และบันทึกการเปลี่ยนแปลงของตลาดนับตั้งแต่ก่อตั้งในเดือนพฤศจิกายน 2022

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

ชื่อ Casper มาจากคำภาษาสเปนว่า "raspar" ซึ่งแปลว่า "ขูด" นอกจากนี้ ยังแสดงความเคารพต่อ “Casper the Friendly Ghost” เนื่องจากเมื่อโปรแกรมกำลังทำงาน ดูเหมือนว่าผีกำลังควบคุมคอมพิวเตอร์ของคุณ!

การขูดเว็บ

เป้าหมายหลักของฉันเมื่อฉันเริ่มโครงการนี้คือการพัฒนาทักษะการขูดเว็บของฉัน การขูดเว็บเป็นคำที่ครอบคลุมซึ่งหมายถึงการดึงข้อมูลที่มีความหมายจากเว็บไซต์ เมื่อปฏิบัติตามชุดคำสั่งที่ตั้งโปรแกรมไว้ โปรแกรมขูดเว็บจะสามารถระบุและดึงข้อมูลและจัดเก็บไว้ในฐานข้อมูลหรือส่งออกไปยังสเปรดชีตได้ ฉันตัดสินใจสร้าง Casper โดยใช้แพ็คเกจการทดสอบและระบบอัตโนมัติ Selenium เพื่อทำ “การวิจัย” ให้ฉัน

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

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

ฟังก์ชันนี้ค้นหาราคาทั้งหมดที่ปรากฏบนหน้าปัจจุบัน ในตัวอย่างนี้ ฉันกำลังค้นหาด้วย xpath ซึ่งหมายความว่า Casper จะค้นหาโครงสร้างโค้ด HTML จนกว่าจะพบบล็อกที่ตรงกับ priceClass โดยใช้เมธอด find_elements ของอ็อบเจ็กต์ไดรเวอร์ Selenium ตัวแปรสตริง priceClass บอกให้ Casper ค้นหาองค์ประกอบ "div" ที่มีแอตทริบิวต์ "data-qa" ที่มีค่าเท่ากับ "price" for วนซ้ำที่ด้านล่างจะแยกวิเคราะห์รายการที่เกี่ยวข้องเพื่อให้ออบเจ็กต์สตริงสามารถส่งไปยังอ็อบเจ็กต์ int ได้ในที่สุด

def findPrices(self):
    """
    Find the prices for each car
    :param self
    :return: prices (list): list of price strings
    """
    # initialize a list of prices to return
    prices = []

    # define the X-Path to search the HTML code
    priceClass = "//div[@data-qa='price']"

    # get a list of price elements and save the parsed text content
    priceElems = self.driver.find_elements(By.XPATH, priceClass)

    # add the text from the elements to the list
    for elem in priceElems:
        prices.append(elem.text.replace(",", "").replace("$", "").split()[0])

    # return the list of prices
    return prices

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

เนื่องจากการค้นหาส่วนใหญ่ให้ผลลัพธ์หลายหน้า โดยแต่ละหน้ามียอดขายเพียง 20–50 หน้า Casper จึงย้ายไปยังหน้าถัดไปหลังจากคัดลอกหน้าแรก รีเซ็ตตัวกรอง และดำเนินการต่อไปจนกว่าจะพบผลลัพธ์ทั้งหมด กระบวนการทั้งหมดจะใช้เวลาประมาณ 30 นาทีในการคัดลอกรายชื่อเฉลี่ย 500 รายการระหว่างเว็บไซต์ทั้ง 6 แห่ง

การบีบอัดภาพ

การรวบรวมภาพได้มากถึง 500 ภาพทุกวันเป็นงานที่สำคัญ และสามารถใช้พื้นที่จัดเก็บข้อมูลที่มีอยู่ของคอมพิวเตอร์ได้อย่างรวดเร็ว เพื่อแก้ไขปัญหานี้ ฉันจำเป็นต้องบีบอัดรูปภาพเพื่อให้ใช้พื้นที่น้อยลงและจัดการได้ง่ายขึ้น แม้ว่าแพ็คเกจอย่าง OpenCV จะมีเทคนิคการบีบอัดรูปภาพในตัว แต่ฉันเลือกที่จะใช้ประโยชน์จากเทคนิคพีชคณิตเชิงเส้นที่ฉันเรียนรู้ในคลาส "ACME" ของฉันเพื่อสร้างอัลกอริทึมที่กำหนดเองเพื่อบีบอัดรูปภาพอย่างมีประสิทธิภาพ คุณสามารถดูข้อมูลโดยละเอียดเกี่ยวกับอัลกอริทึมได้ในบล็อกโพสต์อื่นๆ ของฉัน “การปลดล็อกความลับของการบีบอัดภาพด้วยเวกเตอร์”

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

อัลกอริทึมการให้คะแนน

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

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

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

การตรวจจับความเสียหาย

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

เพื่อแก้ไขปัญหานี้ ฉันจึงพัฒนาโมเดลแมชชีนเลิร์นนิงที่สามารถตรวจจับความเสียหายในรูปภาพรถยนต์ได้อย่างแม่นยำมากกว่า 99% จริงๆ แล้วฟีเจอร์นี้เป็นโปรเจ็กต์สุดท้ายสำหรับชั้นเรียน Deep Learning ของฉัน และกลายเป็นเรื่องท้าทายมากกว่าที่ฉันคาดไว้ในตอนแรก ฉันเชื่อว่ามันสมควรได้รับการโพสต์ของตัวเอง ดังนั้นคุณสามารถหาข้อมูลเพิ่มเติมเกี่ยวกับเรื่องนี้ได้ในบล็อกโพสต์อื่น ๆ ของฉัน “การตรวจจับความเสียหายของยานพาหนะด้วยเทคโนโลยีการเรียนรู้เชิงลึกขั้นสูง” ฉันใช้เวลากว่าสามสิบชั่วโมงในการเพิ่มข้อมูลรูปภาพยานพาหนะด้วยชุดข้อมูลความเสียหายของรถยนต์ที่เปิดเผยต่อสาธารณะ เพื่อฝึกโครงข่ายประสาทเทียมเชิงลึก U-Net เพื่อจำแนกยานพาหนะว่าเสียหายหรือไม่เสียหาย

การคาดการณ์ราคา

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

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

งานในอนาคต

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

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

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

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