<随便写> 多线程的例子
'''
一个线程在使用这个共享的时候,其他线程必须等待他结束
通过"锁"实现,作用就是防止多个线程使用这片内存空间
进程:程序的一次执行
线程:cpu运算的基本调度单位
多线程:大量密集I/O处理,在等待响应的时候,其他线程去工作
多进程:大量的密集并行计算
scrapy:异步网络框架(很多协程在处理)
页码队列--线程取页码爬取(采集线程--网络IO)--数据队列(得到的响应)--线程解析网页(解析线程磁盘IO)--解析后的数据存储
'''
# 请求
import requests
# 队列
from multiprocessing import Queue
# 线程
from threading import Thread
import threading
# 解析
from lxml import etree
# 存储
import json
import time class ThreadCrawl(Thread):
def __init__(self, threadName, pageQueue, dataQueue):
# 调用父类的初始化方法
super(ThreadCrawl, self).__init__()
self.threadName = threadName
self.pageQueue = pageQueue
self.dataQueue = dataQueue
self.headers = {"User-Agent":"Mozilla/5.0(Windows NT 10.0;WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.170 Safari/537.36"} # thread.start()会执行run方法
def run(self):
print("启动"+self.threadName)
while not CRAWL_EXIT:
try:
# 从页码队列取出一个数字,
# 可选参数block(默认Ture)
# 1.队列为空,block为Ture,会进入阻塞状态,直到有新的值进入队列
# 2.如果队列为空.block为False,会弹出Queue.empty()出错
page = self.pageQueue.get(False)
url = "https://www.qiushibaike.com/text/page/" + str(page) + "/"
content = requests.get(url,headers=self.headers).text
#调用数据队列,将源码放进去
self.dataQueue.put(content)
except:
pass
print("结束"+self.threadName) class ThreadParse(Thread):
def __init__(self,threadName,dataQueue,filename,lock):
super(ThreadParse,self).__init__()
self.threadName = threadName
self.dataQueue = dataQueue
self.filename = filename
self.lock = lock def run(self):
while not PARSE_EXIT:
try:
html = self.dataQueue.get(False)
self.parse(html)
except:
pass def parse(self,html):
html = etree.HTML(html)
print(html) # with 后面有两个必须执行的操作:__enter__ 和 _exit__
# 不管里面的操作结果如何,都会执行打开、关闭
# 打开锁、处理内容、释放锁
with self.lock:
# 写入存储的解析后的数据
self.filename.write(json.dumps(html, ensure_ascii=False).encode("utf-8") + "\n") CRAWL_EXIT = False
PARSE_EXIT = False def main():
# 页码队列,可以存储20个值
pageQueue = Queue(20)
# 放入1-10数字,先进先出
for i in range(1, 21):
pageQueue.put(i) # 数据队列,HTML源码,不写参数,默认无限
dataQueue = Queue() # 创建锁
lock = threading.Lock() # 采集线程名字
crawlList = ["采集线程1号", "采集线程2号", "采集线程3号"] # 存储采集线程
thread_crawl = []
for threadName in crawlList:
# 写一个
thread = ThreadCrawl(threadName, pageQueue, dataQueue)
thread.start()
thread_crawl.append(thread) filename = open("duanzi.json","a")
#解析线程名字
parseList = ["解析线程1号","解析线程2号","解析线程3号"]
threadparse = []
for threadName in parseList:
thread = ThreadParse(threadName,dataQueue,filename,lock)
thread.start()
threadparse.append(thread) #如果队列不为空,一直在这等待
while not pageQueue.empty():
pass
#如果队列为空,CRAWL_EXIT = True 退出
global CRAWL_EXIT
CRAWL_EXIT = True #加阻塞,线程做完才能运行主线程
for thread in thread_crawl:
thread.join()
print(thread) while not dataQueue.empty():
pass global PARSE_EXIT
PARSE_EXIT = True for thread in threadparse:
thread.join()
print(thread) with lock:
# 关闭文件
filename.close()
print("谢谢使用") if __name__ == '__main__':
main()
<随便写> 多线程的例子的更多相关文章
- python两段多线程的例子
记录瞬间 =====================其一===================== # coding:UTF-8 import os import threading from tim ...
- C#多线程简单例子讲解
C#多线程简单例子讲解 标签: 多线程c#threadobjectcallbacktimer 分类: C#(7) 转载网址:http://www.knowsky.com/540518.html .NE ...
- Peer模式的多线程程序例子
Peer模式的多线程程序例子 程序的模型大概是这样的.有一个master(),用来分发任务.有N个多线程的slave用来处理任务. 主程序里可以这样调用: 可以看出,上面这段程序还是依赖于Proces ...
- Jquery 随便写些知识点
针对jQuery随便写些觉得还挺实用的一些东西,也没系统的去理一番,只是想到哪写到哪,写的不完全也请多见谅. jQuery和其他javascript库产生$符号冲突了?$符号想必用jQuery的人都不 ...
- 用thinkphp写的一个例子:抓取网站的内容并且保存到本地
我需要写这么一个例子,到电子课本网下载一本电子书. 电子课本网的电子书,是把书的每一页当成一个图片,然后一本书就是有很多张图片,我需要批量的进行下载图片操作. 下面是代码部分: public func ...
- 【转】忙里偷闲写的小例子---读取android根目录下的文件或文件夹
原文网址:http://www.cnblogs.com/wenjiang/p/3140055.html 最近几天真的是各种意义上的忙,忙着考试,还要忙着课程设计,手上又有外包的项目,另一边学校的项目还 ...
- python多线程简单例子
python多线程简单例子 作者:vpoet mail:vpoet_sir@163.com import thread def childthread(threadid): print "I ...
- 忙里偷闲写的小例子---读取android根目录下的文件或文件夹
最近几天真的是各种意义上的忙,忙着考试,还要忙着课程设计,手上又有外包的项目,另一边学校的项目还要搞,自己的东西还在文档阶段,真的是让人想死啊!! 近半个月来,C#这方面的编码比较多,android和 ...
- 再议perl写多线程端口扫描器
再议perl写多线程端口扫描器 http://blog.csdn.net/sx1989827/article/details/4642179 perl写端口多线程扫描器 http://blog.csd ...
随机推荐
- PHP PDO 大对象 (LOBs)
应用程序在某一时刻,可能需要在数据库中存储"大"数据. "大"通常意味着"大约 4kb 或以上",尽管某些数据库在数据达到"大&q ...
- Android源码的git下载地址
git clone https://android.googlesource.com/device/common.git git clone https://android.googlesour ...
- NX二次开发-创建直线UF_CURVE_create_line与NXOpen->CreateLine
NX11+VS2013 #include <uf.h> #include <uf_curve.h> #include <NXOpen/CurveCollection.hx ...
- SSDT
2.系统服务调度表SSDT及SSSDT Shadow 系统服务:由操作系统提供的一组函数(内核函数),API可以间接或者直接的调用系统服务.操作系统以动态链接库(DLL)的形式提供API. SSDT: ...
- Vue.js框架的基础指令
Vue.js 渐进式 javascript 框架,可以独立完成前后端分离式web项目的javascript框架 js是页面脚本语言,用来控制或是辅助页面搭建,vue是js功能的集合体. 三大主流前端框 ...
- 简述MapReduce数据流
目前it基本都是一个套路,获得数据然后进行逻辑处理,存储数据. 基本上弄清楚整个的数据流向就等于把握了命脉. 现在说说mapreduce的数据流 1.首先数据会按照TextInputFormat按照特 ...
- 20140316 window live write 插件 推荐代码高亮插件 构造函数只能用初始化成员列表方式的例子
1.window live write 插件:http://www.cnblogs.com/liuxianan/archive/2013/04/13/3018732.html 2.推荐代码高亮插件:W ...
- MyBatis中使用RowBounds对查询结果集进行分页
MyBatis可以使用RowBounds逐页加载表数据.RowBounds对象可以使用offset和limit参数来构建.参数offset表示开始位置,而limit表示要取的记录的数目 映射文件: & ...
- python 18 函数基础二
转自 http://www.cnblogs.com/BeginMan/p/3173328.html 一.装饰器(decorators) 装饰器的语法以@开头,接着是装饰器函数的名字.可选参数. 紧跟装 ...
- 整理及优化CSS代码的7个原则
作为网页设计师(前端工程师),你可能还记得曾经的那个网页大小建议:一个网页(包括HTML.CSS.Javacript.Flash和图片)尽量不要超过30KB的大小,随着互联网的日益庞大,网络带宽也在飞 ...