该项目大致分为以下步骤:
- 使用 requests库 获取页面
- 使用 lxml库 和 XPath 解析页面
- 爬取电影海报图片
- 使用 pandas库 将电影的相关信息存储为csv文件
- 添加循环,保存所有图片以及相关信息
首先,我们构建一个框架来获取豆瓣电影的HTML页面:
import requests
def get_html(url):
"""
获取HTML页面
Parameters
----------
url : string
URL链接
Returns
-------
HTML
HTML页面
"""
headers = {'User-Agent':"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36"}
try:
html = requests.get(url, headers=headers)
html.encoding = html.apparent_encoding
if html.status_code == 200:
print("获取HTML页面成功!")
except Exception as e:
print("获取HTML页面失败,原因是:%s" % e)
return html.text
if __name__ == '__main__':
url = "https://movie.douban.com/top250"
html = get_html(url)
接下来,我们分析一下豆瓣电影的网页:
使用开发者工具(F12),经过分析,可以发现每一页的电影信息都是这些li标签:
![](https://i-blog.csdnimg.cn/blog_migrate/1bffe180515c1fe86bc2fe59e361afea.png)
我们用 XPath Helper 获取这些li标签:
![](https://i-blog.csdnimg.cn/blog_migrate/9db88e38df02d3f3aec60d0503ced8fe.png)
在刚才获取的li标签下继续分析电影相关信息:
首先是电影名字:
![](https://i-blog.csdnimg.cn/blog_migrate/f318c4e947af89d2194d87e905adc7c6.png)
接下来是导演主演信息:
![](https://i-blog.csdnimg.cn/blog_migrate/ce041ee70d1ef3d3734e3650b205ea49.png)
然后是年份、国家和电影类型:
![](https://i-blog.csdnimg.cn/blog_migrate/736960c314eaf7997583f266a3b42afb.png)
接下来是电影评分:
![](https://i-blog.csdnimg.cn/blog_migrate/dcfeaf0315f88cbf3cd31470b7a8ea23.png)
然后是评价人数:
![](https://i-blog.csdnimg.cn/blog_migrate/18df61ae148fb20025029b2792755a64.png)
接下来是简介:
![](https://i-blog.csdnimg.cn/blog_migrate/d4debbc9e261e538ae059eeb62f95cb4.png)
(这里发现Top 247的那部电影没有简介,所以后面需要处理一下)
最后是电影海报图片:
![](https://i-blog.csdnimg.cn/blog_migrate/4fc61447bca3bb13d0d780b75ac97c9f.png)
分析完页面之后,我们写一下解析页面的函数:
from lxml import etree # 解析HTML页面
def parse_html(html):
"""
解析HTML页面
Parameters
----------
html : HTML
爬取的HTML页面
Returns
-------
movies : list
电影信息
imgurls : list
电影海报图片
"""
movies = [] # 存储电影的相关信息
imgurls = [] # 存储电影海报图片
html = etree.HTML(html)
lis = html.xpath("//ol[@class='grid_view']/li") # XPath返回列表对象
# 提取每一部电影的相关信息
for li in lis:
# 下面的XPath路径前面都要加上. 表示从li这个节点开始
name = li.xpath(".//a/span[@class='title'][1]/text()")[0] # 获取到的列表第0个元素才是电影名字
director_actor = li.xpath(".//div[@class='bd']/p/text()[1]")[0].replace(' ','').replace('\n','').replace('/','').replace('\xa0', '') # 去除字符串中的多余字符
info = li.xpath(".//div[@class='bd']/p/text()[2]")[0].replace(' ','').replace('\n','').replace('\xa0', '') # 去除字符串中的多余字符
rating_score = li.xpath(".//span[@class='rating_num']/text()")[0]
rating_num = li.xpath(".//div[@class='star']/span[4]/text()")[0]
introduce = li.xpath(".//p[@class='quote']/span/text()")
# 把提取的相关信息存入movie字典,顺便处理Top 247那部电影没有introduce的情况
if introduce:
movie = {'name': name, 'director_actor': director_actor, 'info': info, 'rating_score': rating_score,
'rating_num': rating_num, 'introduce': introduce[0]}
else:
movie = {'name': name, 'director_actor': director_actor, 'info': info, 'rating_score': rating_score,
'rating_num': rating_num, 'introduce': None}
movies.append(movie)
imgurl = li.xpath(".//img/@src")[0] # 提取图片URL
imgurls.append(imgurl)
return movies, imgurls
if __name__ == '__main__':
url = 'https://movie.douban.com/top250'
html = get_html(url)
movies = parse_html(html)[0]
imgurls = parse_html(html)[1]
测试时发现 director_actor 和 info 有 \xa0不间断空白符:
用.replace(’\xa0’, ‘’)语句去除。
接下来编写保存电影海报图片的函数:
import os
def download_img(url, movie):
"""
保存海报图片
Parameters
----------
url : string
图片文件链接
movie : dict
电影信息
Returns
-------
None.
"""
if 'movieposter' in os.listdir(r'S:\DouBan'):
pass
else:
os.mkdir('movieposter')
os.chdir(r'S:\DouBan\movieposter')
img = requests.get(url).content # 返回的是bytes型也就是二进制的数据
with open(movie['name'] + '.jpg', 'wb') as f:
f.write(img)
最后添加循环,爬取所有电影的海报图片以及相关信息:
每一页有25部电影,一共十页:
每一页的URL通过以下方式决定:
import pandas as pd
if __name__ == '__main__':
MOVIES = []
IMGURLS = []
for i in range(10):
url = "https://movie.douban.com/top250?start=" + str(i*25) + "&filter="
html = get_html(url)
movies = parse_html(html)[0]
imgurls = parse_html(html)[1]
MOVIES.extend(movies)
IMGURLS.extend(imgurls)
for i in range(250):
download_img(IMGURLS[i], MOVIES[i])
print("正在下载第" + str(i+1) + "张图片……")
os.chdir(r'S:\DouBan') # 记得把路径换回来
moviedata = pd.DataFrame(MOVIES) # 把电影相关信息转换为DataFrame数据格式
moviedata.to_csv('movie.csv')
print("电影相关信息存储成功!")
运行代码:
![](https://i-blog.csdnimg.cn/blog_migrate/c036e4c1e6a531d155f2ddf9e43c9bca.png)
![](https://i-blog.csdnimg.cn/blog_migrate/e768cb6668f104c609130e5402cbb0be.png)
![](https://i-blog.csdnimg.cn/blog_migrate/dd888561f04503f891d52e3faa34e00f.png)
![](https://i-blog.csdnimg.cn/blog_migrate/0e0969c76372a9c25abe789181f8ace9.png)
![](https://i-blog.csdnimg.cn/blog_migrate/5d08cc39c9f93e5546cb611338e0f0ff.png)