爬取4K高清美图
这篇爬虫主要是用来爬取网站高清4K图片,这也是笔者学初学爬虫的时候最先写一个的爬虫脚本,现在回过头来重新梳理一下,也算是对从前知识的一个总结,希望对大家有所帮助!
爬取任意网站的的首要都是分析目标网站,我们需要做的主要流程如下:
1. 访问目标网站,找到你需要的资源具体在某个页面,如何进入该页面,资源在具体的什么位置。
2. 通过 F12 开发者工具,找到数据的获取接口,数据是在静态页面直接获取,还是异步加载存放为json等等
3. 编写简单的代码,查看是否能直接访问,试探其访问机制及其反爬措施
4. 完善代码,逐步请求到你需要的数据。
1、分析url以及页面结构
通过F12调试工具的简单调试,我们发现,它网页url的参数变化规律显而易见。
首页:http://pic.netbian.com/
次级风景目录:http://pic.netbian.com/4kfengjing/
(http://pic.netbian.com/4kmeinv/index.html)
次级风景目录的第二页:http://pic.netbian.com/4kmeinv/index_2.html
风景目录下某个图片:http://pic.netbian.com/tupian/12356.html
图片资源:http://pic.netbian.com/uploads/allimg/170725/103840-150095032034c0.jpg
我们不难发现,
/4kfengjing/ 代表的就是首页下不同模块的标识名称
index_2 代表的就是次级模块目录下翻页的标识
12356 代表的是次级风景目录下某个图片的标识名称
/uploads/allimg/170725/103840-150095032034c0.jpg 代表的是我们所需要请求图片的部分url
值得注意的是 http://pic.netbian.com/4kfengjing/ 和http://pic.netbian.com/4kmeinv/index.html同样都访问的第一页的内容,而从第二页起,这个参数的变化规律便是数字随着翻页加1。而12356 以及/uploads/allimg/170725/103840-150095032034c0.jpg参数都在相应的上一级页面中可以直接拿到。
( 其实在风景目录页面里,获取下一级图片页面的同时,也可以直接拿到图片资源的地址,不过笔者这里选择进入图片页面后再拿图片资源的地址,虽然这样会多请求一次,但是当时笔者为了获取图片名称同时给图片命名的代码简单些,选择了多请求一次的方式。)
了解到这些以后我们便可以开始按照规则制造url,编写爬虫访问我们所需要的资源。
2、开始编码
首先导入本项目用到的库:
from lxml.html import etree
import requests
from PIL import Image
import os
import sys
其中,requests 库主要用来发起网络请求,并接收服务器返回的数据;lxml库主要用来解析 html 内容;os 库主要用于将数据输出存储到本地文件中,PIL库是用来处理图片;sys库主要用于解释器相关的操作。
headers = {
'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36'
}
url_list = []
url = 'http://pic.netbian.com/4kmeinv/index_.html'
res = requests.get(url=url,headers=headers)
res.encoding = res.apparent_encoding # 修改编码
response = etree.HTML(res.text)
response = etree.tostring(response)
response = etree.fromstring(response) # 以上搭建xpath对象
content = response.xpath('//ul[@class="clearfix"]/li')
for i in content:
tu_url = i.xpath('./a/@href')
tupian_url = 'http://pic.netbian.com'+ ''.join(tu_url)
url_list.append(tupian_url)
首先是进入模块页面,利用xpath规则拿到图片页面的url,并放入url_list这个列表中,方便后续使用。
for i in url_list:
r = requests.get(url=i, headers=headers)
r.encoding = r.apparent_encoding # 修改编码
html = etree.HTML(r.text)
html = etree.tostring(html)
html = etree.fromstring(html) # 以上搭建xpath对象
url = html.xpath(r'//a[@id="img"]/img/@src')
print(url)
rr = requests.get('http://pic.netbian.com' + ''.join(url), headers=headers)
name = html.xpath(r'//a[@id="img"]/img/@title')
rr.encoding = rr.apparent_encoding # 修改编码
这里是图片页面,从模块页面拿到的url_list列表中不断地拿出图片地址,进行访问,并拿到对应的图片资源地址。
```c
with open(f"./tutu/{''.join(name)}" + '.png', 'wb') as fw:
fw.write(rr.content)
img = Image.open(f"./tutu/{''.join(name)}" + '.png')
img = img.resize((4000, 2000), Image.ANTIALIAS) # 改变大小 抗锯齿
# print(img.size)
img.save(f"./tutu/{''.join(name)}" + '.png', quality=95)
print(str(name) + " 保存完成!")
对拿到的图片资源进行保存以及利用PIL库将图片的清晰度变成高清4k。
2、优化程序
我们通过这个流程可以拿到指定模块下高清图片,但是存在两个问题,第一就是我们没有加入翻页,只能获取到第一页的内容;其次模块的url是写死的,我们无法动态的选择下载摸个模块的高清图片。
于是我们对其进行如下的改进:
area = input('请输入类别:')
if area.find('美女')>=0:
area = '4kmeinv'
elif area.find('风景')>=0:
area = '4kfengjing'
elif area.find('游戏')>=0:
area = '4kyouxi'
elif area.find('动漫')>=0:
area = '4kdongman'
elif area.find('影视')>=0:
area = '4kyingshi'
elif area.find('明星')>=0:
area = '4kmingxing'
elif area.find('汽车')>=0:
area = '4kqiche'
elif area.find('动物')>=0:
area = '4kdongwu'
elif area.find('人物')>=0:
area = '4krenwu'
elif area.find('美食')>=0:
area = '4kmeishi'
elif area.find('宗教')>=0:
area = '4kzongjiao'
elif area.find('背景')>=0:
area = '4kbeijing'
else:
print('输入关键词格式不正确')
sys.exit(0)
page = int(input('请输入页数:'))
for i in range(0,page+1):
i = int(i)
if i==1:
url = 'http://pic.netbian.com/'+ area +'/index.html'
res = requests.get(url=url,headers=headers)
res.encoding = res.apparent_encoding # 修改编码
response = etree.HTML(res.text)
# print(type(response))
response = etree.tostring(response)
# print(type(response))
response = etree.fromstring(response) # 以上搭建xpath对象
# print(type(response))
content = response.xpath('//ul[@class="clearfix"]/li')
for i in content:
tu_url = i.xpath('./a/@href')
tupian_url = 'http://pic.netbian.com'+ ''.join(tu_url)
url_list.append(tupian_url)
elif i>=1:
i = str(i)
# url = 'http://pic.netbian.com/4kmeinv/index_.html'
url = 'http://pic.netbian.com/' + area + '/index_' + i + '.html'
res = requests.get(url=url,headers=headers)
res.encoding = res.apparent_encoding # 修改编码
response = etree.HTML(res.text)
response = etree.tostring(response)
# print(type(response))
response = etree.fromstring(response) # 以上搭建xpath对象
# print(type(response))
content = response.xpath('//ul[@class="clearfix"]/li')
for i in content:
tu_url = i.xpath('./a/@href')
tupian_url = 'http://pic.netbian.com'+ ''.join(tu_url)
url_list.append(tupian_url)
我们将模块的选择以及页数,都定义为一个可以手动输入的参数,而这个参数利用find方法的特性支持关键词搜索,这样我们便可以下载你想要模块的高清图片了!
实际运行测试一下,假设我们要爬取美女图片模块下前2页的图片,那我们在开始日期中输入美女呀,在页数中输入 2,运行。
这样我们就可以顺利的获取到我们想要的高清4k图片啦。
以下是完整代码:
from lxml.html import etree
import requests
from PIL import Image
import os
import sys
path = './tutu'
if not os.path.exists(path):
os.makedirs(path)
headers = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36'
}
url_list = []
area = input('请输入类别:')
if area.find('美女')>=0:
area = '4kmeinv'
elif area.find('风景')>=0:
area = '4kfengjing'
elif area.find('游戏')>=0:
area = '4kyouxi'
elif area.find('动漫')>=0:
area = '4kdongman'
elif area.find('影视')>=0:
area = '4kyingshi'
elif area.find('明星')>=0:
area = '4kmingxing'
elif area.find('汽车')>=0:
area = '4kqiche'
elif area.find('动物')>=0:
area = '4kdongwu'
elif area.find('人物')>=0:
area = '4krenwu'
elif area.find('美食')>=0:
area = '4kmeishi'
elif area.find('宗教')>=0:
area = '4kzongjiao'
elif area.find('背景')>=0:
area = '4kbeijing'
else:
print('输入关键词格式不正确')
sys.exit(0)
page = int(input('请输入页数:'))
for i in range(0,page+1):
i = int(i)
if i==1:
url = 'http://pic.netbian.com/'+ area +'/index.html'
res = requests.get(url=url,headers=headers)
res.encoding = res.apparent_encoding # 修改编码
response = etree.HTML(res.text)
response = etree.tostring(response)
response = etree.fromstring(response) # 以上搭建xpath对象
content = response.xpath('//ul[@class="clearfix"]/li')
for i in content:
tu_url = i.xpath('./a/@href')
tupian_url = 'http://pic.netbian.com'+ ''.join(tu_url)
url_list.append(tupian_url)
elif i>=1:
i = str(i)
url = 'http://pic.netbian.com/' + area + '/index_' + i + '.html'
res = requests.get(url=url,headers=headers)
res.encoding = res.apparent_encoding # 修改编码
response = etree.HTML(res.text)
response = etree.tostring(response)
response = etree.fromstring(response) # 以上搭建xpath对象
content = response.xpath('//ul[@class="clearfix"]/li')
for i in content:
tu_url = i.xpath('./a/@href')
tupian_url = 'http://pic.netbian.com'+ ''.join(tu_url)
url_list.append(tupian_url)
for i in url_list:
r = requests.get(url=i, headers=headers)
r.encoding = r.apparent_encoding # 修改编码
html = etree.HTML(r.text)
html = etree.tostring(html)
html = etree.fromstring(html) # 以上搭建xpath对象
url = html.xpath(r'//a[@id="img"]/img/@src')
rr = requests.get('http://pic.netbian.com' + ''.join(url), headers=headers)
name = html.xpath(r'//a[@id="img"]/img/@title')
rr.encoding = rr.apparent_encoding # 修改编码
with open(f"./tutu/{''.join(name)}" + '.png', 'wb') as fw:
fw.write(rr.content)
img = Image.open(f"./tutu/{''.join(name)}" + '.png')
img = img.resize((4000, 2000), Image.ANTIALIAS) # 改变大小 抗锯齿
# print(img.size)
img.save(f"./tutu/{''.join(name)}" + '.png', quality=95)
print(str(name) + " 保存完成!")
print("保存完成!")