写在前面
之前学习过python的一些相关知识,主要是通过 b站视频网络安全系列教程学习、黑马程序员Python教程_600集Python从入门到精通教程(懂中文就能学会)等进行的一些学习
大一暑假期间,当时有个暑假训练营,也是这一块的知识,使用anaconda和vscode进行一些数据分析、机器学习的入门,参考见往期博客
不过时间过了很长,内容基本都快忘记了,草稿箱中的爬虫小项目迟迟没有完成…
现在恰逢百度的Ai Studio 提供线上的 运行环境(不必再装anaconda等环境实在是太好了),感觉学一学爬虫还是挺不错的
开始
一、AI Studio环境运行流程
二、本地运行
需要注意的是,和上面的略微有些不同
- 本地运行需要加上headers应对反爬,不加的话
error code
为418
- 图片保存的地址推荐些绝对路径
- 使用
urllib.reques.Request()
方法需要引入import urllib.request,而不是import urllib
本地运行源代码
import sys
import time
from bs4 import BeautifulSoup
import re
import urllib.request
import openpyxl
import requests
# 获取页面全部内容,参数为待爬取的
def askURL(url):
# 发送请求,参数url,其他参数默认缺省
# 添加头信息,否则失败
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'}
req = urllib.request.Request(url,headers=headers)
try:
res = urllib.request.urlopen(req)
html = res.read()
# 发生异常,根据异常结果打印相关信息
print(html)
return html
except urllib.error.URLError as e:
if hasattr(e, "code"):
print(e.code)
if hasattr(e, "reason"):
print(e.reason)
# 正则res获取相关内容
def getData(baseurl):
# 定义正则模式
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)
# 去掉无关内容
remove = re.compile(r' |\n|</br>|\.*')
datalist = []
for i in range(0, 10):
# 爬取数量
url = baseurl + str(i * 25);
# 获得html对象
html = askURL(url)
print(html)
# 解析html获取soup
soup = BeautifulSoup(html,'html.parser')
# 找到每一个影片项
for item in soup.find_all('div', class_='item'):
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):
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(remove, "", bd)
bd = re.sub('<br(\s+)?\/?>(\s+)?', " ", bd) # 去掉<br >
bd = re.sub('/', " ", bd) # 替换/
data.append(bd.strip())
datalist.append(data)
time.sleep(5)
return datalist
def saveData(datalist, savepath):
book = openpyxl.Workbook();
sheet = book.create_sheet("豆瓣电影Top250")
col = ('电影详情链接', '图片链接', '影片中文名', '影片外国名', '评分', '评价数', '概况', '相关信息')
sheet.append(col) # 添加列头
for i in range(0, 250):
data = datalist[i]
for j in range(0, 8):
sheet.cell(row=(i + 2), column=(j + 1), value=data[j])
# openpyxl中的单元格计数从1开始, 加上第一行是列头, 要多跳一个
# openpyxl中的计数和Excel内的计数方式一致, 但和常规编程从0开始的方式相左
book.save(savepath) # 保存
def main():
print("开始爬取......")
baseurl = 'https://movie.douban.com/top250?start='
datalist = getData(baseurl)
savapath = u'D:\\豆瓣电影Top250.xlsx'
saveData(datalist, savapath)
main()
print("完成!,请查看excel文件")