欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

多线程爬取4k超高清美图壁纸

程序员文章站 2022-05-26 18:29:02
...

多线程爬取4k美图壁纸

前言:看完此篇文章你可以更加深入的了解多线程的使用,并且最重要的你能够下载你自己想要的超高清4k壁纸

爬取结果:
多线程爬取4k超高清美图壁纸

1. 分析网站
要爬取的url :http://pic.netbian.com/

a) 判断网页是动态加载还是静态加载页面。右击查看网页源代码,按Ctrl + f在源代码中搜索网站的详情页地址,从而判断整个网页是静态加载的
多线程爬取4k超高清美图壁纸
b) 明确爬取的目标。我们要爬取的目标是详情页的图片,因为详情页壁纸的大小比例才是我们想要的,索引页的壁纸比例都太小
多线程爬取4k超高清美图壁纸
c) 分析类别。通过多次点击4K风景,4K动漫,4K影视我们可以发现url的变化,因为网页的结构都是一样的,所以我们只需要更改url就可以获取每个类别的壁纸了
多线程爬取4k超高清美图壁纸
2.代码演练

a) 我们可以通过字典的方式让用户选择需要爬取的内容,此时choice_ty的值就是我们要爬取类别的url的后部分内容,我们只需要拼接即可获取网页的url了。

    try:
        ty = input('请输入想要爬取的类型 \n-风景-,-美女-,-游戏-,-动漫-,-影视-,-明星-,-汽车-,-动物-,-人物-,-美食-,-宗教-,-背景- \n:')
        ty_dict = {'风景':'fengjing','美女':'meinv','游戏':'youxi','动漫':'dongman','影视':'yingshi','明星':'mingxing',
                   '汽车':'qiche','动物':'dongwu','人物':'renwu','美食':'meishi','宗教':'zongjiao','背景':'beijing'}
        choice_ty = ty_dict[ty]
    except KeyError:
        print('请输入正确的类型')

b) 批量处理请求头。我们先添加请求头,这里我告诉大家一个在pycharm中批量处理请求头的方法。

  1. 首先复制所有的请求头
    多线程爬取4k超高清美图壁纸
    2.在pycharm中建立一个以.txt结尾的文件在上面的搜索框中输入(.): (.),在下面的搜索框中输入"$1": "$2"即可获得格式化后的请求头
    多线程爬取4k超高清美图壁纸
    c) 由于在此不好讲解,我会将更细一步的讲解全放在完整代码中。

    完整代码如下:

import requests,os
from lxml import etree
from queue import Queue
from threading import Thread

class WallPaper4K(object):
    def __init__(self):
        self.headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.113 Safari/537.36'}   # 请求索引页和详情页的请求头
        self.url_list = Queue()        # 创建url的队列
        # 请求下载图片的请求头,你们可以用我教的方法批量处理请求头。
        self.HEADERS = {
                        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
                        "Accept-Encoding": "gzip, deflate",
                        "Accept-Language": "zh-CN,zh;q=0.9",
                        "Cache-Control": "max-age=0",
                        "Connection": "keep-alive",
                        "Cookie": "__cfduid=db7022ded646a57a7c92d437eaa741c5c1588228993; Hm_lvt_526caf4e20c21f06a4e9209712d6a20e=1588339511,1588670116,1588677703,1588684950; zkhanecookieclassrecord=%2C65%2C53%2C66%2C; Hm_lpvt_526caf4e20c21f06a4e9209712d6a20e=1588685839",
                        "Host": "pic.netbian.com",
                        "If-Modified-Since": "Mon, 30 Mar 2020 16:35:52 GMT",
                        "If-None-Match": "'5e821fe8-4a440'",
                        "Referer": "http://pic.netbian.com/tupian/25685.html",
                        "Upgrade-Insecure-Requests": "1",
                        "User-Agent": "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.113 Safari/537.36"}
    # 解析索引页,并获取索引页中详情页的url
    def parse_index(self):
        while not self.url_list.empty():
            response = requests.get(self.url_list.get(),headers=self.headers).content.decode('gbk')
            html = etree.HTML(response)   # 创建用于使用xpath的对象
            details_urls = html.xpath("//ul[@class='clearfix']//li/a/@href")   # 使用xpath提取出所有详情页的url
            for url in details_urls:   # 遍历获取每个详情页的url
                detail_url = 'http://pic.netbian.com/' + url   # 因为获取的url不是完整的url,所以这里需要进行拼接
                self.par_detail_url(detail_url)           # 将拼接后的详情页url传给par_detail_url方法去解析详情页

    def par_detail_url(self,url):
        res = requests.get(url,headers=self.headers).content.decode('gbk')   # 向详情页发送请求获取响应
        html = etree.HTML(res)
        img_url = 'http://pic.netbian.com/' + html.xpath("//a[@id='img']/img/@src")[0]   # 因为在详情页获取的图片url不是完整的所以需要进行拼接
        name = html.xpath("//h1/text()")[0]     # 获取图片的名字
        self.save_image(img_url,name)         # 将拼接后的图片url和图片名称传给save_image方法

    def save_image(self,img_url,name):
        try:         # 这里最好加上异常捕获
            res = requests.get(img_url,timeout=3).content   # 向图片的下载地址发送请求获取响应,并用.content将其转为二进制数据
            filename = 'F:/图片/'
            if not os.path.exists(filename):       # 使用os库中的path模块判断电脑中的filename路径的文件夹是否创建,如果没有则创建
                os.makedirs(filename)
            # 打开一个文件并保存数据
            with open(filename+'{}.jpg'.format(name),'wb')as f:   # 注意图片的后缀为.jpg
                f.write(res)       # 保存的图片得为二进制数据
                print('已下载{}'.format(name))
        except Exception:
            print('下载失败{}'.format(name))

    def main(self,choice_ty):
        self.url_list.put('http://pic.netbian.com/4k{}/'.format(choice_ty))  # 因为索引页中的第一页url和其余页数的url不同,所以这里需要单独添加到url的队列中
        t_list = []
        for i in range(2,200):
            url_index = 'http://pic.netbian.com/4k{}/index_{}.html'.format(choice_ty,i)   # 使用format方法将用户输入的选择和页数拼接成完整的url_index
            self.url_list.put(url_index)       # 将拼接后的url放入到url的队列中
        for x in range(10):     # 开启10个线程,注意:线程不要过多,否则对方服务器会有压力
            t1 = Thread(target=self.parse_index)   # 创建线程
            t1.start()     # 启动线程
            t_list.append(t1)   # 将线程放入到t_list中
        for t in t_list:    # 遍历t_list列表并使用join()方法使主线程等待其它线程结束
            t.join()

if __name__ == '__main__':
    # 用户输入的过程和从字典中取值过程得加上异常捕获,以免出现keyerror
    try:
        ty = input('请输入想要爬取的类型 \n-风景-,-美女-,-游戏-,-动漫-,-影视-,-明星-,-汽车-,-动物-,-人物-,-美食-,-宗教-,-背景- \n:')  # 得到用户的输入
        # 创建类别的字典
        ty_dict = {'风景':'fengjing','美女':'meinv','游戏':'youxi','动漫':'dongman','影视':'yingshi','明星':'mingxing',
                   '汽车':'qiche','动物':'dongwu','人物':'renwu','美食':'meishi','宗教':'zongjiao','背景':'beijing'}
        choice_ty = ty_dict[ty]   # 根据用户的输入取出字典中所对应的值
        spider = WallPaper4K()
        spider.main(choice_ty)
    except KeyError:
        print('输入有误,请重新输入')


结语:欢乐的学习时光就结束了,有任何问题的可以在下方留言,我看到了一定会回复的。希望你们能够在此篇文章中获取到你们想要的知识,要相信汗水不会欺骗你。

励志话语:做一个决定,并不难,难的是付诸行动,并且坚持到底。