2.3 抓取Web页面信息
爬虫:就是通过编程语言和网络编程技术结合,在互联网中的Web页面上,获取我们所要的一些数据
爬去的数据:文本、图片、多媒体信息、数据信息
数据怎么存:文件、数据库、分布式存储
有些网站为了防止外部人员窃取网页信息,有可能会对网页进行反爬虫处理(比如只能通过浏览器访问,通过其他方式访问是会被拒绝访问的,不让下载/验证码/如百度等大型互联网公司图片等通过JS代码嵌套在内,动态生成的图片,有逻辑性,而非简单的结构性)
练习的时候爬非知名网站,大型网站爬不下来
import os,requests,re#requests非python自带,需要自行导入
def analyseAlbumPathsandNames(url):
albumpaths = []
albumnames = []
regexForName = re.compile(r'<p>(.*)</p>')
regexForLink = re.compile(r'meinv(.*)html')
resp = requests.get(url) # 访问url对应的网址 并返回响应对象
text = resp.text
# print(resp.text) # text指的是响应的主体内容
#以上操作放前面,防止运行时间过长,导致一方认为另一方长期没响应,断开连接,导致数据读不出来
# 1.获取专辑名称
names = regexForName.findall(text)
for name in names:
albumnames.append(name)
# 2. 获取专辑网址
links = regexForLink.findall(text)
for link in links:
if "tag" not in link:
albumpaths.append("http://www.win4000.com/meinv"+link+"html")#过滤tag字段的
return albumpaths,albumnames[28:-1]#返回时不全部返回,因为前27个和最后一个不是需要的数据,所以选择部分打印
def downPicture(picturepath,i,albumdir):
# 1 创建图片的文件名称和其父目录
picturename = albumdir + "/" + str(i) + ".jpg"
if os.path.exists(picturename):
return
# http://pic1.win4000.com/pic/2/04/65e44941c9.jpg
# 2 寻找照片本身的网址
regexForPic = re.compile(r'http://pic(.*?)jpg')#注意非贪心匹配
lst = regexForPic.findall(requests.get(picturepath).text)
picLink = "http://pic"+lst[7] + "jpg"#注意验证这个地方,是下载同一个还是依次往后下载了
file = open(picturename,"wb")
file.write(requests.get(picLink).content)
file.flush()
print(picturename+",下载完成!")
def downPictures(albumdir,albumpath):#图片要存放的文件夹,当前图片所在专辑的目录
print("=" * 20)
# 1 获取当前专辑照片的总个数
resp = requests.get(albumpath)#专辑地址
text = resp.text
regexForNumber = re.compile(r'<em>(\d+)</em>')#解析出来就是一个数字
number = int(regexForNumber.findall(text)[0])
# 2 根据总个数,拼接该专辑下每一张照片的网址
for i in range(1,number + 1):
# http://www.win4000.com/meinv208366.html
# http://www.win4000.com/meinv208366_2.html
picturepath = albumpath[:-5] + "_" + str(i) + ".html"
# 3 根据每一个照片的地址和其编号 下载进专辑目录
downPicture(picturepath,i,albumdir)#网址,第几个照片,专辑
def createAlbum(albumname,albumpath):
albumdir = meinv + "/" + albumname
if not os.path.exists(albumdir):
os.mkdir(albumdir)
downPictures(albumdir,albumpath)#按理,应该放if里面,这样的话创建文件夹就直接下载,有了文件夹就意味着已经下载过了,此处是为了测试,所以放外面
# 1 创建图片的总目录
meinv = "meinv"
if not os.path.exists(meinv):
os.mkdir(meinv)
# 2 链接到网页,获取网页中的信息
url = "http://www.win4000.com/meitu.html"
# 3 获取专辑的名称+专辑的网址
albumpaths,albumnames = analyseAlbumPathsandNames(url)
print(len(albumpaths))
print(len(albumnames))
for i in range(len(albumnames)):
# 4 创建每一个专辑的文件夹并下载专辑中的图片
createAlbum(albumnames[i],albumpaths[i])
一个网站一个爬虫策略,要熟悉所要爬的网页的架构才能写出相应策略进行数据爬取。
2.4 Excel数据处理
xlrd(读),openpyxl(用于新建)用到这两个模块
import xlrd, openpyxl
# 1 从大五人格原始数据中读取数据xls
# 2 计算相关的数据
# 3 将计算结果写入到大五人格结果数据xls文件中
# 将Excel文件读取进来 data
data = xlrd.open_workbook("大五原始数据.xls")
# 读取Excel文件中的第一个数据表
table = data.sheets()[0]
# 获取当前数据表中有效的行数
rows = table.nrows
# 创建一个存储大五人格结果数据Excel文件
wb = openpyxl.Workbook()
# 获取Excel文件中名称为Sheet的表
sheet = wb.get_sheet_by_name("Sheet")
sheet['A1'] = '序号'
sheet['B1'] = '姓名'
sheet['C1'] = '神经质'
sheet['D1'] = '外向性'
sheet['E1'] = '开放性'
sheet['F1'] = '顺同性'
sheet['G1'] = '严谨性'#以上为表头,自行定义
# 按行处理数据(有效数据从第2行开始的)
for i in range(1, rows):
rowData = table.row(i) # 获取第i+1行的所有Cell格子
name = rowData[6].value # 获取第7个格子中的数据-姓名
rowData = rowData[18:] # 获取60个题的分数
# 设置相关性格的计分
aim1 = aim2 = aim3 = aim4 = aim5 = 0
for l in range(len(rowData)):
var = rowData[l].value
# 所有针对aim1计分分值的角标
if l % 5 == 0:
if l == 0 or l == 15 or l == 30 or l == 45:#反向计分的值
aim1 += (6 - var)
else:
aim1 += var
# 所有针对aim2计分分值的角标
if l % 5 == 1:
if l == 11 or l == 26 or l == 41 or l == 56:
aim2 += 6 - var
else:
aim2 += var
# aim3
if l % 5 == 2:
if l == 17 or l == 22 or l == 27 or l == 32 or l == 47:
aim3 += 6 - var
else:
aim3 += var
# aim4
if l % 5 == 3:
if l == 8 or l == 13 or l == 18 or l == 23 or l == 38 or l == 43 or l == 53 or l == 58:
aim4 += 6 - var
else:
aim4 += var
# aim5
if l % 5 == 4:
if l == 14 or l == 29 or l == 44 or l == 54:
aim5 += 6 - var
else:
aim5 += var
sheet['A%s' % (i + 1)] = i#第i+1行记录的是第i个人的数据
sheet['B%s' % (i + 1)] = name
sheet['C%s' % (i + 1)] = aim1
sheet['D%s' % (i + 1)] = aim2
sheet['E%s' % (i + 1)] = aim3
sheet['F%s' % (i + 1)] = aim4
sheet['G%s' % (i + 1)] = aim5
wb.save("结果表.xls")#保存,以上都是只在内存里面的,只有这一步之后才保存
print("计算完成!")