วิธีการขูดหน้าเว็บ imdb?


10

ฉันพยายามเรียนรู้การขูดเว็บโดยใช้ Python ด้วยตนเองเป็นส่วนหนึ่งของความพยายามในการเรียนรู้การวิเคราะห์ข้อมูล ฉันพยายามขูดหน้าเว็บ imdb ซึ่งมี url ต่อไปนี้: http://www.imdb.com/search/title?sort=num_votes,desc&start=1&title_type=feature&year=1950,2012

ฉันกำลังใช้โมดูล BeautifulSoup ต่อไปนี้เป็นรหัสที่ฉันใช้:

r = requests.get(url) # where url is the above url    
bs = BeautifulSoup(r.text)
for movie in bs.findAll('td','title'):
    title = movie.find('a').contents[0]
    genres = movie.find('span','genre').findAll('a')
    genres = [g.contents[0] for g in genres]
    runtime = movie.find('span','runtime').contents[0]
    year = movie.find('span','year_type').contents[0]
    print title, genres,runtime, rating, year

ฉันได้รับผลลัพธ์ต่อไปนี้:

The Shawshank Redemption [u'Crime', u'Drama'] 142 mins. (1994)

ด้วยการใช้รหัสนี้ฉันสามารถขูดชื่อประเภทไทม์และปี แต่ฉันไม่สามารถคัดลอก iddb ภาพยนตร์ id หรือการจัดอันดับ หลังจากตรวจสอบองค์ประกอบ (ในเบราว์เซอร์โครม) ฉันไม่สามารถหารูปแบบที่จะให้ฉันใช้รหัสที่คล้ายกันข้างต้น

ใครช่วยฉันเขียนรหัสที่จะให้ฉันขูดรหัสภาพยนตร์และการให้คะแนน?


1
ฉันแก้ไขโค้ดของคุณเล็กน้อย แต่ก็ล้มเหลวเพราะratingไม่ได้กำหนดไว้ หากคุณแก้ไขนั้นคุณยังสามารถเพิ่มและfrom BeautifulSoup import BeautifulSoup import requestsและทำไมไม่แสดงด้วยurl="http://etc"ดังนั้นเราไม่ต้องทำเพื่อตัวเราเอง?
Spacedman

คำตอบ:


12

แทนการขูดคุณอาจจะพยายามที่จะได้รับข้อมูลโดยตรงที่นี่: http://www.imdb.com/interfaces ดูเหมือนว่าพวกเขามีข้อมูลพร้อมใช้งานผ่าน ftp สำหรับภาพยนตร์นักแสดงและอื่น ๆ


2
@Gred Thatcher ขอบคุณสำหรับลิงค์ โครงการนี้เป็นส่วนหนึ่งของความพยายามในการเรียนรู้เกี่ยวกับการขูดเว็บและปัญหาเหล่านี้ทั้งหมด - :)
user62198

8

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

bs = BeautifulSoup(r.text)
for movie in bs.findAll('td','title'):
    title = movie.find('a').contents[0]
    genres = movie.find('span','genre').findAll('a')
    genres = [g.contents[0] for g in genres]
    runtime = movie.find('span','runtime').contents[0]
    rating = movie.find('span','value').contents[0]
    year = movie.find('span','year_type').contents[0]
    imdbID = movie.find('span','rating-cancel').a['href'].split('/')[2]
    print title, genres,runtime, rating, year, imdbID

ผลลัพธ์มีลักษณะดังนี้:

The Shawshank Redemption [u'Crime', u'Drama'] 142 mins. 9.3 (1994) tt0111161

2

คุณสามารถรับทุกสิ่งจาก div ด้วย class = "rating rating-list"

สิ่งที่คุณต้องทำคือ retrive attribute id: [id = "tt1345836 | imdb | 8.5 | 8.5 | advsearch"] เมื่อคุณมีเนื้อหานี้คุณแยกสตริงนี้ด้วย '|' และคุณจะได้รับ: 1. พารามิเตอร์: movie id 3. พารามิเตอร์: คะแนนภาพยนตร์


ขอบคุณ @Matic DB ... ฉันสามารถรับ id .. ด้านล่างเป็นวิธีแก้ปัญหาของฉัน
user62198

2

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

print "\t".join([title, genres,runtime, rating, year])

สิ่งที่ดีเกี่ยวกับไฟล์ที่คั่นด้วยแท็บคือถ้าคุณจบการปรับขนาดมันสามารถอ่านได้อย่างง่ายดายเช่นอาฟริกา นอกจากนี้คุณสามารถอ่านข้อมูลในโปรแกรมเป็นภาษาไพ ธ อนโดยใช้โปรแกรม:

 line.split("\t")

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.