【问题标题】:IMDb webscraping for the top 250 movies using BeautifulsoupIMDb 使用 Beautifulsoup 抓取前 250 部电影
【发布时间】:2022-10-21 07:21:24
【问题描述】:

我知道这里已经有很多类似的问题了,但是没有一个可以为我的问题提供令人满意的答案。所以这里是:

我们需要从 IMDb 的前 250 部电影中创建一个数据框来进行分配。所以我们需要先用 BeautifulSoup 抓取数据。

这些是我们需要抓取的属性:

IMDb id (0111161)
Movie name (The Shawshank Redemption)
Year (1994)
Director (Frank Darabont)
Stars (Tim Robbins, Morgan Freeman, Bob Gunton)
Rating (9.3)
Number of reviews (2.6M)
Genres (Drama)
Country (USA)
Language (English)
Budget ($25,000,000)
Gross box Office Revenue ($28,884,504)

到目前为止,我只设法得到了其中的几个。我收到了所有电影的所有单独 URL,现在我遍历它们。到目前为止,这是循环的样子:

for x in np.arange(0, len(top_250_links)):
    url=top_250_links[x]
    req = requests.get(url)
    page = req.text
    soup = bs(page, 'html.parser')
    
    # ID
    
    # Movie Name
    Movie_name=(soup.find("div",{'class':"sc-dae4a1bc-0 gwBsXc"}).get_text(strip=True).split(': ')[1])
    
    # Year
    year =(soup.find("a",{'class':"ipc-link ipc-link--baseAlt ipc-link--inherit-color sc-8c396aa2-1 WIUyh"}).get_text())
    
    # Length
    
    
    # Director
    director = (soup.find("a",{'class':"ipc-metadata-list-item__list-content-item"}).get_text())
    
    # Stars
    stars = [a.attrs.get('title') for a in soup.select('td.titleColumn a')]
    
    
    # Rating
    rating = (soup.find("span",{'class':"sc-7ab21ed2-1 jGRxWM"}).get_text())
    rating = float(rating)
        
    # Number of Reviews
    reviews = (soup.find("span",{'class':"score"}).get_text())
    reviews = reviews.split('K')[0]
    reviews = float(reviews)*1000
    reviews = int(reviews)
    
    # Genres
    genres = (soup.find("span",{'class':"ipc-chip__text"}).get_text())

    # Language
    
    
    # Country
    
    
    # Budget
    meta = (soup.find("div" ,{'class':"ipc-metadata-list-item__label ipc-metadata-list-item__label--link"}))
    
    
    # Gross box Office Revenue
    gross = (soup.find("span",{'class':"ipc-metadata-list-item__list-content-item"}).get_text())
    
    # Combine
    movie_dict={
        'Rank':x+1,
        'ID': 0,
        'Movie Name' : Movie_name,
        'Year' : year,
        'Length' : 0,
        'Director' : director,
        'Stars' : stars,
        'Rating' : rating,
        'Number of Reviewes' : reviews,
        'Genres' : genres,
        'Language': 0,
        'Country': 0,
        'Budget' : 0,
        'Gross box Office Revenue' :0}
    
    df = df.append(pd.DataFrame.from_records([movie_dict],columns=movie_dict.keys() ) )

我找不到获取丢失信息的方法。如果这里有人对这种话题有经验,并且可以分享他的想法,那将帮助很多人。我认为这个任务并不新鲜并且已经解决了数百次,但是 IMDb 改变了它们 HTML 中的类和结构。

提前致谢。

【问题讨论】:

  • 为什么不for url in top_250_links:
  • 缺少什么信息?
  • 如果您使用真实的 URL 创建最少的工作代码,它可能会简单得多 - 所以我们可以简单地复制和测试它(并使用它来创建解决方案)
  • 看来您可以使用 data-testid="title-details-languages" 来获取包含语言的行 - 然后使用另一个 find() 在此行内搜索 ul - soup.find({'data-testid':"title-details-languages"}).find('ul')。或者直接使用 select() 和 CSS 选择器 - soup.select('data-testid="title-details-languages" ul')

标签: python html web-scraping beautifulsoup imdb


【解决方案1】:

BeautifulSoup 有很多搜索元素的功能。很高兴阅读所有documentation

您可以使用许多.find().parent 等创建更复杂的代码。

soup.find(text='Language').parent.parent.find('a').text

对于某些元素,您还可以使用data-testid="...."

soup.find('li', {'data-testid': 'title-details-languages'}).find('a').text

最小男性工作代码(The Shawshank Redemption

import requests
from bs4 import BeautifulSoup as BS

url = 'https://www.imdb.com/title/tt0111161/?pf_rd_m=A2FGELUUNOQJNL&pf_rd_p=1a264172-ae11-42e4-8ef7-7fed1973bb8f&pf_rd_r=A453PT2BTBPG41Y0HKM8&pf_rd_s=center-1&pf_rd_t=15506&pf_rd_i=top&ref_=chttp_tt_1'

response = requests.get(url)
soup = BS(response.text, 'html.parser')

print('Language:', soup.find(text='Language').parent.parent.find('a').get_text(strip=True))
print('Country of origin:', soup.find(text='Country of origin').parent.parent.find('a').get_text(strip=True))

for name in ('Language', 'Country of origin'):
    value = soup.find(text=name).parent.parent.find('a').get_text(strip=True)
    print(name, ':', value)

print('Language:', soup.find('li', {'data-testid':'title-details-languages'}).find('a').get_text(strip=True))
print('Country of origin:', soup.find('li', {'data-testid':'title-details-origin'}).find('a').get_text(strip=True))

for name, testid in ( ('Language', 'title-details-languages'), ('Country of origin', 'title-details-origin')):    
    value = soup.find('li', {'data-testid':testid}).find('a').get_text(strip=True)
    print(name, ':', value)

结果:

Language: English
Country of origin: United States

Language : English
Country of origin : United States

Language: English
Country of origin: United States

Language : English
Country of origin : United States

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-05
    • 2015-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多