第十五章 多线程练习图片爬取案例
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