分享

爬虫抓图全网最新方法,这一次终于是4k高清美图,只因为我不下载JPG图片!

 紫竹林1ht2lcnc 2021-02-26

我学爬虫一直有一个梦想,就是想真正达到可见即可爬的态度,所以我一直在尝试找一种方式去搞定它,从最开始的模拟接口去交接数据,但是我发现这行不通,然而条条大路通罗马,后浪又怎么能这么消逝在沙滩上,直到我想了一个问题,为什么我们每次保存图片都是JPG格式,为什么不是PNG格式? 那我就查阅了相关文献,终于,我成功了,我用另类的方式搞定了这些限制次数的图库,这是一次大胆的创意,可以适用在任何图站,希望对大家有帮助!

都2020年了,爬虫党还在为了图片的下载质量烦恼吗?还是只会下载JPG图片?那我有一种另类方式可以帮助你真正的白嫖高质量图片,肝了一个礼拜的干货,绝对能改变你对爬虫的看法和思考,原来爬虫这么有趣,也不会这么思维固然,代码方式尽量简单一点,让大家能看懂,加油各位!

在这里插入图片描述
防止有人说我标题党,我先给图致敬,绝对是4k以上画质,作假的剁手!

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

技术分析:

爬虫还用JPG?

这个另类技术设计到一点值得我们思考,我们每次爬虫保存的图片都是默认JPG,为什么

  • 先不管他们的定义是什么,简单来说,JPG就是一种有损压缩技术,在符合所需画质的前提下,尽可能的提高压缩比,来减少储存空间,所以传输速度快,文件小,画质低,这也就是网站为什么都用JPG来存储图片了。
  • 而PNG我定义就是一种大保健,他能保存完整的画质,也就是相对无损压缩技术,缺点也就是存储空间大,保留了很多原始通道,所以网站不采用,爬虫教学也不采用。
  • 而位图的定义,理论上是可以无限放大的,JPG作为位图自然是糟糕的选择,而PNG确实是一个完美的搭档,这里我就钻了这个空子,用了这种方式搞定了高清图库。
  • 采用这种方式,我不是吹嘘我有多厉害,可能有人想过,但是我只是分享这种方式给更多的朋友,改善他们的固有思维,如果你想要小图片的话保存JPG也是很好的选择,而我喜欢高清大图,我采用的是PIL库的Image类的操作,下面我会给出很好的解释。这是一个全站点图片爬取的爬虫,速度可能有点慢,我尽力使用了线程池,谢谢理解!

技术关键代码:

存储为位图,然后无损放大图片,就可以得到我们的效果了,还不懂的留言问我。

with open(''.join(name) + '.png', 'wb') as fw:fw.write(rr.content) img = Image.open(''.join(name) + '.png') img = img.resize((4000, 2000), Image.ANTIALIAS) # 改变大小 抗锯齿 # print(img.size) img.save(''.join(name) + '.png', quality=95) # 质量分数 95
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

如果看到这里觉得对你有帮助的,希望给个关注和赞,这是对我最大的支持!

在这里插入图片描述

项目技术:

  • 还是熟悉的网站 彼岸图网 这个网站质量挺高的,但是有个缺点就是限制次数,所以这次就决定搞它了,其他网站也是大同小异之作。
  • 总的步骤分了几大模块,设计到的技术点不是很多,requests和xpath 作为爬虫基础技术,还有Image类和线程池技术,然后文件的os库也是必须的。
  • 我保证说的很清楚,我们就开始实践吧!

获取分组网址和标题:

  • 我们这次做的是一个全站点爬取,所以得考虑分组问题,这里我们编写爬虫获取箭头所指向的信息,我保存为一个列表,方便我接下来的操作。
    在这里插入图片描述
    代码:
def get_groups(url, headers):  # 获得重要信息    '''根据传入的最初网址和标题头,获得每个专栏的网址和标题'''    r = requests.get(url, headers=headers)    r.encoding = r.apparent_encoding  # 转换编码    if r.status_code == 200:        html = etree.HTML(r.text)        html = etree.tostring(html)        html = etree.fromstring(html)        url_list = html.xpath(r'//div[@class='classify clearfix']//a/@href')  # 获得网页分组的url        name = html.xpath(r'//div[@class='classify clearfix']//a/text()')  # 获得网页分组的标题    else:        print('请求错误!')    return name, url_list  # 把分组标题和分组网址回溯
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

开始下载选择:

  • 获取成功这些我们就开始选择下载,更友好和人性化:
    这里我就简单的写写哈,别介意:
    在这里插入图片描述

代码如下:

def begin_down(title, url, headers): # 下载选择'''这里的参数为刚获取的标题和网址还有请求头''' print('白嫖方式下载高清图片'.center(30, '-')) for i, j in enumerate(title): print(i, '\t\t\t\t\t', j) inp = int(input('输入下载选项:')) # print(title[inp], url[inp]) get_image_1st(title[inp], url[inp], headers) # 调用第一页的网址进行下载 get_image(title[inp], url[inp], headers) # 下载剩下的所有页
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

这里获取的网址需要到下一步进行拼接,根据我的观察,分组网站的第一页和其他页网址不相连,没有规律可循,所以我写了爬取第一页和爬取其他页二个函数来获取图片,这里下面我也会说。


获取图片网址:

在这里插入图片描述

  • 随后我们点击图片进入这样页面,看我箭头标注,我们要获取href的内容,而不是img中的网址,img里面的是缩小图片,没什么质量,看多了还伤眼睛,不值得,我给你大图,你也爽。编写代码,获取href然后网址拼接这个样子 http://pic.netbian.com/tupian/17781.html 就可以打开了。

代码:

def get_image_1st(title, url, headers):  # 得到第一页的图片网址    url_1st = 'http://pic.netbian.com/' + url  # 拼接分组网址    r = requests.get(url_1st, headers)    if r.status_code == 200:        html = etree.HTML(r.text)        html = etree.tostring(html)        html = etree.fromstring(html)        page_url = html.xpath(r'//ul[@class='clearfix']//li/a/@href')  # 获得每张图片的真实网址        #  print(page_url)        page_url = ['http://pic.netbian.com' + i for i in page_url]  # 网址拼接        pool_down(title, page_url, headers)  # 调用图片下载函数 下载选择页的 第一页全部图片,因为第一页网址特殊def get_image(title, url, headers):  # 得到其他页的图片网址    '''找其他页的网址,然后找到每张图片的点击图片网址'''    pages_url = []    for i in range(2, 10):  # 我们假定最大翻页为10页        other_url = 'http://pic.netbian.com' + url + 'index_' + str(i) + '.html'  # 拼接网址        # print(other_url)        r = requests.get(other_url, headers=headers)  # 尝试请求第二页 获得图片的点击网址        if r.status_code == 200:            html = etree.HTML(r.text)            html = etree.tostring(html)            html = etree.fromstring(html)            page_url = html.xpath(r'//ul[@class='clearfix']//li/a/@href')  # 获得每张图片的真实网址            page_url = ['http://pic.netbian.com' + i for i in page_url]  # 网址拼接            pages_url.append(page_url)    pool_down(title, pages_url, headers)  # 调用下载
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

获得下载网址:

  • 然后我们打开图片,通过控制台,可以得到我下图的画面:

在这里插入图片描述

这里注意一点,我们获取的是src里面的图片网址,这个质量更高一点,便于我们修改画质,这里使用到了线程池和Image的使用,简单使用起来不是很难。

代码如下:

def image_down(title, page_url, headers): # 下载图片 if not os.path.exists(title + '//'): os.mkdir(title + '//') os.chdir(title + '//') else: os.chdir(title + '//') for i, j in enumerate(page_url): # 遍历第一页的图表列表 r = requests.get(j, headers=headers) # 请求这个图片网址 if r.status_code == 200: 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') name = html.xpath(r'//a[@id='img']/img/@title') rr = requests.get('http://pic.netbian.com' + ''.join(url), headers=headers) if rr.status_code == 200: # 请求下载图片网址 rr.encoding = rr.apparent_encoding # 修改编码 with open(''.join(name) + '.png', 'wb') as fw: fw.write(rr.content) img = Image.open(''.join(name) + '.png') img = img.resize((4000, 2000), Image.ANTIALIAS) # 改变大小 抗锯齿 # print(img.size) img.save(''.join(name) + '.png', quality=95) # 质量分数 95 print(f'{title} 中第 {i + 1} 张下载完成!') else: print('错误啦')def pool_down(title, page_url, headers): # 线程下载 # print(title, len(page_url)) path = 'D://彼岸图库//' # 创建总的文件夹 if not os.path.exists(path): os.mkdir(path) os.chdir(path) else: os.chdir(path) # 创建一个多线程下载 pool = Pool(6) # 一次6下 if len(page_url) > 2: # 如果是其他网址 for i in page_url: pool.apply(image_down, args=(title, i, headers)) elif len(page_url) == 1: # 如果是第一页 pool.apply(image_down, args=(title, page_url, headers)) # 调用线程池 pool.close() pool.join()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

项目经验:

  • 全部的代码我差不多全部给出了,为了让你们身体健康,我还是希望大家可以自行的编写一下主函数,主函数很简单的,就是简单的调用,参数我已经都给了,体验一下编程的快乐,这样左右手就很充实啦!

  • 我对爬虫的理解不在于代码多难实现,而是如何分析网站,好的分析,绝对事半功倍!

  • 这一次项目,因为是静态网址,没有遇到多少坑坑洼洼,都是小毛病,我就不提出来博取幸苦费用了。

  • 总的来说,你们看了觉得有帮助的,给个关注和支持,就是对我最大的帮助,我会加油,你们也是!

项目后记:

任他天高鸟飞,奔涌吧,后浪!

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多