爬虫(17)多线程练习 图片爬取案例

本文通过实例介绍了如何使用多线程爬取王者荣耀高清壁纸。首先分析了网页结构,发现数据是动态加载的,通过分析接口找到图片URL。接着通过解析JSON数据,提取所需URL,使用`parse.unquote()`方法解码URL,获取大图地址。最后,利用多线程爬取并保存图片,详细讲解了生产者消费者模型在爬虫中的应用。
摘要由CSDN通过智能技术生成

第十五章 多线程练习图片爬取案例

1. 多线程练习

我们对多线程的特点进行一下解释:
进程:系统中正在运行的应用程序。
单核的cpu一次只能执行一个进程,其他的进程处于非运行状态。多软件打开的时候,cpu在快速切换,由于速度之快,我们感受不到切换。
多核的cpu可以同时执行多个进程。
线程:进程中包含的执行单元。
一个进程可以包含多个线程。Python中一次只能执行一个线程。其他的都在阻塞和等待。原因就是有锁,防止多个线程竞争资源。
下面我们用普通方式和多线程方式来爬取王者荣耀高清图片来练习多线程爬虫。

2. 王者荣耀案例思路分析

我们的需求是要爬取王者荣耀的高清图片。网址在这里:https://pvp.qq.com/web201605/wallpaper.shtml
打开网页,下拉找到高清壁纸栏目,我们看到图片有三种规格:
在这里插入图片描述
我们要的是最后一个规格:1920×1200的高清图片。思路是只要找到图片对应的url就可以了。我们右键检查:
在这里插入图片描述
我们复制一下里面的url:http://shp.qpic.cn/ishow/2735011317/1610529849_84828260_19594_sProdImgNo_1.jpg/0
在网页上粘贴,回车查找。
在这里插入图片描述
得到的是一个小的封面图片。我们往下看有个ul标签,点击打开这个标签:

在这里插入图片描述
点开后发现有很多li标签,其中有三个li标签对应三个图片的规格:
在这里插入图片描述
我们点开其中第一个标签里面的href里的url发现是一个图片,后面每个li标签里的都是,规格不同。
在这里插入图片描述
下面我们分析一下整个页面的总标签是谁:
在这里插入图片描述
当我的鼠标放在一个id = "Work_List_Container_267733"的div标签上时,发现高清壁纸板块的所以图片被选中。那就是这个了。后面我的鼠标滑动到class = "p_newhero_item"的标签上的时候,其中一个图片被选中,那么这个标签时每张图片的位置。而其中的li标签是 每张图片的不同规格:在这里插入图片描述
下面我们查看一下总标签的id在不在网页源码里面:右键查看网页源码,Ctrl+F,在跳出的搜索框里粘贴id:
在这里插入图片描述
发先这个div标签里并没有url或者更多的信息。点击下一个,
在这里插入图片描述
也是这样。在下一个
在这里插入图片描述
下一个:
在这里插入图片描述
四个全部展开,没有我们要的信息。这就说明,这些数据并不在网页源码种,而是动态加载出来的。我们的办法有两个,一个是用selenium,一个是分析数据接口。今天我们分析数据接口。
点network,清空,然后刷新一下。点XHR看看加载内容:
在这里插入图片描述
通过标签的名字我们可以猜一猜:点一下herolist.json
在这里插入图片描述
点response看一下响应的数据:
在这里插入图片描述
在response收索框里输入jpg看看有没有这个文件。
在这里插入图片描述
我们只能去All里面去找了,后来找到了在一个worklist的元素里,有两个,内容是一样的,只不过时间戳不同。
在这里插入图片描述
我们点开下面的,然后点Response在出现的页面里Ctrl+F,在输入框里输入jpg,看到有180个jpg文件。那就是在这里了。
在这里插入图片描述

2.1 第一种方法:直接在Previews里面找

点击Preview:
·
复制最后一个高清的地址,然后到网页地址栏复制,回车发现并不能打开,这是因为这个地址是被编码过后的地址,需要我们解码一下:

from urllib import parse
img = parse.unquote('http%3A%2F%2Fshp%2Eqpic%2Ecn%2Fishow%2F2735012617%2F1611652314%5F84828260%5F14368%5FsProdImgNo%5F8%2Ejpg%2F200')
print(img)

输出:

D:\Python38\python.exe D:/work/爬虫/Day15/my_code/get_picture.py
http://shp.qpic.cn/ishow/2735012617/1611652314_84828260_14368_sProdImgNo_8.jpg/200

Process finished with exit code 0

把这个地址复制到网页地址栏里再试一下:
在这里插入图片描述
发现是封面小图。再次检查源码:
在这里插入图片描述
那我们把这里的url后面的200也改成0试试:
在这里插入图片描述
回车:
在这里插入图片描述
大图出现!鲜花在哪里?

2.2 第二种方法:通过json.cn网站解析

我们可以在Response里面复制其中的响应内容,然后打开json.cn网站,在左边输入框中粘贴进去:
在这里插入图片描述
打开json.cn网站:
在这里插入图片描述

发现报错了,不能正确解析,显示“无效的配置长度”。这是因为地址里有这样一段需要删除:

在这里插入图片描述

这是因为请求地址里有一段:
jsoncallback=jQuery的数据,原因是jQuery在解析jsoncallback时会返回jsoncallback的字符串,该字符串会被jsoncallback方法会所执行,执行时产生的数据会出现无法识别的问题。json.cn网站解析时就会报错。解决方法就是删除掉上图所示的数据。然后就能正确解析了。
在这里插入图片描述
后面的操作类似,就不再赘述了。以后遇到类似的问题都这样进行处理就可以了。

3. 获取数据

现在我们写代码来获取数据:

import requests


headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36','referer': 'https://pvp.qq.com/'}

def main():
    # 明确目标url
    page_url = 'https://apps.game.qq.com/cgi-bin/ams/module/ishow/V1.0/query/workList_inc.cgi?activityId=2735&sVerifyCode=ABCD&sDataType=JSON&iListNum=20&totalpage=0&page=0&iOrder=0&iSortNumClose=1&iAMSActivityId=51991&_everyRead=true&iTypeId=2&iFlowId=267733&iActId=2735&iModuleId=2735&_=1612141973825'
    # 把url里这一段删除:&jsoncallback=jQuery171013413315924847624_1612141973463
    res = requests.get(page_url,headers=headers)
    # 如果res.text 是个json类型的字符串
    print(type(res.json()),res.json())

if __name__ == '__main__':
    main()

执行结果:

<class 'dict'> {'iBltFlag': '0', 'iCache': '1', 'iRet': '0', 'iTotalLines': '468', 'iTotalPages': '24', 'sMsg': 'Successful', 'List': [{'dtInputDT': '2021%2D01%2D26%2017%3A11%3A54', 'iBallotNum': '0', 'iClickNum': '0', 'iDownloadNum': '0', 'iNonsupportNum': '0', 'iProdId': '1669', 'iStatus': '1', 'sProdImgNo_1': 'http%3A%2F%2Fshp%2Eqpic%2Ecn%2Fishow%2F2735012617%2F1611652313%5F84828260%5F14368%5FsProdImgNo%5F1%2Ejpg%2F200', 'sProdImgNo_2': 'http%3A%2F%2Fshp%2Eqpic%2Ecn%2Fishow%2F2735012617%2F1611652313%5F84828260%5F14368%5FsProdImgNo%5F2%2Ejpg%2F200', 'sProdImgNo_3': 'http%3A%2F%2Fshp%2Eqpic%2Ecn%2Fishow%2F2735012617%2F1611652313%5F84828260%5F14368%5FsProdImgNo%5F3%2Ejpg%2F200', 'sProdImgNo_4': 'http%3A%2F%2Fshp%2Eqpic%2Ecn%2Fishow%2F2735012617%2F1611652313%5F84828260%5F14368%5FsProdImgNo%5F4%2Ejpg%2F200', 'sProdImgNo_5': 'http%3A%2F%2Fshp%2Eqpic%2Ecn%2Fishow%2F2735012617%2F1611652313%5F84828260%5F14368%5FsProdImgNo%5F5%2Ejpg%2F200', 'sProdImgNo_6': 'http%3A%2F%2Fshp%2Eqpic%2Ecn%2Fishow%2F2735012617%2F1611652313%5F84828260%5F14368%5FsProdImgNo%5F6%2Ejpg%2F200', 'sProdImgNo_7': 'http%3A%2F%2Fshp%2Eqpic%2Ecn%2Fishow%2F2735012617%2F1611652314%5F84828260%5F14368%5FsProdImgNo%5F7%2Ejpg%2F200', 'sProdImgNo_8': 'http%3A%2F%2Fshp%2Eqpic%2Ecn%2Fishow%2F2735012617%2F1611652314%5F84828260%5F14368%5FsProdImgNo%5F8%2Ejpg%2F200', 'sProdName': '%E8%8A%88%E6%9C%88%2D%E7%99%BD%E6%99%B6%E6%99%B6', 'sThumbURL': 'http%3A%2F%2Fshp%2Eqpic%2Ecn%2Fishow%2F2735012617%2F1611652313%5F84828260%5F14368%5FsProdImgNo%5F1%2Ejpg%2F200'}, {'dtInputDT': '2021%2D01%2D20%2015%3A15%3A41', 'iBallotNum': '0', 'iClickNum': '0', 'iDownloadNum': '0', 'iNonsupportNum': '0', 'iProdId': '1667', 'iStatus': '1', 'sProdImgNo_1': 'http%3A%2F%2Fshp%2Eqpic%2Ecn%2Fishow%2F2735012015%2F1611126939%5F84828260%5F23512%5FsProdImgNo%5F1%2Ejpg%2F200', 'sProdImgNo_2': 'http%3A%2F%2Fshp%2Eqpic%2Ecn%2Fishow%2F2735012015%2F1611126939%5F84828260%5F23512%5FsProdImgNo%5F2%2Ejpg%2F200', 'sProdImgNo_3': 'http%3A%2F%2Fshp%2Eqpic%2Ecn%2Fishow%2F2735012015%2F1611126939%5F84828260%5F23512%5FsProd'http%3A%2F%2Fshp%2Eqpic%2Ecn%2Fishow%2F2735121015%2F1607585084%5F84828260%5F20640%5FsProdImgNo%5F7%2Ejpg%2F200', 'sProdImgNo_8': 'http%3A%2F%2Fshp%2Eqpic%2Ecn%2Fishow%2F2735121015%2F1607585084%5F84828260%5F20640%5FsProdImgNo%5F8%2Ejpg%2F200', 'sProdName': '%E6%BE%9CCG%E3%80%8A%E7%9B%AE%E6%A0%87%E3%80%8B', 'sThumbURL': 'http%3A%2F%2Fshp%2Eqpic%2Ecn%2Fishow%2F2735121015%2F1607585083%5F84828260%5F20640%5FsProdImgNo%5F1%2Ejpg%2F200'}, {'dtInputDT': '2020%2D12%2D10%2015%3A24%3A13', 'iBallotNum': '0', 'iClickNum': '0', 'iDownloadNum': '0', 'iNonsupportNum': '0', 'iProdId': '1643', 'iStatus': '1', 'sProdImgNo_1': 'http%3A%2F%2Fshp%2Eqpic%2Ecn%2Fishow%2F2735121015%2F1607585051%5F84828260%5F6762%5FsProdImgNo%5F1%2Ejpg%2F200', 'sProdImgNo_2': 'http%3A%2F%2Fshp%2Eqpic%2Ecn%2Fishow%2F2735121015%2F1607585052%5F84828260%5F6762%5FsProdImgNo%5F2%2Ejpg%2F200', 'sProdImgNo_3': 'http%3A%2F%2Fshp%2Eqpic%2Ecn%2Fishow%2F2735121015%2F1607585052%5F84828260%5F6762%5FsProdImgNo%5F3%2Ejpg%2F200', 'sProdImgNo_4': 'http%3A%2F%2Fshp%2Eqpic%2Ecn%2Fishow%2F2735121015%2F1607585052%5F84828260%5F6762%5FsProdImgNo%5F4%2Ejpg%2F200', 'sProdImgNo_5': 'http%3A%2F%2Fshp%2Eqpic%2Ecn%2Fishow%2F2735121015%2F1607585052%5F84828260%5F6762%5FsProdImgNo%5F5%2Ejpg%2F200', 'sProdImgNo_6': 'http%3A%2F%2Fshp%2Eqpic%2Ecn%2Fishow%2F2735121015%2F1607585052%5F84828260%5F6762%5FsProdImgNo%5F6%2Ejpg%2F200', 'sProdImgNo_7': 'http%3A%2F%2Fshp%2Eqpic%2Ecn%2Fishow%2F2735121015%2F1607585052%5F84828260%5F6762%5FsProdImgNo%5F7%2Ejpg%2F200', 'sProdImgNo_8': 'http%3A%2F%2Fshp%2Eqpic%2Ecn%2Fishow%2F2735121015%2F1607585052%5F84828260%5F6762%5FsProdImgNo%5F8%2Ejpg%2F200', 'sProdName': '%E6%BE%9CCG%E3%80%8A%E7%9B%AE%E6%A0%87%E3%80%8B', 'sThumbURL': 'http%3A%2F%2Fshp%2Eqpic%2Ecn%2Fishow%2F2735121015%2F1607585051%5F84828260%5F6762%5FsProdImgNo%5F1%2Ejpg%2F200'}, {'dtInputDT': '2020%2D12%2D10%2015%3A19%3A54', 'iBallotNum': '0', 'iClickNum': '0', 'iDownloadNum': '0', 'iNonsupportNum': '0', 'iProdId': '1642', 'iStatus': '1', 'sProdImgNo_1': 'http%3A%2F%2Fshp%2Eqpic%2Ecn%2Fishow%2F2735121015%2F1607584793%5F84828260%5F11833%5FsProdImgNo%5F1%2Ejpg%2F200', 'sProdImgNo_2': 'http%3A%2F%2Fshp%2Eqpic%2Ecn%2Fishow%2F2735121015%2F1607584793%5F8482826
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值