python3 多线程获取数据实例

import requests
import json
from retrying import retry
from lxml import etree
from queue import Queue
import threading

class QiuShi:
  def __init__(self):
    # 定义三个队列
    self.url_queue = Queue()
    self.html_queue = Queue()
    self.content_list_queue = Queue()
    self.headers = {
    "User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36"
    }

  def get_url_list(self):
    url_list = [‘https://www.qiushibaike.com/8hr/page/{}/‘.format(i) for i in range(1, 14)]
    for url in url_list:
      # 将url使用put方法放入队列
      self.url_queue.put(url)

  @retry(stop_max_attempt_number=3)
  def _parse_url(self, url):
    response = requests.get(url, headers=self.headers, timeout=3)
    assert response.status_code == 200
    return etree.HTML(response.content)

  def parse_url(self):
  # 这里需要一个url。
  # 因为url = self.url_queue.get()只会从队列里取一次url.所以这里需要加while True循环来取。
  # 当url队列里没有url的时候这里会堵塞等待,只要有就取。
  # 但是取过后队列的基数并没有减1(并没有减去刚取走的url),所以要在下面使用task_done()
  while True:
    url = self.url_queue.get()
    print(url)
    try:
      html = self._parse_url(url)
    except:
      html = None
    # 将html添加到队列里
    self.html_queue.put(html)
    self.url_queue.task_done()

  def get_content_list(self):
    # 和上面一样
    while True:
      html = self.html_queue.get()
      if html is not None:
        div_list = html.xpath(‘//div[@id="content-left"]/div‘)
        content_list = []
        for div in div_list:
          item = {}
          item[‘name‘] = div.xpath(‘.//h2/text()‘)[0].replace("\n", "") if len(div.xpath(‘.//h2/text()‘)) > 0 else None
          item[‘content‘] = div.xpath(‘.//div[@class="content"]/span/text()‘)[0].replace("\n", "") if len(div.xpath(‘.//div[@class="content"]/span/text()‘)) > 0 else None
          item[‘comment‘] = div.xpath(‘.//i[@class="number"]/text()‘)[1] if len(div.xpath(‘.//i[@class="number"]/text()‘)) > 0 else None
          item[‘img‘] = div.xpath(‘.//img/@src‘) if len(div.xpath(‘.//img/@src‘)) > 0 else None

          content_list.append(item)
         self.content_list_queue.put(content_list)
      self.html_queue.task_done()

  def save_content_list(self):
    while True:
      content_list = self.content_list_queue.get()

      with open("qiubai.json", "a", encoding="utf-8") as f:
        for content in content_list:
          json.dump(content, f, ensure_ascii=False, indent=2)
          f.write(‘,\n‘)

      self.content_list_queue.task_done()

  def run(self):
    thread_list = []
    # 创建一个提取url的线程
    t_url = threading.Thread(target=self.get_url_list)
    thread_list.append(t_url)
    # 因为发送请求比较耗时,这里我们就用多线程来做
    for i in range(5):
      t_parse = threading.Thread(target=self.parse_url)
      thread_list.append(t_parse)
    # 提取数据也比较耗时,这里我们也使用多线程
    for i in range(3):
      t_get_content_list = threading.Thread(target=self.get_content_list)
      thread_list.append(t_get_content_list)
    # 保存数据必须用一个线程要数据就会乱
    t_save = threading.Thread(target=self.save_content_list)
    thread_list.append(t_save)
    for t in thread_list:
      t.setDaemon(True) # 守护线程
      t.start()
    # 当所有队列里没有数据,基数都等于0的时候主线程结束。否则一直堵塞在q.join()
    for q in [self.content_list_queue, self.html_queue, self.url_queue]:
      q.join()

if __name__ == ‘__main__‘:
qiubai = QiuShi()
qiubai.run()

时间: 2024-10-10 23:17:27

python3 多线程获取数据实例的相关文章

ios 异步多线程 获取数据

简介 iOS有三种多线程编程的技术,分别是: (一)NSThread (二)Cocoa NSOperation (三)GCD(全称:Grand Central Dispatch) 这三种编程方式从上到下,抽象度层次是从低到高的,抽象度越高的使用越简单,也是Apple最推荐使用的. 三种方式的优缺点介绍: 1)NSThread: 优点:NSThread 比其他两个轻量级 缺点:需要自己管理线程的生命周期,线程同步.线程同步对数据的加锁会有一定的系统开销 NSThread实现的技术有下面三种: 一般

HBase 高性能获取数据 - 多线程批量式解决办法

在前篇博客里已经讲述了通过一个自定义 HBase Filter来获取数据的办法,在末尾指出此办法的性能是不能满足应用要求的,很显然对于如此成熟的HBase来说,高性能获取数据应该不是问题.下面首先简单介绍了搜索引擎的性能,然后详细说明了HBase与MySQL的性能对比,这里的数据都是经过实际的测试获得的.最后,给出了采用多线程批量从HBase中取数据的方案,此方案经过测试要比通过自定义Filter的方式性能高出很多. Solr和HBase专辑 1.“关于Solr的使用总结的心得体会”(http:

多线程获取数据库数据

在开发中,如大量获取数据时,不但速度慢,而且影响效率,下面就给大家介绍下用多线程获取数据库数据: 1.首先新建一个获取实体列表的方法,如想获取数量或其他类型,需要另外编写方法,这里只是做简单的介绍: /// <summary> /// 根据SQL语句返回实体集合,这里不能返回IQueryable,否则在线程中会获取不到上下文对象 /// </summary> /// <typeparam name="T"></typeparam> ///

第五章 “我要点爆”微信小程序云开发实例之从云端获取数据制作首页

下面我们来实现从云端获取数据,完成首页世界页面index的制作,首页分为4个数据列表导航页面,页面具体内容如下: 推荐:为用户推荐最新的点爆信息,它包含文本点爆内容和语音点爆内容. 文爆:筛选出文字点爆内容,只显示文字点爆内容. 音爆:筛选出语音点爆内容,只显示语音点爆内容. 爆榜:将点爆内容取出前20名进入排行. [实现页面内数据列表的滚动和导航切换后,每个导航下数据列表都在顶部] 由于我们使用的头部导航栏是通过数据绑定在同一页面进行切换,所以当一个页面内数据列表向下滚动后,切换导航后页面的s

Python进阶(三十四)-Python3多线程解读

Python进阶(三十四)-Python3多线程解读 线程讲解 ??多线程类似于同时执行多个不同程序,多线程运行有如下优点: 使用线程可以把占据长时间的程序中的任务放到后台去处理. 用户界面可以更加吸引人,这样比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进度条来显示处理的进度. 程序的运行速度可能加快. 在一些等待的任务实现上如用户输入.文件读写和网络收发数据等,线程就比较有用了.在这种情况下我们可以释放一些珍贵的资源如内存占用等等. ??线程在执行过程中与进程还是有区别的.每个独立

python3多线程

多线程类似于同时执行多个不同程序,多线程运行有如下优点:(推荐学习:web前端视频教程) 使用线程可以把占据长时间的程序中的任务放到后台去处理. 用户界面可以更加吸引人,比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进度条来显示处理的进度. 程序的运行速度可能加快. 在一些等待的任务实现上如用户输入.文件读写和网络收发数据等,线程就比较有用了.在这种情况下我们可以释放一些珍贵的资源如内存占用等等. 每个独立的线程有一个程序运行的入口.顺序执行序列和程序的出口.但是线程不能够独立执行,必

【REACT NATIVE 系列教程之十三】利用LISTVIEW与TEXTINPUT制作聊天/对话框&&获取组件实例常用的两种方式

本站文章均为 李华明Himi 原创,转载务必在明显处注明: 转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/react-native/2346.html 本篇Himi来利用ListView和TextInput这两种组件实现对话.聊天框. 首先需要准备的有几点:(组件的学习就不赘述了,简单且官方有文档) 1. 学习下 ListView: 官方示例:http://reactnative.cn/docs/0.27/tutorial.html#content

C#/.NET使用HttpWebRequest、SqlBulkCopy从API获取数据批量插入DB

小弟新手程序员一枚,代码技术和文章水平均不才.所写文章均为对自己所写所学代码的简单记录,可能对于老手程序员营养价值不高,望莫见怪. 我工作上有个需求:从某处API接口上获取数据(大约1W条而已)并插入到数据库中. 楼主刚毕业菜鸟,没做过批量插入操作.借助baidu搜索得知SqlBulkCopy可以实现.SqlBulkCopy相关的原理,我现在还没了解就不摆弄了,以后补上! (不要问为什么不用google,公司内网就连msdn.microsoft.com都不给上!另外我公司是开发C#/.NET的,

vue 中使用 AJAX获取数据的方法

在VUE开发时,数据可以使用jquery和vue-resource来获取数据.在获取数据时,一定需要给一个数据初始值. 看下例: <script type="text/javascript"> new Vue({ el:'#app', data:{data:""}, created:function(){ var url="json.jsp"; var _self=this; $.get(url,function(data){ _se