一篇文章教会你用Python多线程获取小米应用商店App
【一、项目背景】
小米应用商店给用户发现最好的安卓应用和游戏,安全可靠,可是要下载东西要一个一个的搜索太麻烦了。而已速度不是很快。
今天用多线程爬取小米应用商店的游戏模块。快速获取。
【二、项目目标】
目标 :应用分类 - 聊天社交 应用名称, 应用链接,显示在控制台供用户下载。
【三、涉及的库和网站】
1、网址:百度搜 - 小米应用商店,进入官网。
2、涉及的库:requests、threading 、queue 、json、time
3、软件:PyCharm
【四、项目分析】
1、确认是否为动态加载。
通过页面局部刷新, 右键查看网页源代码,搜索关键字未搜到 。断定此网站为动态加载网站,需要抓取网络数据包分析。
2、使用chrome浏览器,F12抓取网络数据包。
1)抓取返回json数据的URL地址(Headers中的Request URL)。
http://app.mi.com/categotyAllListApi?page={}&categoryId=2&pageSize=30
2)查看并分析查询参数(headers中的Query String Parameters)。
page: 1 categoryId: 2 pageSize: 30
发现只有page再变,0 1 2 3 ... ... ,这样我们就可以通过控制page的直拼接多个返回json数据的URL地址。
【五、项目实施】
1、我们定义一个class类继承object,然后定义init方法继承self,再定义一个主函数main继承self。准备导入库,url地址和请求头headers。
import requests from threading import Thread from queue import Queue import json import time class XiaomiSpider(object): def __init__(self): self.headers = {'User-Agent':'Mozilla/5.0'} self.url = 'http://app.mi.com/categotyAllListApi?page={}&categoryId=15&pageSize=30' def main(self): pass if __name__ == '__main__': imageSpider = XiaomiSpider() imageSpider.main()
2、定义队列,用来存放URL地址
self.url_queue = Queue()
3、URL入队列
def url_in(self): # 拼接多个URL地址,然后put()到队列中 for i in range(67): self.url.format((str(i))) self.url_queue.put(self.url)
4、定义线程事件函数get_page(请求数据)
def get_page(self): # 先get()URL地址,发请求 while True: # 当队列不为空时,获取url地址 if not self.url_queue.empty(): url = self.url_queue.get() html = requests.get(url,headers=self.headers).text self.parse_page(html) else: break
5、定义函数parse_page 解析json模块,提取应用名称,应用链接内容。
# 解析函数 def parse_page(self,html): app_json = json.loads(html) for app in app_json['data']: # 应用名称 name = app['displayName'] # 应用链接 link = 'http://app.mi.com/details?id={}'.format(app['packageName']) d = { '名称' : name,'链接' : link } print(d)
6、main方法, 定义t_list = [] 存放所有线程的列表。调用get_page多线程爬取。
def main(self): self.url_in() # 存放所有线程的列表 t_list = [] for i in range(10): t = Thread(target=self.get_page) t.start() t_list.append(t)
7、for循环遍历列表,统一回收线程。
# 统一回收线程 for p in t_list: p.join()
8、统计一下执行时间。
start = time.time() spider = XiaomiSpider() spider.main() end = time.time() print('执行时间:%.2f' % (end-start))
【六、效果展示】
1、运行程序。点击运行,将游戏名称,下载链接,执行时间,显示在控制台。
2、点击蓝色的网址可以直接去到下载页面下载应用,如下图所示。
【七、总结】
1、不建议抓取太多数据,容易对服务器造成负载,浅尝辄止即可。
2、Python多线程优点。使用线程可以把占据长时间的程序中的任务放到后台去处,程序的运行速度可能加快。
3、单线程可以被抢占(中断),而已多线程就有了更多的选择。而已在其他线程正在运行时,线程可以暂时搁置(也称为睡眠)。可以释放一些珍贵的资源如内存占用。
4、大家也可以尝试在爬取其他分类,按照操作步骤,自己尝试去做。自己实现的时候,总会有各种各样的问题,切勿眼高手低,勤动手,才可以理解的更加深刻。
5、需要本文源码的小伙伴,后台回复“小米应用”四个字,即可获取。
看完本文有收获?请转发分享给更多的人
IT共享之家
入群请在微信后台回复【入群】

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
2.3.3 CGLIB动态代理 -《SSM深入解析与项目实战》
2.3.3 CGLIB动态代理 前面介绍了JDK的动态代理,从一些实例也可以看到,JDK动态代理是依赖于实现的接口的。而CGLIB弥补了这个缺点,让我们在不需要实现接口的情况下,也可以实现动态代理。JDK动态代理和CGLIB动态代理在Spring实现AOP中都是使用到的技术,Spring AOP默认是使用JDK动态代理来代理接口的,但是可以进行强制使用CGLIB动态代理。 CGLIB内部使用了ASM(Java字节码操控框架)来进行转换字节码。可以代理没有接口类的类。所以相比较JDK动态代理来说,灵活一些,更值得称赞的地方是,由于CGLIB第通过字节码产生子类进行覆盖委托类的非final方法进行代理,而JDK动态代理使用Java类反射进行代理,所以CGLIB动态代理比JDK动态代理更快。注意,CGLIB不能对final和私有方法进行代理。 实例演示。首先创建一个委托类(目标类)。 代码清单2-25:AliPay目标类 public class AliPay { public void pay(String operation) { System.out.println("进行AliPay...
- 下一篇
Java泛型初探
前言 在学习java掉头的日子里很多青年脱坑,同时也有很多青年入坑,但入坑的时候可能没有什么好的指导或者学习方法可能头发掉的一发不可收拾…… 笔者有个学弟就遇到了相同的境遇,学弟被泛型搞得头晕目眩,搞不懂泛型是个啥玩意。天天用的泛型也不知道啥玩意(他可能都不知道他有没有用泛型)。立图为证!当然,笔者深度还欠缺,如果错误还请指正! 本篇就根据笔者的理解简单的介绍一下泛型(深入还需自己),如果深度不够或者有错误还请见谅。 泛型是程序设计语言的一种特性。允许程序员在强类型程序设计语言中编写代码时定义一些可变部分,那些部分在使用前必须作出指明。各种程序设计语言和其编译器、运行环境对泛型的支持均不一样。将类型参数化以达到代码复用提高软件开发工作效率的一种数据类型。泛型类是引用类型,是堆对象,主要是引入了类型参数这个概念。——百度百科 没有泛型的时候 泛型,从字面的意思来看,广泛的意思,能够广泛的代表或者处理某一类事务的类型(java集合类)。在没有泛型的时候,你会如何去处理?比如你写链表的时候。可能会这样: public class node { public int value;//节点的结果...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- SpringBoot2整合Redis,开启缓存,提高访问速度
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- CentOS7安装Docker,走上虚拟化容器引擎之路
- CentOS7设置SWAP分区,小内存服务器的救世主
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- MySQL8.0.19开启GTID主从同步CentOS8
- Hadoop3单机部署,实现最简伪集群
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题