队列:
from queue import Queue
#创建队列对象
q = Queue()
#将url加入队列
q.put(url)
#判断队列是否为空
q.empyt()
#从队列中取一个值
q.get()
线程模块:
from threading from Thread
#用于存储建立的线程对象
List = []
for i in range(5):
#创建线程对象
t = Thread(target=函数名)
#将线程对象加入列表
List.append(t)
#创建并启动线程
t.start()
#等待回收所有线程
for i in list:
i.join()
下面是一个运用多线程抓取小米应用商店的案例:
首先查看页面是静态页面还是动态加载页面,
判断是动态加载页面,然后按F12进行抓包处理,当然也可以用Fiddler等抓包软件进行抓包处理。
抓取返回json数据的URL地址
查看并分析查询数据
通过处理拼接返回多个json数据的URL地址。
具体请求和解析代码实现如下:
import requests
import json
from threading import Thread
from queue import Queue
import time
class XiaomiSpider(object):
def init(self):
self.url = ‘http://app.mi.com/categotyAllListApi?page={}&categoryId=2&pageSize=30’
self.headers = {‘User-Agent’:‘Mozilla/5.0’}
# 创建队列
self.q = Queue()
self.i = 0
# URL入队列
def url_in(self):
for page in range(67):
url = self.url.format(str(page))
# 入队列
self.q.put(url)
# 线程事件函数:获取队列中URL,发请求解析处理数据
def get_data(self):
while True:
# 获取URL
if not self.q.empty():
url = self.q.get()
html = requests.get(
url,
headers=self.headers
).text
html = json.loads(html)
# html: 字典
for app in html['data']:
# 应用名称
app_name = app['displayName']
# 应用链接
app_link = 'http://app.mi.com/details?id=' + app['packageName']
d = {
'应用名称':app_name,
'应用链接':app_link
}
print(d)
self.i += 1
else:
break
def main(self):
# 入队列
self.url_in()
# 空列表
t_list = []
# 创建多个线程并启动线程
for i in range(10):
t = Thread(target=self.get_data)
t_list.append(t)
t.start()
# 回收线程
for i in t_list:
i.join()
print(self.i)
if name == ‘main’:
start = time.time()
spider = XiaomiSpider()
spider.main()
end = time.time()
print(‘执行时间:%.2f’ % (end-start))