多线程爬虫实战-思路

前言

最近有很多小伙伴找到我,说想要王者荣耀所有英雄皮肤的照片,但是又不想自己去下载,正好借这个机会给大家讲解一下多线程的爬虫实战

由于线程爬虫会对任何服务器都有一定的影响,本文仅供学习交流使用,切勿拿去做什么不好的事情,要做一个合法的爬虫写手。

📝个人主页→数据挖掘博主ZTLJQ的主页

b1691e6f246947eeb06ee06469621bc2.gif

个人推荐python学习系列:

☄️爬虫JS逆向系列专栏 - 爬虫逆向教学

☄️python系列专栏 - 从零开始学python


那么我们进入第一步,写爬虫的第一步永远都是打开要进行爬取的网站,直接打开王者荣耀的官网即可

打开了官网以后我们就要找到我们需要爬的东西究竟是什么,这个一定要理清楚,我们需要的是英雄皮肤图片,官网的图片如下图:

34d7f0d38b4f43999ecbbee37b31cd7b.png

 

 那么我们可以知道这个页面暂时是没有我们需要的照片,只有英雄的照片,那么我们点击英雄进去链接会发现进去的页面是我们需要的东西。​

 那么我们就按照经验第一步就是看看是不是可以在URL上找到方法,对比多个URL

pvp.qq.com/web201605/herodetail/544.shtml

pvp.qq.com/web201605/herodetail/545.shtml

我们就可以发现,URL只有后面的数字发生了改变,那么我们就可以在URL上做文章,但是还有一个问题,我们并不知道这个数字是从多少开始从多少结束,而且我们也不清楚数字对应的英雄是谁。

于是我就回到了最开始的页面,打开F12,这个是我凭经验进行寻找的,一般这类图片的网站基本上是动态的,所以一定是需要用到抓包工具的,于是我进行抓包,发现了其中的奥秘如下图:

c9e331f9602846d590b1d900f47eb778.png

 一般来说这类JSON数据里面是包括了很多网站的参数的,并且看这个英文名字,太明显了好吗,herolist这不是直接把答案都告诉你了吗英雄列表。

点击这个json文件下载下来以后,就会发现奥秘,如下是其中的一个参数

[{
    "ename": 105,
    "cname": "廉颇",
    "title": "正义爆轰",
    "new_type": 0,
    "hero_type": 3,
    "skin_name": "正义爆轰|地狱岩魂",
    "moss_id": 3627

那么我们在对比一下这个ename是不是一个数字,然后用上面的网址pvp.qq.com/web201605/herodetail/545.shtml

把这个后面的545改成105就会发现对应上了是廉颇这个英雄的皮肤网页,那么就简单了,接下来只需要搞定皮肤页面的爬取就可以了,输入网址后的照片如下:

6fc24190b74a40698c4ac4c08fef192e.png

 

 接下来在这个皮肤的网页找到每个皮肤的地址,进行批量下载就好了,打开F12定位到皮肤的位置就会发现可以直接用XPATH进行爬取。如下图:

a43ba6d08832493eb6275924cb5383ca.png

 这个里面用到的也就是ename中的数据,所以现在所有的思路都已经清晰了,只需要进行代码的编写就好了

首先呢我们需要对json文件进行下载解析

response = requests.get('https://pvp.qq.com/web201605/js/herolist.json')
data = json.loads(response.text)

接下来就需要把json文件中的ename参数和cname参数用上,因为最后存文件就用得到文件夹命名还有之前构造URL

num = j['ename']
name = j['cname']
res2 = requests.get("https://pvp.qq.com/web201605/herodetail/{}.shtml".format(num))
res2_decode = res2.content.decode('gbk')
_element = etree.HTML(res2_decode)
element_img = _element.xpath('//div[@class="pic-pf"]/ul/@data-imgname')
name_img = element_img[0].split('|')

然后进行一个for循环,还有一个文件的写入

for i in range(0,10):
    res1 = requests.get("https://game.gtimg.cn/images/yxzj/img201606/skin/hero-info/{0}/{0}-bigskin-{1}.jpg".format(num,i+1))
    if res1.status_code == 200:
        aa = name_img[i].find('&')
        bb = name_img[i][:aa]
        res_img = res1.content
        a = './王者荣耀/' + str(name)
        b = './王者荣耀/' + str(name)+'/'+bb+'.jpg'
        if not os.path.exists('./王者荣耀/'):
            os.mkdir('./王者荣耀/')
        if not os.path.exists(a):
            os.mkdir(a)
        with open(b,"wb") as f:
            f.write(res_img)
            print(name,bb)

最后加上一个多线程,开启线程进行爬取就可以了,主体的代码就像下面一样

def pa(j):
    num = j['ename']
    name = j['cname']
    res2 = requests.get("https://pvp.qq.com/web201605/herodetail/{}.shtml".format(num))
    res2_decode = res2.content.decode('gbk')
    _element = etree.HTML(res2_decode)
    element_img = _element.xpath('//div[@class="pic-pf"]/ul/@data-imgname')
    name_img = element_img[0].split('|')

    for i in range(0,10):
        res1 = requests.get("https://game.gtimg.cn/images/yxzj/img201606/skin/hero-info/{0}/{0}-bigskin-{1}.jpg".format(num,i+1))
        if res1.status_code == 200:
            aa = name_img[i].find('&')
            bb = name_img[i][:aa]
            res_img = res1.content
            a = './王者荣耀/' + str(name)
            b = './王者荣耀/' + str(name)+'/'+bb+'.jpg'
            if not os.path.exists('./王者荣耀/'):
                os.mkdir('./王者荣耀/')
            if not os.path.exists(a):
                os.mkdir(a)
            with open(b,"wb") as f:
                f.write(res_img)
                print(name,bb)
        else:
            break


def duo():
    response = requests.get('https://pvp.qq.com/web201605/js/herolist.json')
    data = json.loads(response.text)
    for j in data:
        t = threading.Thread(target=pa,args=(j,))
        t.start()
        h.append(t)
    for k in h:
        k.join()

最后爬出来的效果也是非常好的如下图:

0f7a3a0fa76145bab35b489fbbe56ef8.png

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZTLJQ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值