使用Python对豆瓣TOP250网页进行爬取
ps.此博客是根据B站视频Python爬虫基础5天速成(2021全新合集)Python入门+数据可视化 所进行的练习,更详细的做法可直接观看原视频,如有问题请及时联系我以作处理。
一.抓取网页信息
- 由下图可知豆瓣Top250的网页地址,再由箭头所指的方向可以得知start所指的为电影的页数*25,
由此可以得知电影的基本网址
baseurl="https://movie.douban.com/top250?start="
- 再通过F12可以得知浏览器所接受请求标头信息
-
由此我们可以写一个得到一个指定的URL网页内容的方法:
首先我们将之后要用到的包给引进来
from bs4 import BeautifulSoup #网页解析 import re #正则表达式 import urllib.request,urllib.response #制定URL,获取网页数据 import xlwt #进行excel操作 import sqlite3 #进行sqlite数据库操作
askURL方法:
# 得到一个指定的URL网页内容
def askURL(url):
head = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36 Edg/88.0.705.56",
"Cookie":'ll="118270"; bid=4YQbty686r4; _vwo_uuid_v2=D70936AC87C69F8BC8F4BF6C5AB424046|57bc340fdcbf53cb4b16576594fe2b9e; __utmc=30149280; __utmc=223695111; dbcl2="173056973:CIFtTpdZ52Q"; ck=xbJG; push_doumail_num=0; _pk_ref.100001.4cf6=%5B%22%22%2C%22%22%2C1612514149%2C%22https%3A%2F%2Fcn.bing.com%2F%22%5D; _pk_ses.100001.4cf6=*; __utma=30149280.883681393.1612335085.1612489281.1612514150.6; __utmb=30149280.0.10.1612514150; __utmz=30149280.1612514150.6.4.utmcsr=cn.bing.com|utmccn=(referral)|utmcmd=referral|utmcct=/; __utma=223695111.1785544053.1612335087.1612489281.1612514150.6; __utmb=223695111.0.10.1612514150; __utmz=223695111.1612514150.6.4.utmcsr=cn.bing.com|utmccn=(referral)|utmcmd=referral|utmcct=/; push_noty_num=0; _pk_id.100001.4cf6=4e19a79dbcbe37e7.1612335087.5.1612514169.1612489288.'
}#用户代理,告诉浏览器我们可以接受什么样的信息
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"):
print(e,"code")
if hasattr(e,"reason"):
print(e.reason)
return html
其中最重要的为User-Agent,这个信息必须要有,这个是网页分辨浏览器还是爬虫的关键,如果豆瓣之后拒绝爬取(403)后可以登录后将Cookie也添加进来 |
二.解析网页
-
首先对豆瓣250的网页F12进行分析
-
由上图我们可以得知一个
- 标签存储一个电影信息,而每一部电影的具体信息存储在中,由此我们可以写一个方法获得电影的信息
首先通过网页分析找到所需的信息,然后使用正则表达式将具体信息提取出来:
#影片详情链接 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)
之后开始编写getData方法获取网页数据:
# 爬取网页 def getData(baseurl): datalist=[] for i in range(1,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) #测试查看电影item data = [] #保存电影信息 item = str(item) item = item.replace("\u00a0", "") #去除数据库NBSP问题 #影片详情链接 link = re.findall(findLink, item)[0] # re库用来通过正则表达式查找指定字符串 # print(link) 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) # 添加影片评分 judge = re.findall(findJudge, item)[0] data.append(judge) # 添加影片评价人数 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) print(datalist) return datalist
三.将数据保存在.xls文件中
1. 之前我们引用了xlwt包可以直接编写方法将数据保存
#保存数据
def saveData(datalist,savepath):
workbook = xlwt.Workbook(encoding="utf-8")
worksheet = workbook.add_sheet('豆瓣电影Top250') #在同一文件夹
col = ("影片详情链接","影片图片链接","影片中文名","影片外文名","影片评分","影片评价人数","影片概况","影片相关内容")
for i in range(0,8):
worksheet.write(0,i,col[i]) #列名
for i in range(0,250):
print("第%d条"%i)
data = datalist[i]
for j in range(0,8):
worksheet.write(i+1,j,data[j])
workbook.save(savepath)
四.将数据存储到sqlite数据库中
-
初始化一个sqlite数据库:
def init_db(dbpath): sql = ''' create table movie250 ( id INTEGER primary key autoincrement, info_link text, pic_link text, cname varchar, ename varchar, score numeric, rated numeric, instroduction text, info text ) ''' conn = sqlite3.connect(dbpath) cursor = conn.cursor() cursor.execute(sql) conn.commit() conn.close()
-
编写方法将数据存储到sqlite数据库中:
def saveData2DB(datalist,dbpath): init_db(dbpath) conn = sqlite3.connect(dbpath) cursor = conn.cursor() for data in datalist: for index in range(len(data)): if index==4 or index==5: continue data[index] = '"'+data[index]+'"' sql = ''' insert into movie250( info_link,pic_link,cname,ename,score,rated,instroduction,info) values(%s)'''%",".join(data) cursor.execute(sql) conn.commit() cursor.close() conn.close()
%",".join(data)可以将数据以逗号分割 |
五.编写主函数
现在所有的方法都写完了,可以开始编写主函数了:
def main():
baseurl="https://movie.douban.com/top250?start="
#1.爬取网页
datalist=getData(baseurl)
savepath = "豆瓣电影Top250.xls"
dbpath = "movie.db"
#3.保存数据
saveData(datalist,savepath)
saveData2DB(datalist,dbpath)
if __name__ == '__main__':
main()
# init_db("movietest.db")![](https://www.icode9.com/i/l/?n=20&i=blog/2304148/202102/2304148-20210212210833828-75672266.png)
print("爬取完毕")