多线程队列下载天涯帖子

版本一:

  1. #coding:utf-8
  2. import Queue
  3. import threading
  4. import time
  5. import urllib2
  6. import re
  7. exitFlag = 0
  8. class myThread (threading.Thread):
  9. def __init__(self, threadID, name, q, txt_dict):
  10. threading.Thread.__init__(self)
  11. self.threadID = threadID
  12. self.name = name
  13. self.q = q
  14. self.txt_dict = txt_dict
  15. def run(self):
  16. print "Starting " + self.name
  17. process_data(self.name, self.q, self.txt_dict)
  18. print "Exiting " + self.name
  19. def process_data(threadName, q, txt_dict):
  20. while not exitFlag:
  21. queueLock.acquire()
  22. if not workQueue.empty():
  23. data = q.get()
  24. queueLock.release()
  25. print "%s processing %s" % (threadName, data)
  26. down_text(txt_dict, data)
  27. else:
  28. queueLock.release()
  29. time.sleep(1)
  30. def down_text(txt_dict, url):
  31. """根据传入的url抓出各页内容,按页数做键存入字典"""
  32. html_content =urllib2.urlopen(url, timeout=30).read()
  33. text_pattern = re.compile(‘<span>时间:(.*?)</span>.*?<!-- <div class="host-ico">楼主</div> -->.*?<div class="bbs-content.*?>\s*(.*?)</div>‘, re.DOTALL)
  34. text = text_pattern.findall(html_content)
  35. text_join = [‘\r\n\r\n\r\n\r\n‘.join(item) for item in text]
  36. txt_dict[url] = text_join
  37. def page(url):
  38. """根据第一页地址抓取总页数"""
  39. html_page = urllib2.urlopen(url, timeout=30).read()
  40. page_pattern = re.compile(r‘<a href="\S*?">(\d*)</a>\s*<a href="\S*?" class="\S*?">下页</a>‘)
  41. page_result = page_pattern.search(html_page)
  42. if page_result:
  43. page_num = int(page_result.group(1))
  44. return page_num
  45. def write_text(filename, dict, urls):
  46. """把字典内容按键(页数)写入文本,每个键值为每页内容的list列表"""
  47. tx_file = open(filename, ‘w+‘)
  48. for i in urls:
  49. print i
  50. tx_list = dict[i]
  51. for tx in tx_list:
  52. tx = tx.replace(‘<br>‘, ‘\r\n‘).replace(‘<br />‘, ‘\r\n‘).replace(‘ ‘, ‘‘)
  53. tx_file.write(tx.strip()+‘\r\n‘*4)
  54. tx_file.close()
  55. threadList = ["Thread-1", "Thread-2", "Thread-3"]
  56. queueLock = threading.Lock()
  57. workQueue = Queue.Queue(200)
  58. threads = []
  59. threadID = 1
  60. url = ‘http://bbs.tianya.cn/post-16-956795-1.shtml‘
  61. file_name =‘abc.txt‘
  62. my_page = page(url)
  63. my_dict = {}
  64. urls = []
  65. page_range = range(1, my_page+1)
  66. for num in page_range:
  67. myurl = ‘%s%s.shtml‘ % (url[:-7], num)
  68. urls.append(myurl)
  69. # 创建新线程
  70. for tName in threadList:
  71. thread = myThread(threadID, tName, workQueue, my_dict)
  72. thread.start()
  73. threads.append(thread)
  74. threadID += 1
  75. # 填充队列
  76. queueLock.acquire()
  77. for word in urls:
  78. workQueue.put(word)
  79. queueLock.release()
  80. # 等待队列清空
  81. while not workQueue.empty():
  82. pass
  83. # 通知线程是时候退出
  84. exitFlag = 1
  85. # 等待所有线程完成
  86. for t in threads:
  87. t.join()
  88. print "Exiting Main Thread"
  89. write_text(file_name, my_dict, urls)

版本二:

  1. #coding:utf-8
  2. import Queue
  3. import threading
  4. import time
  5. import urllib2
  6. import re
  7. import sys
  8. queue = Queue.Queue()
  9. url = ‘http://bbs.tianya.cn/post-16-996521-1.shtml‘
  10. urls=[]
  11. Dict_txt = {}
  12. file_name = ‘abc.txt‘
  13. class ThreadNum(threading.Thread):
  14. def __init__(self, queue):
  15. threading.Thread.__init__(self)
  16. self.queue = queue
  17. def run(self):
  18. while True:
  19. #消费者端,从队列中获取num
  20. num = self.queue.get()
  21. sys.stdout.flush()
  22. down_text(Dict_txt, num)
  23. print ‘**finished download %s**‘ % num
  24. time.sleep(1)
  25. #在完成这项工作之后,使用 queue.task_done() 函数向任务已经完成的队列发送一个信号
  26. self.queue.task_done()
  27. def down_text(txt_dict, url):
  28. """根据传入的url抓出各页内容,按页数做键存入字典"""
  29. print ‘--downling %s--‘ % url
  30. html_content =urllib2.urlopen(url, timeout=30).read()
  31. text_pattern = re.compile(‘<span>时间:(.*?)</span>.*?<!-- <div class="host-ico">楼主</div> -->.*?<div class="bbs-content.*?>\s*(.*?)</div>‘, re.DOTALL)
  32. text = text_pattern.findall(html_content)
  33. text_join = [‘\r\n\r\n\r\n\r\n‘.join(item) for item in text]
  34. txt_dict[url] = text_join
  35. def page(url):
  36. """根据第一页地址抓取总页数"""
  37. html_page = urllib2.urlopen(url, timeout=30).read()
  38. page_pattern = re.compile(r‘<a href="\S*?">(\d*)</a>\s*<a href="\S*?" class="\S*?">下页</a>‘)
  39. page_result = page_pattern.search(html_page)
  40. list1 = []
  41. if page_result:
  42. page_num = int(page_result.group(1))
  43. page_range = range(1, page_num+1)
  44. for num in page_range:
  45. myurl = ‘%s%s.shtml‘ % (url[:-7], num)
  46. list1.append(myurl)
  47. return list1
  48. def write_text(filename, dict, urls):
  49. """把字典内容按键(页数)写入文本,每个键值为每页内容的list列表"""
  50. tx_file = open(filename, ‘w+‘)
  51. for i in urls:
  52. tx_list = dict[i]
  53. for tx in tx_list:
  54. tx = tx.replace(‘<br>‘, ‘\r\n‘).replace(‘<br />‘, ‘\r\n‘).replace(‘ ‘, ‘‘)
  55. tx_file.write(tx.strip()+‘\r\n‘*4)
  56. tx_file.close()
  57. start = time.time()
  58. def main():
  59. #产生一个 threads pool, 并把消息传递给thread函数进行处理,这里开启10个并发
  60. urls = page(url)
  61. for i in range(5):
  62. t = ThreadNum(queue)
  63. t.start()
  64. #往队列中填错数据
  65. for num in urls:
  66. queue.put(num)
  67. #wait on the queue until everything has been processed
  68. queue.join()
  69. print ‘---- start write ----‘
  70. write_text(file_name, Dict_txt, urls)
  71. main()
  72. print"Elapsed Time: %s" % (time.time() - start)

--版本三

  1. #coding:utf-8
  2. import urllib
  3. import re
  4. import threading
  5. import os, time
  6. class Down_Tianya(threading.Thread):
  7. """多线程下载"""
  8. def __init__(self, url, num, dt):
  9. threading.Thread.__init__(self)
  10. self.url = url
  11. self.num = num
  12. self.txt_dict = dt
  13. def run(self):
  14. print ‘downling from %s‘ % self.url
  15. self.down_text()
  16. def down_text(self):
  17. """根据传入的url抓出各页内容,按页数做键存入字典"""
  18. html_content =urllib.urlopen(self.url).read()
  19. text_pattern = re.compile(‘<span>时间:(.*?)</span>.*?<!-- <div class="host-ico">楼主</div> -->.*?<div class="bbs-content.*?>\s*(.*?)</div>‘, re.DOTALL)
  20. text = text_pattern.findall(html_content)
  21. text_join = [‘\r\n\r\n\r\n\r\n‘.join(item) for item in text]
  22. self.txt_dict[self.num] = text_join
  23. def page(url):
  24. """根据第一页地址抓取总页数"""
  25. html_page = urllib.urlopen(url).read()
  26. page_pattern = re.compile(r‘<a href="\S*?">(\d*)</a>\s*<a href="\S*?" class="\S*?">下页</a>‘)
  27. page_result = page_pattern.search(html_page)
  28. if page_result:
  29. page_num = int(page_result.group(1))
  30. return page_num
  31. def write_text(dict, fn):
  32. """把字典内容按键(页数)写入文本,每个键值为每页内容的list列表"""
  33. tx_file = open(fn, ‘w+‘)
  34. pn = len(dict)
  35. for i in range(1, pn+1):
  36. tx_list = dict[i]
  37. for tx in tx_list:
  38. tx = tx.replace(‘<br>‘, ‘\r\n‘).replace(‘<br />‘, ‘\r\n‘).replace(‘ ‘, ‘‘)
  39. tx_file.write(tx.strip()+‘\r\n‘*4)
  40. tx_file.close()
  41. def main():
  42. url = ‘http://bbs.tianya.cn/post-16-996521-1.shtml‘
  43. file_name =‘abc.txt‘
  44. my_page = page(url)
  45. my_dict = {}
  46. print ‘page num is : %s‘ % my_page
  47. threads = []
  48. """根据页数构造urls进行多线程下载"""
  49. for num in range(1, my_page+1):
  50. myurl = ‘%s%s.shtml‘ % (url[:-7], num)
  51. downlist = Down_Tianya(myurl, num, my_dict)
  52. downlist.start()
  53. threads.append(downlist)
  54. """检查下载完成后再进行写入"""
  55. for t in threads:
  56. t.join()
  57. write_text(my_dict, file_name)
  58. print ‘All download finished. Save file at directory: %s‘ % os.getcwd()
  59. if __name__ == ‘__main__‘:
  60. main()

来自为知笔记(Wiz)

时间: 2024-10-21 02:50:01

多线程队列下载天涯帖子的相关文章

Android实现网络多线程断点续传下载(转)

本示例介绍在Android平台下通过HTTP协议实现断点续传下载. 我们编写的是Andorid的HTTP协议多线程断点下载应用程序.直接使用单线程下载HTTP文件对我们来说是一件非常简单的事.那么,多线程断点需要什么功能? 1.多线程下载, 2.支持断点. 使用多线程的好处:使用多线程下载会提升文件下载的速度.那么多线程下载文件的过程是:  (1)首先获得下载文件的长度,然后设置本地文件的长度. HttpURLConnection.getContentLength();//获取下载文件的长度 R

Android实现网络多线程断点续传下载

本示例介绍在Android平台下通过HTTP协议实现断点续传下载. 我们编写的是Andorid的HTTP协议多线程断点下载应用程序.直接使用单线程下载HTTP文件对我们来说是一件非常简单的事.那么,多线程断点需要什么功能? 1.多线程下载, 2.支持断点. 使用多线程的好处:使用多线程下载会提升文件下载的速度.那么多线程下载文件的过程是: (1)首先获得下载文件的长度,然后设置本地文件的长度. HttpURLConnection.getContentLength();//获取下载文件的长度 Ra

android 多线程断点续传下载 四 - 仿下载助手

我们先一起简单回顾下它的基本原理. http://blog.csdn.net/shimiso/article/details/6763664  android 多线程断点续传下载 一 http://blog.csdn.net/shimiso/article/details/6763986  android 多线程断点续传下载 二 http://blog.csdn.net/shimiso/article/details/8448544  android 多线程断点续传下载 三 界面效果 线程池 T

多线程断点下载原理(java代码实例演示)

其实多线程断点下载原理,很简单的,那么我们就来先了解下,如何实现多线程的断点下载,首先:你必须明白第一点,那么就是,什么是多线程下载,该知识点可以查看本博客上一篇文章,Android之多线程下载原理,断点下载呢,其实就是在这个的基础之上添加了一些东西,那么添加了什么东西了,现在来做一个详细的了解. 1.在下载的过程中,边下载,变用一个文件来记录下载的位置,也就是下载了多少的数据 1.创建文件 2.记录下载多少数据 3.存储数据 2.第二次下载的时候,就去读取文件中是否存有数据,读取上次下载的位置

Java之多线程断点下载的实现

RandomAccessFile类: 此类的实例支持对随机訪问文件的读取和写入.随机訪问文件的行为相似存储在文件系统中的一个大型 byte 数组. 存在指向该隐含数组.光标或索引,称为文件指针.输入操作从文件指针開始读取字节.并随着对字节的读取而前移此文件指针. 假设随机訪问文件以读取/写入模式创建,则输出操作也可用.输出操作从文件指针開始写入字节.并随着对字节的写入而前移此文件指针.写入隐含数组的当前末尾之后的输出操作导致该数组扩展.该文件指针能够通过 getFilePointer 方法读取.

Android/java http多线程断点下载(附源码)

先看下项目结构: http多线程断点下载涉及到 数据库,多线程和http请求等几个模块,东西不是很多,想弄清楚也不是很困难,接下来我和大家分享下我的做法. 一.先看MainActivity.java 成员变量,主要是一些下载过程的变量和handler private String path = "http://192.168.1.3:8080/wanmei/yama.apk"; private String sdcardPath; private int threadNum = 5;

iOS开发网络篇—大文件的多线程断点下载(转)

http://www.cnblogs.com/wendingding/p/3947550.html iOS开发网络篇—多线程断点下载 说明:本文介绍多线程断点下载.项目中使用了苹果自带的类,实现了同时开启多条线程下载一个较大的文件.因为实现过程较为复杂,所以下面贴出完整的代码. 实现思路:下载开始,创建一个和要下载的文件大小相同的文件(如果要下载的文件为100M,那么就在沙盒中创建一个100M的文件,然后计算每一段的下载量,开启多条线程下载各段的数据,分别写入对应的文件部分). 项目中用到的主要

Python实现多线程HTTP下载器

本文将介绍使用Python编写多线程HTTP下载器,并生成.exe可执行文件. 环境:windows/Linux + Python2.7.x 单线程 在介绍多线程之前首先介绍单线程.编写单线程的思路为: 解析url: 连接web服务器: 构造http请求包: 下载文件. 接下来通过代码进行说明. 解析url 通过用户输入url进行解析.如果解析的路径为空,则赋值为'/':如果端口号为空,则赋值为"80":下载文件的文件名可根据用户的意愿进行更改(输入'y'表示更改,输入其它表示不需要更

Android多线程断点续传下载

这个月接到一个项目,要写一个像360助手一样的对于软件管理的APP:其中,遇到了一个问题:多线程断点下载 这个 ,由于之前没有写过这方面的应用功能.所以,不免要自学了.然后就在各个昂站上收索并整理了一下.跟大家分享一下,也能加深我在这方面的理解. 什么是多线程下载? 多线程下载其实就是迅雷,BT一些下载原理,通过多个线程同时和服务器连接,那么你就可以榨取到较高的带宽了,大致做法是将文件切割成N块,每块交给单独一个线程去下载,各自下载完成后将文件块组合成一个文件,程序上要完成做切割和组装的小算法