การรับข้อมูลจากหน้าเว็บด้วยวิธีที่มั่นคงและมีประสิทธิภาพ


11

เมื่อเร็ว ๆ นี้ฉันได้เรียนรู้ว่าการใช้ regex เพื่อแยก HTML ของเว็บไซต์เพื่อรับข้อมูลที่คุณต้องการไม่ใช่วิธีการที่ดีที่สุด

ดังนั้นคำถามของฉันง่าย: อะไรคือสิ่งที่ดีที่สุด / มีประสิทธิภาพมากที่สุดและเป็นวิธีที่มีเสถียรภาพโดยทั่วไปในการรับข้อมูลนี้

ฉันควรทราบว่า:

  • ไม่มี API
  • ไม่มีแหล่งข้อมูลอื่นที่ฉันสามารถรับข้อมูลได้ (ไม่มีฐานข้อมูลฟีดและอื่น ๆ )
  • ไม่สามารถเข้าถึงไฟล์ต้นฉบับได้ (ข้อมูลจากเว็บไซต์สาธารณะ)
  • สมมติว่าข้อมูลเป็นข้อความปกติแสดงในตารางในหน้า html

ตอนนี้ฉันใช้ python สำหรับโปรเจคของฉัน แต่ภาษา / การแก้ปัญหา / เคล็ดลับก็ดี

เป็นคำถามด้าน: คุณจะไปเกี่ยวกับมันอย่างไรเมื่อหน้าเว็บถูกสร้างโดย Ajax สาย?

แก้ไข:

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


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

1
@JoachimSauer - คำถามยังสามารถตอบได้ด้วยวิธีที่ดีที่สุด
ไม่เปิดเผยตัว

เนื่องจากเว็บไซต์ส่วนใหญ่เป็นแบบไดนามิกและเก็บข้อมูลไว้ในฐานข้อมูลวิธีที่ดีที่สุดคือการรับฐานข้อมูลจากเว็บไซต์ หากเว็บไซต์มี API คุณสามารถใช้งานได้ ในกรณีที่คุณต้องการขูดหน้าคงที่จากนั้น Python urllib และโมดูล HTMLParser ในตัวจะทำงานได้ดี แพคเกจบางอย่างสำหรับการคัดลอก HTML นั้นมีให้ที่ PyPi
Ubermensch

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

1
อาจฝังเว็บเบราว์เซอร์เช่น Webkit แล้วใช้การเขียนสคริปต์ DOM เพื่อรับข้อมูลจากหน้าที่แสดงผล เกือบทุกแพลตฟอร์มสามารถทำได้ แต่นี่คือวิธีที่คุณจะทำใน Qt: doc.qt.nokia.com/4.7-snapshot/qtwebkit-bridge.html
user16764

คำตอบ:


2

นี่คือ 2 เซ็นต์ของฉัน:

หากไม่มี AJAX ที่เกี่ยวข้องหรือสามารถล้างได้อย่างง่ายดาย 'แก้ไข' HTML เป็น XHTML (โดยใช้ HTMLTidy เป็นต้น) จากนั้นใช้ XPath แทนนิพจน์ทั่วไปเพื่อดึงข้อมูล
ในหน้าเว็บที่มีโครงสร้างอย่างดีเอนทิตีของข้อมูลที่แยกกันอย่างมีเหตุผลนั้นมีความแตกต่างกัน<div>หรือแท็กอื่น ๆ ซึ่งหมายความว่าคุณจะสามารถค้นหาข้อมูลที่ถูกต้องได้อย่างง่ายดายด้วยนิพจน์ XPath แบบง่าย สิ่งนี้ยอดเยี่ยมเช่นกันเพราะคุณสามารถทดสอบพูดคอนโซลของ Chrome หรือคอนโซลนักพัฒนาซอฟต์แวร์ของ Firefox และตรวจสอบว่ามันใช้งานได้ดีก่อนที่จะเขียนรหัสอื่นแม้แต่บรรทัดเดียว
วิธีการนี้ยังมีอัตราส่วนสัญญาณต่อสัญญาณรบกวนที่สูงมากเนื่องจากโดยทั่วไปแล้วการแสดงออกเพื่อเลือกข้อมูลที่เกี่ยวข้องจะเป็นแบบเส้นเดียว นอกจากนี้ยังง่ายต่อการอ่านมากกว่านิพจน์ทั่วไปและออกแบบมาเพื่อวัตถุประสงค์ดังกล่าว

หากมี AJAX และมีส่วนเกี่ยวข้องกับ JavaScript อย่างรุนแรงให้ฝังองค์ประกอบของเบราว์เซอร์ในแอปพลิเคชันและใช้ DOM เพื่อเรียกกิจกรรมที่คุณต้องการและ XPath เพื่อดึงข้อมูล มีส่วนประกอบของเบราว์เซอร์ที่ฝังอยู่ได้ดีมากมายส่วนใหญ่ใช้เบราว์เซอร์ในโลกแห่งความจริงซึ่งเป็นสิ่งที่ดีเนื่องจากหน้าเว็บอาจไม่ถูกต้อง (X) HTML แต่ก็ยังแสดงผลได้ดีบนเบราว์เซอร์หลักทั้งหมด จริงๆแล้วหน้าส่วนใหญ่จะได้รับวิธีนี้ในที่สุด)


ขอบคุณฉันจะดู XPath อีกแน่นอน ฉันไม่ชินกับการทำงานกับมันดังนั้นมันจะเป็นเรื่องดีที่ได้เรียนรู้ +1 :)
Mike

5

จากประสบการณ์ของผมโดยใช้สภาพแวดล้อม .NET คุณสามารถใช้ประโยชน์จากHTML Agility แพ็ค

หากหน้าถูกจัดรูปแบบเป็น XHTML คุณสามารถใช้ตัวแยกวิเคราะห์ XML ปกติได้ มันมีอะไรมากมายสำหรับสภาพแวดล้อมที่คุณสามารถจินตนาการได้

สำหรับคำถามเกี่ยวกับ AJAX คุณสามารถใช้รหัสเครือข่าย HTTP ปกติเพื่อรับข้อมูลและแยกวิเคราะห์ได้

อีกครั้งหาก AJAX สแต็กของคุณคืนค่า XML คุณจะมีตัวเลือกมากมาย หากส่งคืน JSON ให้พิจารณาไลบรารีที่อนุญาตให้คุณแมปสตรีมกับวัตถุที่พิมพ์ ใน .NET ผมแนะนำให้คุณNewtonsoft.Json


และด้วย 'รหัสเครือข่าย HTTP' คุณหมายถึงการจับการตอบสนองของเซิร์ฟเวอร์เมื่อมีการร้องขอ? ขอบคุณสำหรับคำแนะนำฉันจะต้องแน่ใจว่าได้ตรวจสอบพวกเขา +1
Mike

เผง ใน. NET คุณสามารถใช้ System.Net.WebClient หรือไลบรารีเช่น RestSharp | restsharp.org ฉันใช้มันกับ Mono สำหรับ Droid ด้วย
gsscoder

4

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

มีห้องสมุดทุกภาษาหลักที่จะแยก HTML เช่นนี้

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


ขอบคุณฉันใช้Beautiful Soupเพื่อทำงานให้เสร็จ ฉันรู้ว่ามันจะไม่มั่นคงฉันควรจะชี้แจงว่าในคำถามของฉัน +1 สำหรับคุณ :)
Mike

4

เป็นคำถามด้าน: คุณจะไปเกี่ยวกับมันอย่างไรเมื่อหน้าเว็บถูกสร้างโดย Ajax สาย?

หากมีการโทร ajax อาจเป็นไปได้ว่าบาง POST หรือ GET url มีตัวแปรบางตัว

ฉันจะตรวจสอบจาวาสคริปต์เพื่อค้นหาว่าจุดสิ้นสุดและพารามิเตอร์คืออะไร หลังจากนั้นอาจเป็นไปได้ว่าข้อมูลที่ส่งคืนคือ json / xml / plain text หรือบางที HTML บางส่วน

เมื่อคุณทราบข้อมูลข้างต้นแล้วคุณเพียงแค่ขอ GET หรือ POST ไปยังปลายทางนั้นและแยกวิเคราะห์ข้อมูลที่ส่งคืน


2
ที่น่าสังเกตว่าหลายบริการตรวจสอบส่วนหัว HTTP เพื่อให้แน่ใจว่าเป็นHTTP_X_REQUESTED_WITH XMLHttpRequestคนดีจะใช้การป้องกัน XSRF บางประเภทสำหรับคำขอ POST ดังนั้นคุณจะต้องใช้คุกกี้วิเศษเช่นกัน การทำเครื่องหมายจุดจบของ AJAX ที่ไม่เปิดเผยโดย API สาธารณะบางอย่างรู้สึกลำบากเล็กน้อยสำหรับฉันและมีดโกนของคุณก็มีแนวโน้มที่จะแตกหักหากผลลัพธ์ (หรือนโยบายการร้องขอ) เปลี่ยนแปลง
Tim Post

@ โพสต์คุณถูกต้อง 100% ฉันเห็นมัน "เหนอะ" แน่นอน :) แต่ในกรณีที่ไม่มีประชาชน API ใดต้องการต้อง ..
darknight

ฉันสามารถใช้สิ่งนี้กับแอปพลิเคชันขับเคลื่อน AJAX ของฉัน (และด้วย 'ของตัวเอง' ฉันไม่ได้หมายความว่าฉันเขียนไว้ แต่การตั้งค่าเป็นของฉัน) แต่มันไม่รู้สึกถูกต้องที่จะลองและบายพาสระบบของเซิร์ฟเวอร์อื่น TimPost มันรู้สึกว่า 'icky' มันเป็นความคิดที่ดีอย่างไรก็ตามขอบคุณ! +1!
Mike

1

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


ฉันรู้ว่าหน้า HTML ไม่ควรถูกวิเคราะห์ด้วยคอมพิวเตอร์ แต่บางครั้งก็ไม่มีตัวเลือกอื่น นอกจากนี้ฉันใช้ข้อมูลที่เปิดเผยต่อสาธารณชนสำหรับโครงการส่วนบุคคลที่ไม่ได้ทำการค้า แต่อย่างใดฉันไม่คิดว่าฉันต้องได้รับอนุญาตอย่างชัดเจนหรือไม่? ขอบคุณสำหรับข้อมูลของคุณ! +1 สำหรับคุณด้วย;)
Mike

@MikeHeremans หากต้องการทราบว่าคุณได้รับอนุญาตให้รับข้อมูลจากเว็บไซต์หรือไม่ให้อ่าน ToS และ robots.txt หากทั้งคู่ไม่ปฏิเสธสิทธิ์ในการขูดข้อมูลโดยอัตโนมัติคุณควรจะยอมรับในกรณีส่วนใหญ่อย่างถูกกฎหมาย แน่นอน
IANAL

หากคุณต้องการที่จะเห็นรหัสของโครงการดังกล่าว: code.google.com/p/acao-toolkit/source/browse/... ตรวจสอบ content_script.js เป็นรหัสที่ฉีดเข้าไปในหน้าเว็บ
nohros
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.