#爬取豆瓣TOP250电影信息
import requests
from bs4 import BeautifulSoup # 网页解析,获取数据
import re # 正则表达式,进行文字匹配
import xlwt # 进行excel操作
#import sqlite3 # 进行SQLite数据库操作
# 创建正则表达式对象,标售规则
findLink = re.compile(r'<a href="(.*?)">') # 影片详情链接
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) # 导演,主演,电影信息
# re.S 使.匹配包括换行在内的所有字符
# 主运行函数
def main():
www = "https://movie.douban.com/top250?start=" #要爬取的网页链接
# 1.爬取网页
datalist = getData(www)
# 2.当前目录新建XLS,存储进去
savename = "豆瓣电影Top250.xls"
# 3.保存数据
saveData(datalist, savename)
# 爬取网页
def getData(WWW):
datalist = [] #创建空列表,用来存储爬取的网页信息
for i in range(0, 10): # 调用获取页面信息的函数,因为有10页所以要循环10次
url = WWW + str(i * 25)# https://movie.douban.com/top250?start=(0, 25, 50, ......)表示第一页,第二页,第三页......
html = askURL(url) # 保存获取到的网页源码
# 逐一解析数据
soup = BeautifulSoup(html, "html.parser")# html.parser是python内置的HTML解析器,必备
for item in soup.find_all('div', class_="item"): # 依次查找class属性为'item'的<div>标签的字符串,并依次存储信息,直到整个页面查找完毕
data = [] # 创建一个新的列表,保存一部电影所有信息
item = str(item) # 将item转化为字符串类型,用于下方re.findall
link = re.findall(findLink, item)[0] # 通过正则表达式查找,[0]在这里的意思是,取re.findall返回的匹配列表中的第一个元素
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)
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+)', "", bd)# 不知道为啥,爬取的网页信息里<br>里面会带有一个'/',变成<br/>,使用正则表达式选择的时候要注意,再进行替换操作
bd = re.sub('/', "", bd)# 删除多余的'/'
data.append(bd.strip()) # .strip()用于去除字符串开头和结尾的空白字符
datalist.append(data)
return datalist
# 得到指定一个URL的网页内容
def askURL(url):
head = { # 模拟浏览器头部信息,向豆瓣服务器发送消息
"User-Agent": "Mozilla / 5.0(Windows NT 10.0; Win64; x64) AppleWebKit / 537.36(KHTML, like Gecko) Chrome / 80.0.3987.122 Safari / 537.36"
}
# 用户代理,表示告诉豆瓣服务器,我们是什么类型的机器、浏览器(本质上是告诉浏览器,我们可以接收什么水平的文件内容)
response = requests.get(url, headers=head)# import requests中的get请求获取网页信息
html = ""# 建立空字符串,用于存储网页信息
try:
html = response.text
except requests.RequestException as e:# requests.RequestException包含requests库中所有错误的信息
# 如果上述try抛出了一个异常,这个异常会被捕获,并将异常信息赋值给e
if hasattr(e, "status_code"):# 检查异常对象e,如果e中包含status_code属性的信息,status_code 属性包含响应的状态码,比如 404(未找到)或 500(服务器错误)
print(e.status_code)# 输出e中status_code属性的信息
if hasattr(e, "reason"):# 同理
print(e.reason)
#这段代码的作用是尝试获取 HTTP 请求的响应内容,如果在这个过程中出现了异常(例如网络问题、服务器错误等),则会捕获这个异常,并打印出相应的状态码和错误原因。这样做可以帮助调试和了解为什么请求失败了。
# hasattr(object, name)
# object:要检查的对象。
# name:字符串形式的属性名称,用于检查该属性是否存在于对象中。
return html
# 保存数据到表格
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) #创建工作表
yuanzu = ("电影详情链接", "图片链接", "影片中文名", "影片外国名", "评分", "评价数", "概况", "相关信息")
for i in range(0,8):
sheet.write(0, i, yuanzu[i]) #循环补充列名
for i in range(0,250):
data = datalist[i]
for j in range(0,8):
sheet.write(i+1, j, data[j]) #循环补充数据
book.save(savepath) #保存
if __name__ == "__main__": # 当程序执行时
# 调用函数
main()
print("爬取完毕!")
先有代码后学习,爬虫学习内容之多,还需继续努力!