python爬虫实战——豆瓣电影TOP250
一. 准备工作
网页分析
首先对豆瓣电影的网页URL进行分析:
豆瓣电影TOP250的首页是https://movie.douban.com/top250
而翻一页之后变成了 https://movie.douban.com/top250?start=25&filter=
不难发现此时最上面的电影显示的是第26名的电影,所以只需要修改网页链接中的25为指定数值,就可以模拟翻页功能
每页的URL不同之处:最后的数值 = (页数-1)* 25
编码规范
一般Python程序第一行加入 #coding=utf-8
保证代码中的中文被正确解释
Python文件中可以加入main函数用于测试程序
预备知识
向服务器请求html
数据:urllib
库或者request
库
解析html
内容:BeautifulSoup
和re
库
输出到excel:xlwt
库
二. 获取数据
获取指定URL对应的HTML数据——askURL函数
def askURL(url):
# 用户代理,让服务器知道我们是什么类型的机器和浏览器
# 告诉服务器我们可以接受什么类型的信息
head = { # 模拟浏览器头部信息
"User-Agent":
"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 "
"Safari/537.36 "
}
request = urllib.request.Request(url, headers=head)
html = ""
try:
response = urllib.request.urlopen(request)
html = response.read().decode("utf-8")
# print(html)
except urllib.error.URLError as e:
if hasattr(e, "code"): # 如果有code标签,输出
print(e.code)
if hasattr(e, "reason"): # 如果有reason标签,输出
print(e.reason)
return html
重点:通过设定headers
信息伪装成浏览器向服务器请求数据
遍历所有包含所需信息的页面并获取HTML——getData函数第一部分
for i in range(0, 10): # 循环遍历10个页面
url = baseurl + str(i * 25)
html = askURL(url)
解析HTML页面并提取相应的数据——getData函数第二部分
# 2.解析数据
soup = BeautifulSoup(html, "html.parser")
for item in soup.find_all("div", class_="item"):
这一部分首先用bs4
中的BeautifulSoup
库解析HTML为树形结构,然后通过遍历查找所需信息
# 影片详情链接的匹配规则
findLink = re.compile(r'<a href="(.*?)">')
# 影片图片链接的匹配规则 re.S给.增加换行匹配的能力
findImgSrc = re.compile(r'<img.*src="(.*?)"', re.S)
# 影片片名
findTitle = re.compile(r'<span class="title">(.*)</span>')
# 影片评分
findRating = re.compile(r'<span class="rating_num" property="v:average">(.*)</span>')
# 找到评价人数
findJudge = re.compile(r'<span>(\d*)人评价</span>')
# 找到概况
findInq = re.compile(r'<span class="inq">(.*)</span>')
# 找到影片的相关内容
findBd = re.compile(r'<p class="">(.*?)</p>', re.S)
重点:通过F12查看豆瓣电影网站的源代码,找出各个信息所在的特定标签,并且通过正则表达式的方式匹配到所需信息
按照一定格式存储所提取的电影信息——getData函数第三部分
data = [] # 保存一部电影的所有信息
item = str(item)
link = re.findall(findLink, item)[0] # 查找影片详情链接
data.append(link)
imgSrc = re.findall(findImgSrc, item)[0] # 查找图片来源
data.append(imgSrc)
titles = re.findall(findTitle, item) # 片名可能有多个
if len(titles) == 2: # 分情况添加到data中
ctitle = titles[0] # 添加中文名
data.append(ctitle)
otitle = titles[1].replace("/", "") # 去掉一些无关紧要的信息
data.append(otitle) # 添加外国名
else:
data.append(titles[0]) # 没有外国名的时候也要添加一个空信息
data.append(' ') # 这样才能保证结果输出到表格中的时候是对齐的
rating = re.findall(findRating, item)[0] # 查找评分
data.append(rating)
judgeNum = re.findall(findJudge, item)[0] #查找打分的人数
data.append(judgeNum)
inq = re.findall(findInq, item) # 查找影片概述
if len(inq) != 0:
inq = inq[0].replace("。", "")
data.append(inq) # 添加概述
else:
data.append(" ")
bd = re.findall(findBd, item)[0] # 查找其他相关信息
bd = re.sub('<br(\s+)?/>(\s+)?', "", bd) # 去掉多余的空格
bd = re.sub('/', "", bd)
data.append(bd.strip())
datalist.append(data)
重点:当某些影片不存在相应的信息时(例如外国名),要给添加空数据,以保证每个影片的data能对齐输入表格中
三. 储存数据
excel形式存储数据——saveDate
函数
def saveData(datalist, savepath):
workbook = xlwt.Workbook(encoding="utf-8", style_compression=0)
worksheet = workbook.add_sheet('豆瓣电影Top250', cell_overwrite_ok=True)
col = ("电影详情链接", "图片链接", "影片中文名", "影片外文名", "评分", "评价人数", "概况", "相关信息")
for i in range(0, 8): # 先输入表格的抬头
worksheet.write(0, i, col[i])
for i in range(0, 250):
print("第%d条录入" % (i + 1))
data = datalist[i]
for j in range(0, 8): # 逐条录入信息
worksheet.write(i + 1, j, data[j])
workbook.save(savepath)
重点:给定表格的话横纵坐标,之后输入响应信息即可
四.总结与反思
之前在中国大学MOOC学了python爬虫的内容,但是因为课程比较早,所以给出的实战案例爬取对象的网站已经不存在了,所以就想找个项目练习一下所学的知识。
本项目参考了https://www.bilibili.com/video/BV12E411A7ZQ/的相关教学
感觉总体上来说,python爬取静态网页并且输出到excel还是比较简单的,代码量比较小而且容易上手。不过最大的问题在于这种方法只能爬取静态网页,而对用JavaScript动态生成内容的网页无能为力。希望以后能进一步学习爬取动态网页的技术。
还有一个问题是数据虽然得到了,但是excel里内容太繁杂了,实际看起来还不如直接去豆瓣电影的网页看。所以爬取数据之后的展示和分析,可能也需要学习相关的技术。