感悟】

写完这篇日志后,有调了一段时间程序,又有了一点心得分享下:

一)爬稳定的数(dong)据(xi)最好存储下来,特别是数据库在国外的那种,下载时间成本太高昂了,存起来再处理,会节约很多时间;

二)对于python使用多线程写数据到sqlite数据库的做法绝对是浪费感情,是扯淡的行为,一个词叫“大材小用”,单线程足够了。

三)写数据到数据库中commit的次数最好减少,可以10000条insert后commit,当然这取决于事务本身和其他因素,我这里可以提升一倍的速度。

四)回到爬的数据上,文本形式存储对于散户使用是最优的,处理速度快,格式定义好,正则等功能完胜sqlite。

【问题情境】

最近手闲,想写一个简单的批量下载网页的python工具。当然爬虫的轻量级框架scrapy以前用过,还不错。因为这次需求很简单,就直接人肉搞了。结果各种问题就出来了。

其中的思路是,多线程数据库存储这些网页,也方便之后数据处理。但是跑多线程时,脚本经常死掉。开了50个线程,基本出现的错误提示就是"Recursive use of cursors not allowed".

【问题分析】

数据库跑多线程的故事吧,一般都是事务没提交无法保证原子性的问题。问题解决方案可直接看下面的【问题解决】部分。

检查了第一遍:

问题1:发现有个查询语句select没有提交,commit了一下。

分析1:这里感觉没有什么问题,因为查询没有改变数据库所以不提交也一样。

跑一遍:

似乎错误提示少了一些。此时,我insert数据的sleep时间是1sec.试了几遍,还是中途崩掉。

检查第二遍:

问题2:缩短insert的sleep时间,问题更严重了。很快姐崩了。

分析2:应该是insert频繁导致的sql语句冲突概率增加。总感觉这里有问题,就差了下资料,果然是sqlite3多线程的时候有猫腻。于是,在每个提交的位置都增加了线程锁,增强同步效果。

跑了一遍:

错误提示"Recursive use of cursors not allowed"没有再出现。

【解决方案】

加锁,提交。

lock = threading.Lock()

def Func(host,cursor,db):
  try:
    lock.acquire(True)
    res = cursor.execute('''...''',(host,))
    # do something
  finally:
    lock.release()

【其他】

python的sqlite3使用多线程的参数check_same_thread是需要的:

self.conn = sqlite3.connect(dbname, check_same_thread=False)

版权声明:本文为CSDN博主「counsellor」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/counsellor/article/details/43715007

最新文章

  1. python计算器
  2. 自定义View其实很简单系列1-12
  3. [linux] linux shell 将解析完毕的文件备份至其他目录
  4. java 工具类
  5. RSA算法小记
  6. 四则运算出题器(C++)-BUG修复
  7. 代码实现IMapcontrol当前视图输出为图片功能
  8. Access数据库一种树形结构的实现和子节点查询
  9. gpg: no valid OpenPGP data found
  10. JavaScript数学函数的操作
  11. 使用Fiddler解析WCF RIA Service传输的数据
  12. Java NIO与IO
  13. Android - 多语言自动适配
  14. Java高新技术 JDK1.5之新特性
  15. HTML5的Websocket(理论篇 I)
  16. 安卓高级8 SurfaceView案例三 结合mediaplay播放视频
  17. [翻译][架构设计]The Clean Architecture
  18. 采用ddt 可以把ddt获取的数据 塞进测试用例里面的备注里面去展示 (还没有试)
  19. C# 基于DocumentFormat.OpenXml的数据导出到Excel
  20. linux进程管理之信号控制

热门文章

  1. Linux 系统的安全加固
  2. Nginx安装启动过程报错libpcre.so.1 cannot open shared object file: No such file or directory
  3. Pytorch入门随手记
  4. spark2.0的10个特性介绍
  5. springboot 服务端获取前端传过来的参数7种方式
  6. “最不合格”的SAP应聘者: 从大学生到SAP成都研究院开发工程师
  7. MongoDB——理论及使用命令详解 数据库
  8. wlan相关查询命令
  9. PAT Basic 1085 PAT单位排行 (25 分)
  10. set调用add报错: