第一步 导入各功能模块
import requests
import pandas as pd
from bs4 import BeautifulSoup
import numpy as np
import time
本次要爬取的数据如图
第二步 找到元素对应位置
- 回到“https://movie.douban.com/top250?start=0&filter=”网页👉点击F12👉点击对应位置元素
- 1、找到了 li这个模块有我们所要的关键信息;
- 2、li往下一层级找,找到了我们对应下一级信息 【div class=“item”】,如图中2所示;
- 3、在【div class=“item”】下分了两个class,一个是如图3所示,【div class=“info”】可以找到【title】中的电影名;
- 4、在【div class=“item”】的【div class=“info”】中,可以找到我们要的评分和评价人数,如图中4所示;
第三步 使用requests下载网页源码
- 做案例打样
headers = {
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36'
} # 模拟游览器登陆,这个不需要变动
re = requests.get('https://movie.douban.com/top250?start=0&filter=', headers=headers) # 解析网页源码
re.encoding = re.apparent_encoding
soup = BeautifulSoup(re.text,"html.parser") # 用bs库进行解析
使用find_all(“li”)找到对应位置
第四步 标准化源码
- 建议自己拆解各步骤原理,一步一步print出来看
def for_list():
"""
爬取豆瓣电影Top250
总体的方法是建立两个list,进行拼接生成表结构。
如:list = [排名1,评分1,评分人数1,电影名1,电影名2]
再统一写进大的list里变成如下:
totali_list = [ [排名1,评分1,评分人数1,电影名1,电影名21],
[排名2,评分2,评分人数3,电影名2,电影名22],
[排名2,评分2,评分人数3,电影名3,电影名23]
....
[排名n,评分n,评分人数n,电影名n,电影名n]
]
便于我们在写入pd.DataFrame(totali_list)即可,无需调整其他部分
"""
lis = []
for i in soup.find_all("li"):
# 排名
if i.find("div",class_="item"):
rank_ = i.find("em",class_="").text
list_ = []
list_.append(rank_)
# 电影名
for i_2 in i.find_all("div" , class_="star"):
#评分
score_ = i_2.find("span",class_="rating_num").text
list_.append(score_)
# 评价人数
list_3 = []
for i_3 in i_2.find_all("span"):
if i_3.text == "":
pass
else:
list_3.append(i_3.text)
list_.append(list_3[1].replace("人评价",""))
for i_1 in i.find_all("div" , class_="info"):
if "span" in str(i_1):
title = i.find_all("span" ,class_="title")
# 电影名称
# title正常会取出两个,但是也有只有一个的情况,所以需要填充为“空”
for i_ in title:
if len(title) == 2:
list_.append(i_.text.replace("/",""))
if len(title) < 2:
list_.append(i_.text.replace("/",""))
list_.append("空")
lis.append(list_)
df = pd.DataFrame(lis,columns=["排名","评分","评分人数","电影名称","电影名称2"])
return df
- 将各网页进行循环
headers = {
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36'
}
total_film_data = pd.DataFrame(columns=["排名","评分","评分人数","电影名称","电影名称2"])
for page in np.arange(10):
print("正在爬取第{0}页....".format(page+1))
re = requests.get('https://movie.douban.com/top250?start={0}&filter='.format(str(page*25)), headers=headers)
time.sleep(5)
re.encoding = re.apparent_encoding
soup = BeautifulSoup(re.text,"html.parser") # 使用bs库对down下来的数据进行解析
df = for_list()
total_film_data = pd.concat([total_film_data,df])
print("第{0}页已完成....".format(page+1))
- 完成
total_film_data
排名 | 评分 | 评分人数 | 电影名称 | 电影名称2 | |
---|---|---|---|---|---|
0 | 1 | 9.7 | 2563458 | 肖申克的救赎 | The Shawshank Redemption |
1 | 2 | 9.6 | 1904026 | 霸王别姬 | 空 |
2 | 3 | 9.5 | 1925502 | 阿甘正传 | Forrest Gump |
3 | 4 | 9.4 | 1887295 | 泰坦尼克号 | Titanic |
4 | 5 | 9.4 | 2082923 | 这个杀手不太冷 | Léon |
... | ... | ... | ... | ... | ... |
20 | 246 | 8.8 | 200353 | 末路狂花 | Thelma & Louise |
21 | 247 | 8.8 | 248565 | 聚焦 | Spotlight |
22 | 248 | 8.3 | 828482 | 驴得水 | 空 |
23 | 249 | 8.4 | 443104 | 小萝莉的猴神大叔 | Bajrangi Bhaijaan |
24 | 250 | 8.7 | 244353 | 浪潮 | Die Welle |
250 rows × 5 columns