您的位置:首页 > 编程语言 > Python开发

Python爬虫—批量爬取网站图片和音频—并按页码保存在对应文件夹

2020-08-12 15:12 459 查看

Python爬虫-批量爬取网站图片和音频

批量爬取图片

本次我们要爬取的网站是

爱思助手
https://www.i4.cn/,当然对于爬虫来说,爬取在网页中能够直接找到的图片就显得意义不是特别大,所以我们要做的是爬取网站不能直接显示在用户屏幕前的数据。当我们在爱思助手的网页点击,找到
资源
按钮,点击进入后并打开检查窗口时,会发现如下的信息:

我们会发现,在爱思助手的应用中,铃声和壁纸的网页被隐藏了,但是当我们请求https://www.i4.cn/wper_1_0_0_1.html,就可以进入壁纸资源的页面,同样也可以进入铃声资源的页面。所以我们要爬取目标网站的图片就是此处的图片。

在爬取图片之前,我先将会用到的爬虫知识做一个简单的梳理,方便大家理解:

  • 通过
    urllib
    对网络进行访问
import ssl
import urllib.request

ssl._create_default_https_content = ssl._create_unverified_context

# 目标网址
as_url = 'https://www.i4.cn/wper_1_0_0_1.html'
# 访问网络
resp = urllib.request.urlopen(as_url)
# 读取网络信息
data = resp.read()
# 输出到控制台
print(data)
# 转码,将二进制数据转化为utf-8格式的数据
print(data.decode('utf-8'))
# 将数据存储到本地
file = open('爱思助手-壁纸爬取.html', 'wb', 1)
# 写入数据
file.write(data)
# 关闭文件
file.close()

【说明】使用mac的用户或者部分windows用户在执行代码的时候可能会报一个

urllib.reeor.URLError
的错,表示安全权限没有被打开,通过
ssl._create_default_https_content = ssl._create_unverified_context
就可以关闭网络防护。

  • urllib
    中的GET请求
import ssl
import urllib.request, urllib.parse
ssl._create_default_https_content = ssl._create_unverified_context

# GET请求
ce_url = 'https://www.baidu.com/s?'
keyword = input('请输入要百度的内容:')
# wd=爱思助手
# urlencode 函数可以把字典对象转换为get请求的参数
dic_word = {'wd': keyword}
code = urllib.parse.urlencode(dic_word)
# 网址拼接
bd_url = ce_url + code
print(bd_url)
# 把网址进行中文转换
print(urllib.request.unquote(bd_url))
# 百分号编码
ce_url_01 = 'https://www.baidu.com/s?wd=爱思助手'
# 将中文转换为百分号编码用于防止恶意木马软件访问
print(urllib.request.quote(ce_url_01))
resp = urllib.request.urlopen(bd_url)
print('当前get请求的地址:', resp.url)
  • urllib
    的POST请求
# POST请求
post_url = 'http://httpbin.org/post'
# 定义表单请求参数
data_dic = {'username': 'Jack', 'password': '123456dcs'}
# 把字典形式进行转化为POST请求参数
data_str = urllib.parse.urlencode(data_dic)
# 一般情况下,POST请求使用二进制参数
data_code = bytes(data_str, encoding='utf-8')
resp = urllib.request.urlopen(post_url, data=data_code)
# 输出请求结果
print(resp.read().decode('utf-8'))
print('当前请求网址:', resp.url)

通过上面的代码我们可以发现,POST请求和GET请求最大的却别就是,POST请求的地址中不会有被请求的信息,而GET请求的信息会出现在请求地址中。

  • 模拟浏览器进行数据访问

在https://www.i4.cn/wper_1_0_0_1.html网站检查窗口的

Network
中,我们可以看到请求头响应头等等信息

# 通过自定义请求头对网站进行访问
header = {'User-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36'}
# 目标网址
as_url = 'https://www.i4.cn/wper_3_0_0_1.html'
# 请求参数配置
req = urllib.request.Request(url=as_url, headers=header, method='GET', data=None)
# 网络访问
resp = urllib.request.urlopen(req)
print('当前网站数据为:', resp.read().decode('utf-8'))
# 获取网站请求状态码
print('当前网站状态码:', resp.code, resp.status)
# 设置网络请求超时
resp = urllib.request.urlopen(req, timeout=1)
# 获取请求数据的响应头信息
print(resp.getheaders())
# 带cookie默认密码账号登录的
# 包含多条信息的header
header = {'Cookie': 'AGL_USER_ID=eaf214cf-6f25-4efe-9760-da4f4535047a; UM_distinctid=173dd74ffe820f-015debb8ccdd24-f7d123e-1fa400-173dd74ffe9843; CNZZDATA1274270222=65358265-1597147741-https%253A%252F%252Fwww.baidu.com%252F%7C1597147741; Hm_lvt_6c0b2364be196f3c65ff6cde18a4c919=1597148300; JSESSIONID=94DF08B36112153DAF564733D23D08DF; Hm_lpvt_6c0b2364be196f3c65ff6cde18a4c919=1597151065',
'Host': 'www.i4.cn',
'User-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36'}

在自定义header参数是,可以可以根据情况来传入需要的参数即可。

有了上面的

urllib
的基础,接下来,我们就可以进行图片的爬取了:

废话不多说,直接上代码,相信大家一看就懂

import os
import ssl
import re
import urllib.request, urllib.parse
# 并设置安全权限ssl
ssl._create_default_https_content = ssl._create_unverified_context

# 目标网址
as_url = 'https://www.i4.cn/wper_1_0_0_1.html'
# 配置网络请求信息头
"""
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36
"""
header = {'User-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36',
'Host': 'www.i4.cn'}
req = urllib.request.Request(url=as_url, headers=header, method='GET', data=None)
# 网络请求并读取数据
resp = urllib.request.urlopen(req)
if resp.code == 200:
data = resp.read()
# 保存数据到本地文件夹
as_file = open('爱思助手手机壁纸.html', 'wb', 1)
as_file.write(data)
as_file.close()
# 通过正则表达式进行数据匹配
r = r'[a-zA-z]+://[^\s]*.jpg'
# 只匹配大图
r = r'https://d-paper.i4.cn/max[^\s]*.jpg'
# 创建正则表达式模板
pat = re.compile(r)
# 进行数据匹配
img_list = re.findall(pat, data.decode('utf-8'))
print(f'图片数量:{len(img_list)}')
# 下载图片
for i in range(0, len(img_list)):
print(f"正在下载第{i+1}张图片:")
path = 'img_as/' + f'第{i+1}张.jpg'
try:
if not os.path.exists(path):
item_url = img_list[i]
print(item_url)
urllib.request.urlretrieve(item_url, path)
else:
print('文件已存在')
except ValueError:
print('爬取图片失败')
else:
print('网络异常')

这里是默认下载该网站的第一页的大图,若想要下载其他页码的图片,并将每页的图片单独保存在一个文件夹下,只需要对上述代码加上一些判断条件即可:

import os
import ssl
import re
import urllib.request, urllib.parse
ssl._create_default_https_content = ssl._create_unverified_context

page = int(input("请输入想要爬取图片的页码(1-2682):"))
as_url = f'https://www.i4.cn/wper_1_0_0_{page}.html'
header = {'User-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36',
'Host': 'www.i4.cn'}
req = urllib.request.Request(url=as_url, headers=header, method='GET', data=None)
resp = urllib.request.urlopen(req)
if resp.code == 200:
data = resp.read()
r = r'https://d-paper.i4.cn/max[^\s]*.jpg'
pat = re.compile(r)
img_list = re.findall(pat, data.decode('utf-8'))
for i in range(0, len(img_list)):
path = f'img_as/第{page}页/'
if not os.path.exists(path):		# 创建以页码为单位的文件夹
os.mkdir(path)
path = path + f'第{i + 1}张.jpg'
try:
if not os.path.exists(path):	# 按照页码将图片保存在对应的文件夹中
print(f'图片数量:{len(img_list)},\t正在下载第{i + 1}张图片:')
item_url = img_list[i]
print(item_url)
urllib.request.urlretrieve(item_url, path)
else:
print('该页图片已被爬取,请选择其他页进行下载!!')
break
except ValueError:
print('爬取图片失败')
else:
print('网络异常')

此处我将图片保存的文件夹放在与此python文件同级的目录下。最后代码运行的效果如下图所示:

批量爬取音频

相信大家看了我上面的代码,就可以仿照这写出爬取本网站音频的代码了,接下来就直接为大家呈上代码吧:

import os
import urllib.request, urllib.parse
import ssl
import re

ssl._create_default_https_content = ssl._create_unverified_context
page = int(input('请输入想要下载歌曲的页码:'))
as_url = f'https://www.i4.cn/ring_1_0_{page}.html'
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',
'Host': 'www.i4.cn'}
rep = urllib.request.Request(url=as_url, headers=header, method='GET')
resp = urllib.request.urlopen(rep)
if resp.code == 200:
r = r'[a-zA-z]+://[^\s]*.mp3'
data = resp.read()
pat = re.compile(r)
song_list = re.findall(pat, data.decode('utf-8'))
for i in range(0, len(song_list)):
path = f'songs/第{page}页/'
if not os.path.exists(path):
os.mkdir(path)
path = path + f'第{i+1}首.mp3'
try:
if not os.path.exists(path):
print(f'正在爬取第{i+1}首歌\t{song_list[i]}')
urllib.request.urlretrieve(song_list[i], path)
else:
print('该歌曲已被爬取')
break
except ValueError:
print('爬取失败')
else:
print('网络请求错误!!')

此处我将图片保存的文件夹放在与此python文件同级的目录下。

感谢大家的阅读,后续我将继续为大家分享更多的爬虫实战技巧❤

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: