# -*- codeing = utf-8 -*-
# @Time : 2021/8/11 18:50
# Author: hui
# @File : demo.py
# @Software : PyCharm
from bs4 import BeautifulSoup #网页解析,获取数据
import re #正则表达式,进行文字匹配
import urllib.error,urllib.request #指定URL,获取网页数据
import xlwt #进行Excel操作
import sqlite3 #进行sqlite3数据库操作
# 1、(爬取)获取网页数据
# 2、解析网页数据
# 3、存储数据
def main():
baseurl="https://movie.douban.com/top250?start="
#(爬取)获取网页数据
dataList=getData(baseurl)
# excel表存储数据
# savepath="豆瓣电影top10.xls"
# saveData(dataList,savepath)
#sqlite3数据库存储数据
dbpath="movie250.db"
saveData2db(dataList,dbpath)
#详细页面链接
findLink=re.compile(r'')# 指定findLink查找字符串规则
#电影名称
findName=re.compile(r'(.*)')
#电影图片
findIMGSrc=re.compile(r',re.S) #r为了避免转义字符,re.S忽略换行符
#评分
findRating=re.compile(r' ')
#评价人数
findNum=re.compile(r'(\d*)人评价')
#体会
findFeel=re.compile(r'(.*?)')
#影片的相关内容
findBD=re.compile(r'(.*?)
',re.S)
#边爬取数据边解析
def getData(baseurl):
dataList=[]
for i in range(0,10): #调用获取页面函数10次
url=baseurl+str(i*25)
html=askURL(url) #将获取内容返回到html中
#逐一解析数据
soup=BeautifulSoup(html,"html.parser") #使用BeautifulSoup中html.parser解析器来解析html中的内容,并保存在soup中
for item in soup.find_all('div',class_="item"):#以列表的形式查看soup中div下class属性=item的所有内容
data=[] #用于保存解析的数据
item=str(item) #将item中的信息转化为字符串格式
#查找电影详细信息的链接
link=re.findall(findLink,item)[0] #采用正则表达式查找item中符合findLink规则的所有字符串并返回第一个存在link中
data.append(link) #将链接添加到data列表中
img = re.findall(findIMGSrc, item)[0]
data.append(img)
#查找电影姓名
title=re.findall(findName,item)
if len(title)==2: #存在中英文名,如果名字等于2,则分别存储
ctitle=title[0] #中文名为title【0】,存在ctitle中
data.append(ctitle)
otitle=title[1].replace("/","") #英文名为title[1],存在otitle中并将英文名前的/用空代替
data.append(otitle)
else: #如果不存在英文名,直接保存title[0],并在title[1]的位置留空
data.append(title[0])
data.append(" ") #留空
rating= re.findall(findRating, item)[0]
data.append(rating)
num = re.findall(findNum, item)[0]
data.append(num)
feel = re.findall(findFeel, item)
if len(feel) !=0:
feel=feel[0].replace("。","")
data.append(feel)
else:
data.append(" ")
base = re.findall(findBD, item)[0] #规划格式
base=re.sub("
"," ",base) #将base中所有
用空代替
base=re.sub("/"," ",base) #将base中所有/用空代替
data.append(base.strip()) #strip()去掉base中的空格
dataList.append(data) #将每一个电影信息形成一个列表,加入dataList列表中
return dataList
#excel存储数据
# def saveData(dataList,savepath):
# book = xlwt.Workbook(encoding="utf-8")
# sheet = book.add_sheet('豆瓣电影top250')
# col=("电影链接",'图片链接','电影中文名称','英文名','评分','评分人数','电影概述','相关信息')
# for i in range (0,8):
# sheet.write(0,i,col[i])
# for i in range (0,250):
# print("第%d个"%(i+1))
# data=dataList[i]
# for j in range(0,8):
# sheet.write(i+1,j,data[j])
# book.save(savepath)
#sqlite3存储数据
def saveData2db(dataList,dbpath):
init_db(dbpath) #初始化数据库
conn = sqlite3.connect(dbpath)
cur = conn.cursor()
for data in dataList: #一个data为一条数据
for i in range(len(data)): #一个i为data的一列
if i == 4 or i == 5:
continue
data[i] = '"'+data[i]+'"' #字符链接,每个字符前后加上引号(双引号)
sql = '''
insert into movie250 ( /*存在缩进问题,保持书写格式*/
info_link,pic_link,cname,oname,score,people,feel,near)
values (%s)''' % ",".join(data) #是占位的数据,并将data中的数据用逗号连接(用双引号包围逗号)
cur.execute(sql)
conn.commit()
cur.close()
conn.close()
#初始化数据库
def init_db (dbpath):
sql='''
create table movie250
(
id integer primary key autoincrement,
info_link text,
pic_link text,
cname varchar ,
oname varchar ,
score numeric ,/*显示小数*/
people number ,
feel text,
near text
);
'''
conn=sqlite3.connect(dbpath) #连接数据库创建名为dbpath的数据库,存在则打开,不存在则创建
curson=conn.cursor() #获得游标,方便后续操作
curson.execute(sql) #执行sql语句
conn.commit() #提交数据库操作
conn.close() #关闭数据库
#获取指定URL页面的内容
def askURL(url):
header={
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36 SLBrowser/7.0.0.6241 SLBChan/32"
}
request=urllib.request.Request(url,headers=header)
html = ""
try:
response=urllib.request.urlopen(request)
html=response.read().decode("utf-8")
#print(html)
except Exception as e:
if hasattr(e,"code"):
print(e.code)
if hasattr(e,"reason"):
print(e.reason)
return html
if __name__=="__main__":
main()
print("爬取结束")