电影使用Python爬虫从豆瓣抓取Top 250 电影信息
使用Python爬虫 爬取豆瓣top250
文章目录
1)任务介绍
需求分析
爬取豆瓣电影Top250的基本信息,包括电影的
名称
、豆瓣评分
、评价数
、电影概况
、电影链接
等。链接:https://movie.douban.com/top250
2)爬虫知识
什么是爬虫
网络爬虫,是一种按照一定规则
,自动抓取
互联网信息的程序或者脚本。由于互联网数据的多样性和资源的有限性,根据用户需求定向
抓取相关网页并分析已成为入境主流的爬取策略。
爬虫可以做什么
你可以爬取妹子的照片,爬取自己想看的视频等等,只要你能通过浏览器访问的数据都可以通过爬虫获取
爬虫的本质是什么
模拟浏览器
打开网页,获取网页中我们想要的那部分数据
3)基本流程
3.1) 准备工作
通过浏览器查看分析目标网页
分析页面
Chrome开发者工具
(F12)来分析页面,在Elements下找到需要的数据位置编码规范
# -*- coding: utf-8 -*-
或者# coding = utf-8
这样可以在代码中包含中文def
关键词开头,后接空格
、函数标识符名称
、圆括号()
、冒号:
,括号中可以传入参数,函数段缩进
(Tab或者四个空格,只能任选一种),return
用于结束函数,可以返回一个值,也可以不带任何表达式(表示返回可以用None
)if_name_== "_main_":
#
添加注释,说明代码(段)的作用引入模块
3.2)获取数据
通过HTTP库向目标站点发起请求,请求可以包含额外的hrader等信息,如果服务器能正常响应,会得到一个Response,便是所要获取的页面内容。
try...except...
语句3.3)解析内容
得到的内容可能是HTML、json等格式,可以用
页面解析库
、正则表达式
等进行解析。
1. 标签解析
BeautifulSoup
<div>
的标签中,且每个div
标签都有一个属性class="item"
。2. 正则提取
正则表达式
检索
,替换
那些符合某个模式(规则)的文本。正则表达式是对字符串操作的一种逻辑公式,就是事先定义好一些特定字符以及这些特定字符的组合,组成一个“规则字符串”。这个“规则字符串”用来表达对字符串的一种过滤逻辑。python中使用re模块
操作正则表达式。正则表达模式
^
匹配字符串的开头
$
匹配字符串的末尾。
.
匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。
[...]
用来表示一组字符,单独列出:[amk] 匹配 ‘a’,‘m’或’k’
[^...]
不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符。
re*
匹配0个或多个的表达式。
re+
匹配1个或多个的表达式。
re?
匹配0个或1个由前面的正则表达式定义的片段,非贪婪方式
re{ n}
匹配n个前面表达式。例如,"o{2}“不能匹配"Bob"中的"o”,但是能匹配"food"中的两个o。
re{ n,}
精确匹配n个前面表达式。例如,"o{2,}“不能匹配"Bob"中的"o”,但能匹配"foooood"中的所有o。
"o{1,}“等价于"o+”。“o{0,}“则等价于"o*”。
re{ n, m}
匹配 n 到 m 次由前面的正则表达式定义的片段,贪婪方式
a| b
匹配a或b
(re)
匹配括号内的表达式,也表示一个组
(?imx)
正则表达式包含三种可选标志:i, m, 或 x 。只影响括号中的区域。
(?-imx)
正则表达式关闭 i, m, 或 x 可选标志。只影响括号中的区域。
(?: re)
类似 (…), 但是不表示一个组
(?imx: re)
在括号中使用i, m, 或 x 可选标志
(?-imx: re)
在括号中不使用i, m, 或 x 可选标志
(?#...)
注释.
(?= re)
前向肯定界定符。如果所含正则表达式,以 … 表示,在当前位置成功匹配时成功,否则失败。但一旦所含表达式已经尝试,匹配引擎根本没有提高;模式的剩余部分还要尝试界定符的右边。
(?! re)
前向否定界定符。与肯定界定符相反;当所含表达式不能在字符串当前位置匹配时成功。
(?> re)
匹配的独立模式,省去回溯。
\w
匹配数字字母下划线
\W
匹配非数字字母下划线
\s
匹配任意空白字符,等价于 [\t\n\r\f]。
\S
匹配任意非空字符
\d
匹配任意数字,等价于 [0-9]。
\D
匹配任意非数字
\A
匹配字符串开始
\Z
匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。
\z
匹配字符串结束
\G
匹配最后匹配完成的位置。
\b
匹配一个单词边界,也就是指单词和空格间的位置。例如, ‘er\b’ 可以匹配"never” 中的 ‘er’,但不能匹配 “verb” 中的 ‘er’。
\B
匹配非单词边界。‘er\B’ 能匹配 “verb” 中的 ‘er’,但不能匹配 “never” 中的 ‘er’。
\n, \t,
等。 匹配一个换行符。匹配一个制表符, 等
\1...\9
匹配第n个分组的内容。
\10
匹配第n个分组的内容,如果它经匹配。否则指的是八进制字符码的表达式。
3.4)保存数据
保存形式多样,可以存为文本也可以保存到数据库,或者保存特定格式的文件
1. Excel表储存数据
Excel表格储存
利用python库
xlwt
将抽取的数据datalist写入Excel表格from bs4 import BeautifulSoup # 网页解析,获取数据
import re # 正则表达,实现文字匹配
import urllib.request, urllib.error # 制定url,获取网页数据
import xlwt # 进行excel操作
import sqlite3 # 进行SQLite数据库操作
def main():
# 1.爬取网页
baseurl = "https://movie.douban.com/top250?start="
datalist = getData(baseurl)
savepath = "豆瓣电影Top250.xls"
# 3.保存数据
saveData(datalist, savepath)
# 影片链接的规则
findLink = re.compile(r'<a href="(.*?)">') # 创建正则表达式对象,表示规则(字符串表达式)
# 影片的图片的规则
findImgSrc = re.compile(r'<img.*src="(.*?)"', re.S) # 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)
def getData(baseurl):
datalist = []
for i in range(0, 10): # 调用获取页面信息的函数,10次
url = baseurl + str(i * 25)
html = askURL(url) # 保存获取到的网页源码
# 2.逐一解析数据
soup = BeautifulSoup(html, "html.parser")
for item in soup.find_all('div', class_="item"): # 查找符合要求的字符串,形成一个链表
# print(item) #测试
data = [] # 保存一部电影的所有信息
item = str(item)
link = re.findall(findLink, item)[0] # re库用来通过正则表达式查找指定内容
data.append(link)
imgSrc = re.findall(findImgSrc, item)[0] # 添加图片
data.append(imgSrc)
titles = re.findall(findTitle, item) # 片名可能只有一个中文名
if (len(titles) == 2):
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)
judgeNom = re.findall(findJudge, item)[0] # 添加评价人数
data.append(judgeNom)
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) # 去掉<br>
bd = re.sub('/', " ", bd) # 替换/
data.append(bd.strip()) # 去掉前后空格
datalist.append(data)
return datalist
def saveData(datalist, savepath):
print("save....")
book = xlwt.Workbook(encoding="utf-8", style_compression=0) # 创建workbook对象
sheet = book.add_sheet('豆瓣电影Top250', cell_overwrite_ok=True) # 创建工作表
col = ("电影详情链接", "图片链接", "影片中文名", "影片外国名", "评分", "评价数", "概况", "相关信息")
for i in range(0, 8):
sheet.write(0, i, col[i])
for i in range(0, 250):
print("第%d条" % i)
data = datalist[i]
for j in range(0, 8):
sheet.write(i + 1, j, data[j])
book.save(savepath)
def askURL(url):
head = {"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:90.0) Gecko/20100101 Firefox/90.0"}
request = urllib.request.Request(url, headers=head)
html = ""
try:
response = urllib.request.urlopen(request)
html = response.read().decode("utf-8")
except urllib.error.URLError as e:
if hasattr(e, "code"):
print(e.code)
if hasattr(e, "reason"):
print(e.reason)
return html
if __name__ == '__main__':
main()
print("爬取完毕")