1 練習(xí)目標(biāo)
本次練習(xí)爬取豆瓣電影TOP250的數(shù)據(jù),并保存到csv文件中栓辜。
爬取的信息采集自豆瓣電影TOP250列表中的數(shù)據(jù)摘要督函,包括影名(name)沽瞭、導(dǎo)演(director)、演員(actor)豆同、電影類型(style)番刊、國(guó)家地區(qū)(country)、上映日期(release_time)和評(píng)分(score)影锈。
2 爬取網(wǎng)址
https://movie.douban.com/top250
3 URL分析
點(diǎn)擊第2頁(yè)芹务,第3頁(yè)我們看到網(wǎng)址分別是
https://movie.douban.com/top250?start=25&filter=
https://movie.douban.com/top250?start=50&filter=
可以發(fā)現(xiàn)url的構(gòu)建規(guī)則還是很簡(jiǎn)單的蝉绷,頁(yè)面增加1頁(yè),start
的值增加25锄禽。
4 爬蟲練習(xí)
本次分別采用BS4和Xpath兩種解析方式來爬取潜必。需要注意的是豆瓣具有反爬機(jī)制,大家在練習(xí)的時(shí)候一定要注意爬取的頻率沃但,以免被封ip磁滚。
4.1 BS4解析
import requests
from bs4 import BeautifulSoup
import pandas as pd
def get_movie_info(url):
# 定義請(qǐng)求頭,模擬瀏覽器訪問
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'
}
# 發(fā)送GET請(qǐng)求
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
# 獲取導(dǎo)演和演員信息
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 '未知'
# 獲取電影類型宵晚、國(guó)家地區(qū)垂攘、上映日期和片長(zhǎng)
other_info = info[1].strip().split('/')
style = other_info[2].strip()
country = other_info[1].strip()
release_time = other_info[0].strip()
# 獲取評(píng)分
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):
# 將列表轉(zhuǎn)換為DataFrame
df = pd.DataFrame(movie_list, columns=['電影名', '導(dǎo)演', '演員', '類型', '國(guó)家/地區(qū)', '公映時(shí)間', '評(píng)分'])
# 將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 = []
# 遍歷所有頁(yè)面
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):
# 定義請(qǐng)求頭,模擬瀏覽器訪問
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'
}
# 發(fā)送GET請(qǐng)求
response = requests.get(url, headers=headers)
# 使用lxml的HTML解析器解析響應(yīng)
html = etree.HTML(response.text)
movie_list = []
# 遍歷每一部電影的信息
for movie in html.xpath('//div[@class="info"]'):
# 獲取電影名
name = movie.xpath('.//span[@class="title"]/text()')[0]
# 獲取導(dǎo)演和演員信息
director_and_actor = movie.xpath('.//div[@class="bd"]/p/text()[1]')[0].strip().split('\xa0\xa0\xa0')
director = director_and_actor[0][3:]
# 如果沒有列出演員信息淤刃,將演員字段設(shè)置為'未知'
actor = director_and_actor[1][3:] if len(director_and_actor) > 1 else '未知'
# 獲取電影類型晒他、國(guó)家地區(qū)、上映日期和片長(zhǎng)
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()
# 獲取評(píng)分
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):
# 將列表轉(zhuǎn)換為DataFrame
df = pd.DataFrame(movie_list, columns=['電影名', '導(dǎo)演', '演員', '類型', '國(guó)家/地區(qū)', '公映時(shí)間', '評(píng)分'])
# 將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 = []
# 遍歷所有頁(yè)面
for i in range(2):
url = base_url.format(i * 25)
# 獲取電影信息
all_movies.extend(get_movie_info(url))
# 保存電影信息到CSV文件
save_to_csv(all_movies)