import requests from bs4 import BeautifulSoup import pandas as pd import random def requests_get(url): user_agent_list = [ \ "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1", \ "Mozilla/5.0 (X11; CrOS i686 2268.111.0) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11", \ "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6", \ "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6", \ "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/19.77.34.5 Safari/537.1", \ "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.9 Safari/536.5", \ "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.36 Safari/536.5", \ "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3", \ "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3", \ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_0) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3", \ "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3" ] user_agent = random.choice(user_agent_list) headers = { "User-Agent": user_agent } try: response = requests.get(url, headers=headers) response.raise_for_status() return response.text except requests.exceptions.RequestException as e: print(f"请求失败: {e}") return None def get_movie_info(url): # BeautifulSoup的三个方法find: # 返回的是第一个符合条件的数据 # 。可以根据title的值来找到对应的标签对象 # ·根据class的值来找,需要在class下添加下划线find_a11 # ·返回的是一个列表,并且返回了匹配的所有的标签 # select # 有了如上基础,对源代码进行标签路径的分析,就可以取值了。 soup = BeautifulSoup(requests_get(url), 'html.parser') item_elements = soup.find_all("div", class_="item") # print(item_elements) movie_list = [] for item in item_elements: movie = {} # 获取电影排名 movie['ranking'] = item.find('em', class_='').get_text(strip=True) # 获取电影名称 movie['title'] = item.find('span', class_='title').get_text(strip=True) # 获取电影详情链接 movie['link'] = item.find('a', href=True)['href'] # 获取电影评分 movie['rating'] = item.find('span', class_='rating_num').get_text(strip=True) # 获取电影简介 try: movie['profile'] = item.find('span', class_='inq').get_text(strip=True) except AttributeError: movie['profile'] = '无' # 获取电影评价人数 span_list_len = len(item.find_all('span')) if span_list_len >= 6: num_reviews = item.find_all('span')[span_list_len - 2].get_text(strip=True).replace('人评价', '') movie['num_reviews'] = num_reviews # 获取电影海报链接 poster = item.find('img', class_='')['src'] movie['poster'] = poster # 获取电影类型与首映国家与上映年份 movie_infos = item.select('p', class_="")[0].text.strip() # print(movie_infos) if movie['title'] == '大闹天宫': movie['type'] = movie_infos.split('\n')[1].split('/')[4].strip() movie['country'] = movie_infos.split('\n')[1].split('/')[3].split(' ')[0].strip() else: movie['type'] = movie_infos.split('\n')[1].split('/')[2].strip() movie['country'] = movie_infos.split('\n')[1].split('/')[1].split(' ')[0].strip() # print(movie['type']) # print(movie['country']) movie['year'] = movie_infos.split('\n')[1].split('/')[0].strip(' ').strip('(中国大陆)') # print(movie['year']) # print(movie['country']) # 获取电影导演与上映时间 # 注意:因为时间想要一个年月日,所以直接进入详情页获取数据 # 且top页,一些导演名称太长,导致遮挡了主演的全称 # 这些都需要我们重新请求电影详情链接 movie_soup = BeautifulSoup(requests_get(movie['link']), 'html.parser') movie['director'] = movie_soup.find("a", rel="v:directedBy").get_text() # movie['year'] = movi_infose_soup.find("span", property="v:initialReleaseDate").get_text().split('(')[0] #获取片长 movie['time'] = movie_soup.find("span", property="v:runtime").get_text(strip=True).replace('片长','') #获取主演 #主演有些为空,所以需要我们定义异常处理 try: movie['actor'] = movie_soup.find("a", rel="v:starring").get_text(strip=True) except AttributeError: movie['actor'] = '无' # print(movie) movie_list.append(movie) return movie_list if __name__ == '__main__': print(requests_get('https://movie.douban.com/top250')) base_url = 'https://movie.douban.com/top250' movie_data = [] for page in range(10): start = page * 25 # url ='https://movie.douban.com/top250?start=50' url = f'{base_url}?start={start}' print(f"开始爬取第 {page + 1} 页: {url}") movies = get_movie_info(url) movie_data.extend(movies) print('爬取完成') df = pd.DataFrame(movie_data) # # 将数据保存为CSV文件 csv_file = 'flaskProject/data/export.csv' df.to_csv(csv_file, index=False, encoding='utf-8') print('存储完成')