如何用BeautifulSoup抓取Yidio网站超100条电影数据?
解决Yidio电影数据动态加载抓取问题
你的代码只能获取100条数据,是因为requests.get仅能拿到页面初始加载的静态内容,而滚动时的新数据是通过分页接口动态加载的。要抓取至少1000条数据,可以通过循环请求分页页面的方式实现,具体方案如下:
实现步骤
- 识别分页接口:观察浏览器开发者工具的网络请求,发现滚动页面时会请求
https://www.yidio.com/movies?page=N(N为页码,每页返回100条电影)。 - 批量收集电影链接:循环请求page=1到page=10的页面,提取所有电影卡片的链接。
- 添加反爬措施:设置请求头模拟浏览器行为,添加请求间隔避免触发反爬机制。
- 复用原有详情抓取逻辑:对收集到的所有链接,逐个抓取电影信息并保存。
修改后的完整代码
import requests from bs4 import BeautifulSoup import pandas as pd import time # 配置请求头,模拟浏览器访问 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36' } movies_info = { 'Title': [], 'Genres': [], 'Cast': [], 'Director': [], 'Release Date': [], 'MPAA Rating': [], 'Runtime': [], 'Language': [], 'IMDB Rating': [], 'Metascore': [] } def get_movie_links(total_pages=10): """批量获取指定页数的电影链接""" all_urls = [] base_url = 'https://www.yidio.com/movies?page={}' for page in range(1, total_pages + 1): print(f'正在抓取第 {page} 页的电影链接...') url = base_url.format(page) response = requests.get(url, headers=headers) if response.status_code != 200: print(f'第 {page} 页请求失败,状态码:{response.status_code}') continue soup = BeautifulSoup(response.content, 'lxml') movie_links = soup.find_all('a', class_='card movie') page_urls = [link['href'] for link in movie_links] all_urls.extend(page_urls) # 每次请求后暂停1秒,避免请求过于频繁 time.sleep(1) print(f'共收集到 {len(all_urls)} 条电影链接') return all_urls def get_movie_info(url): """抓取单部电影的详细信息""" try: response = requests.get(url, headers=headers) response.raise_for_status() # 抛出请求异常 soup = BeautifulSoup(response.content, 'lxml') # 提取电影标题 movie_title = soup.find('h1').text.strip().split(' ', 1)[1] print(f'正在处理电影:{movie_title}') # 以下补充你原有的信息提取逻辑 # 示例:提取 genres genres = soup.find('div', class_='genres') genre_text = genres.text.strip() if genres else None # 提取导演、演员等其他字段,根据你的原有代码补充 # ... # 将信息存入字典 movies_info['Title'].append(movie_title) movies_info['Genres'].append(genre_text) # 其他字段对应添加 # ... except Exception as e: print(f'处理电影链接 {url} 时出错:{str(e)}') # 出错时填充空值,避免数据结构不一致 for key in movies_info.keys(): movies_info[key].append(None) def main(): # 获取所有电影链接(默认10页,共1000条) urls = get_movie_links(total_pages=10) # 逐个抓取电影详情 for url in urls: get_movie_info(url) # 暂停0.5秒,避免请求过快 time.sleep(0.5) # 生成DataFrame并保存 movies_df = pd.DataFrame(movies_info) movies_df = movies_df.dropna(subset=['MPAA Rating', 'IMDB Rating', 'Metascore']) movies_df.to_csv('movies_info.csv', index_label='id') print('==========================================================') print(f'共保存 {len(movies_df)} 条有效电影信息到 movies_info.csv') if __name__ == '__main__': main()
关键说明
- 分页循环:通过
total_pages参数控制抓取的页数,设置为10即可获取1000条左右的电影链接。 - 请求头:添加
User-Agent模拟浏览器,避免被服务器识别为爬虫。 - 请求间隔:
time.sleep()函数用于控制请求频率,降低被反爬拦截的风险。 - 异常处理:为
get_movie_info添加异常捕获,避免单个链接出错导致程序中断。
内容的提问来源于stack exchange,提问作者Tahar Jaafer
相关产品推荐
相关产品推荐

