1 练习目标
本次练习爬取豆瓣电影TOP250的数据,并保存到csv文件中。
爬取的信息采集自豆瓣电影TOP250列表中的数据摘要,包括影名(name)、导演(director)、演员(actor)、电影类型(style)、国家地区(country)、上映日期(release_time)和评分(score)。
2 爬取网址
https://movie.douban.com/top250
3 URL分析
点击第2页,第3页我们看到网址分别是
https://movie.douban.com/top250?start=25&filter=
https://movie.douban.com/top250?start=50&filter=
可以发现url的构建规则还是很简单的,页面增加1页,start
的值增加25。
4 爬虫练习
本次分别采用BS4和Xpath两种解析方式来爬取。需要注意的是豆瓣具有反爬机制,大家在练习的时候一定要注意爬取的频率,以免被封ip。
4.1 BS4解析
import requests
from bs4 import BeautifulSoup
import pandas as pd
def get_movie_info(url):
# 定义请求头,模拟浏览器访问
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'
}
# 发送GET请求
response = requests.get(url, headers=headers)
# 使用BeautifulSoup解析HTML
soup = BeautifulSoup(response.text, 'lxml')
movie_list = []
# 遍历每一部电影的信息
for movie in soup.find_all('div', class_='info'):
# 获取电影名
name = movie.find('span', class_='title').text
# 获取导演和演员信息
info = movie.find('div', class_='bd').p.text.strip().split('\n')
director_and_actor = info[0].strip().split('\xa0\xa0\xa0')
director = director_and_actor[0][3:]
actor = director_and_actor[1][3:] if len(director_and_actor) > 1 else '未知'
# 获取电影类型、国家地区、上映日期和片长
other_info = info[1].strip().split('/')
style = other_info[2].strip()
country = other_info[1].strip()
release_time = other_info[0].strip()
# 获取评分
score = movie.find('span', class_='rating_num').text
# 将电影信息添加到列表中
movie_list.append([name, director, actor, style, country, release_time, score])
return movie_list
def save_to_csv(movie_list):
# 将列表转换为DataFrame
df = pd.DataFrame(movie_list, columns=['电影名', '导演', '演员', '类型', '国家/地区', '公映时间', '评分'])
# 将DataFrame保存为CSV文件
df.to_csv('douban_top250.csv', index=False, encoding='utf_8_sig')
if __name__ == '__main__':
base_url = 'https://movie.douban.com/top250?start={}&filter='
all_movies = []
# 遍历所有页面
for i in range(10):
url = base_url.format(i * 25)
all_movies.extend(get_movie_info(url))
save_to_csv(all_movies)
4.2 Xpath解析
import requests
from lxml import etree
import pandas as pd
def get_movie_info(url):
# 定义请求头,模拟浏览器访问
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'
}
# 发送GET请求
response = requests.get(url, headers=headers)
# 使用lxml的HTML解析器解析响应
html = etree.HTML(response.text)
movie_list = []
# 遍历每一部电影的信息
for movie in html.xpath('//div[@class="info"]'):
# 获取电影名
name = movie.xpath('.//span[@class="title"]/text()')[0]
# 获取导演和演员信息
director_and_actor = movie.xpath('.//div[@class="bd"]/p/text()[1]')[0].strip().split('\xa0\xa0\xa0')
director = director_and_actor[0][3:]
# 如果没有列出演员信息,将演员字段设置为'未知'
actor = director_and_actor[1][3:] if len(director_and_actor) > 1 else '未知'
# 获取电影类型、国家地区、上映日期和片长
other_info = movie.xpath('.//div[@class="bd"]/p/text()[2]')[0].strip().split('/')
style = other_info[2].strip()
country = other_info[1].strip()
release_time = other_info[0].strip()
# 获取评分
score = movie.xpath('.//span[@class="rating_num"]/text()')[0]
# 将电影信息添加到列表中
movie_list.append([name, director, actor, style, country, release_time, score])
return movie_list
def save_to_csv(movie_list):
# 将列表转换为DataFrame
df = pd.DataFrame(movie_list, columns=['电影名', '导演', '演员', '类型', '国家/地区', '公映时间', '评分'])
# 将DataFrame保存为CSV文件
df.to_csv('douban_top250.csv', index=False, encoding='utf_8_sig')
if __name__ == '__main__':
base_url = 'https://movie.douban.com/top250?start={}&filter='
all_movies = []
# 遍历所有页面
for i in range(2):
url = base_url.format(i * 25)
# 获取电影信息
all_movies.extend(get_movie_info(url))
# 保存电影信息到CSV文件
save_to_csv(all_movies)