python练习题之

2023-10-26

@本文来源于公众号:csdn2299,喜欢可以关注公众号 程序员学府
安装Tornado
省事点可以直接用grequests库,下面用的是tornado的异步client。 异步用到了tornado,根据官方文档的例子修改得到一个简单的异步爬虫类。可以参考下最新的文档学习下。
pip install tornado

异步爬虫

#!/usr/bin/env python
# -*- coding:utf-8 -*-
 
import time
from datetime import timedelta
from tornado import httpclient, gen, ioloop, queues
import traceback
 
 
class AsySpider(object):
  """A simple class of asynchronous spider."""
  def __init__(self, urls, concurrency=10, **kwargs):
    urls.reverse()
    self.urls = urls
    self.concurrency = concurrency
    self._q = queues.Queue()
    self._fetching = set()
    self._fetched = set()
 
  def fetch(self, url, **kwargs):
    fetch = getattr(httpclient.AsyncHTTPClient(), 'fetch')
    return fetch(url, **kwargs)
 
  def handle_html(self, url, html):
    """handle html page"""
    print(url)
 
  def handle_response(self, url, response):
    """inherit and rewrite this method"""
    if response.code == 200:
      self.handle_html(url, response.body)
 
    elif response.code == 599:  # retry
      self._fetching.remove(url)
      self._q.put(url)
 
  @gen.coroutine
  def get_page(self, url):
    try:
      response = yield self.fetch(url)
      print('######fetched %s' % url)
    except Exception as e:
      print('Exception: %s %s' % (e, url))
      raise gen.Return(e)
    raise gen.Return(response)
 
  @gen.coroutine
  def _run(self):
    @gen.coroutine
    def fetch_url():
      current_url = yield self._q.get()
      try:
        if current_url in self._fetching:
          return
 
        print('fetching****** %s' % current_url)
        self._fetching.add(current_url)
 
        response = yield self.get_page(current_url)
        self.handle_response(current_url, response)  # handle reponse
 
        self._fetched.add(current_url)
 
        for i in range(self.concurrency):
          if self.urls:
            yield self._q.put(self.urls.pop())
 
      finally:
        self._q.task_done()
 
    @gen.coroutine
    def worker():
      while True:
        yield fetch_url()
 
    self._q.put(self.urls.pop())  # add first url
 
    # Start workers, then wait for the work queue to be empty.
    for _ in range(self.concurrency):
      worker()
 
    yield self._q.join(timeout=timedelta(seconds=300000))
    assert self._fetching == self._fetched
 
  def run(self):
    io_loop = ioloop.IOLoop.current()
    io_loop.run_sync(self._run)
 
 
class MySpider(AsySpider):
 
  def fetch(self, url, **kwargs):
    """重写父类fetch方法可以添加cookies,headers,timeout等信息"""
    cookies_str = "PHPSESSID=j1tt66a829idnms56ppb70jri4; pspt=%7B%22id%22%3A%2233153%22%2C%22pswd%22%3A%228835d2c1351d221b4ab016fbf9e8253f%22%2C%22_code%22%3A%22f779dcd011f4e2581c716d1e1b945861%22%7D; key=%E9%87%8D%E5%BA%86%E5%95%84%E6%9C%A8%E9%B8%9F%E7%BD%91%E7%BB%9C%E7%A7%91%E6%8A%80%E6%9C%89%E9%99%90%E5%85%AC%E5%8F%B8; think_language=zh-cn; SERVERID=a66d7d08fa1c8b2e37dbdc6ffff82d9e|1444973193|1444967835; CNZZDATA1254842228=1433864393-1442810831-%7C1444972138"  # 从浏览器拷贝cookie字符串
    headers = {
      'User-Agent': 'mozilla/5.0 (compatible; baiduspider/2.0; +http://www.baidu.com/search/spider.html)',
      'cookie': cookies_str
    }
    return super(MySpider, self).fetch(  # 参数参考tornado文档
      url, headers=headers, request_timeout=1
    )
 
  def handle_html(self, url, html):
    print(url, html)
 
 
def main():
  urls = []
  for page in range(1, 100):
    urls.append('http://www.baidu.com?page=%s' % page)
  s = MySpider(urls)
  s.run()
 
 
if __name__ == '__main__':
  main()

可以继承这个类,塞一些url进去,然后重写handle_page处理得到的页面。

异步+多进程爬虫
还可以再变态点,加个进程池,使用了multiprocessing模块。效率飕飕的,

#!/usr/bin/env python
# -*- coding:utf-8 -*-
 
import time
from multiprocessing import Pool
from datetime import timedelta
from tornado import httpclient, gen, ioloop, queues
 
 
class AsySpider(object):
  """A simple class of asynchronous spider."""
  def __init__(self, urls, concurrency):
    urls.reverse()
    self.urls = urls
    self.concurrency = concurrency
    self._q = queues.Queue()
    self._fetching = set()
    self._fetched = set()
 
  def handle_page(self, url, html):
    filename = url.rsplit('/', 1)[1]
    with open(filename, 'w+') as f:
      f.write(html)
 
  @gen.coroutine
  def get_page(self, url):
    try:
      response = yield httpclient.AsyncHTTPClient().fetch(url)
      print('######fetched %s' % url)
    except Exception as e:
      print('Exception: %s %s' % (e, url))
      raise gen.Return('')
    raise gen.Return(response.body)
 
  @gen.coroutine
  def _run(self):
 
    @gen.coroutine
    def fetch_url():
      current_url = yield self._q.get()
      try:
        if current_url in self._fetching:
          return
 
        print('fetching****** %s' % current_url)
        self._fetching.add(current_url)
        html = yield self.get_page(current_url)
        self._fetched.add(current_url)
 
        self.handle_page(current_url, html)
 
        for i in range(self.concurrency):
          if self.urls:
            yield self._q.put(self.urls.pop())
 
      finally:
        self._q.task_done()
 
    @gen.coroutine
    def worker():
      while True:
        yield fetch_url()
 
    self._q.put(self.urls.pop())
 
    # Start workers, then wait for the work queue to be empty.
    for _ in range(self.concurrency):
      worker()
    yield self._q.join(timeout=timedelta(seconds=300000))
    assert self._fetching == self._fetched
 
  def run(self):
    io_loop = ioloop.IOLoop.current()
    io_loop.run_sync(self._run)
 
 
def run_spider(beg, end):
  urls = []
  for page in range(beg, end):
    urls.append('http://127.0.0.1/%s.htm' % page)
  s = AsySpider(urls, 10)
  s.run()
 
 
def main():
  _st = time.time()
  p = Pool()
  all_num = 73000
  num = 4  # number of cpu cores
  per_num, left = divmod(all_num, num)
  s = range(0, all_num, per_num)
  res = []
  for i in range(len(s)-1):
    res.append((s[i], s[i+1]))
  res.append((s[len(s)-1], all_num))
  print res
 
  for i in res:
    p.apply_async(run_spider, args=(i[0], i[1],))
  p.close()
  p.join()
 
  print time.time()-_st
 
 
if __name__ == '__main__':
  main()

多线程爬虫
线程池实现.

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import Queue
import sys
import requests
import os
import threading
import time
 
class Worker(threading.Thread):  # 处理工作请求
  def __init__(self, workQueue, resultQueue, **kwds):
    threading.Thread.__init__(self, **kwds)
    self.setDaemon(True)
    self.workQueue = workQueue
    self.resultQueue = resultQueue
 
 
  def run(self):
    while 1:
      try:
        callable, args, kwds = self.workQueue.get(False)  # get task
        res = callable(*args, **kwds)
        self.resultQueue.put(res)  # put result
      except Queue.Empty:
        break
 
class WorkManager:  # 线程池管理,创建
  def __init__(self, num_of_workers=10):
    self.workQueue = Queue.Queue()  # 请求队列
    self.resultQueue = Queue.Queue()  # 输出结果的队列
    self.workers = []
    self._recruitThreads(num_of_workers)
 
  def _recruitThreads(self, num_of_workers):
    for i in range(num_of_workers):
      worker = Worker(self.workQueue, self.resultQueue)  # 创建工作线程
      self.workers.append(worker)  # 加入到线程队列
 
 
  def start(self):
    for w in self.workers:
      w.start()
 
  def wait_for_complete(self):
    while len(self.workers):
      worker = self.workers.pop()  # 从池中取出一个线程处理请求
      worker.join()
      if worker.isAlive() and not self.workQueue.empty():
        self.workers.append(worker)  # 重新加入线程池中
    print 'All jobs were complete.'
 
 
  def add_job(self, callable, *args, **kwds):
    self.workQueue.put((callable, args, kwds))  # 向工作队列中加入请求
 
  def get_result(self, *args, **kwds):
    return self.resultQueue.get(*args, **kwds)
 
 
def download_file(url):
  #print 'beg download', url
  requests.get(url).text
 
 
def main():
  try:
    num_of_threads = int(sys.argv[1])
  except:
    num_of_threads = 10
  _st = time.time()
  wm = WorkManager(num_of_threads)
  print num_of_threads
  urls = ['http://www.baidu.com'] * 1000
  for i in urls:
    wm.add_job(download_file, i)
  wm.start()
  wm.wait_for_complete()
  print time.time() - _st
 
if __name__ == '__main__':
  main()

这三种随便一种都有很高的效率,但是这么跑会给网站服务器不小的压力,尤其是小站点,还是有点节操为好。
非常感谢你的阅读
大学的时候选择了自学python,工作了发现吃了计算机基础不好的亏,学历不行这是没办法的事,只能后天弥补,于是在编码之外开启了自己的逆袭之路,不断的学习python核心知识,深入的研习计算机基础知识,整理好了,我放在我们的微信公众号《程序员学府》,如果你也不甘平庸,那就与我一起在编码之外,不断成长吧!

其实这里不仅有技术,更有那些技术之外的东西,比如,如何做一个精致的程序员,而不是“屌丝”,程序员本身就是高贵的一种存在啊,难道不是吗?[点击加入]想做你自己想成为高尚人,加油!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

python练习题之 的相关文章

  • Python 3.7 Windows 不支持 dbm.gnu 吗?

    做的时候 import dbm gnu 在适用于 Windows 的标准 Python 3 7 6 64 上 我得到 文件 C Python37 lib dbm gnu py 第 3 行 位于从 gdbm 导入 ModuleNotFound
  • Python 字符串到 SQL IN 参数的列表

    我在 python 中有这个查询 ssim group S1200 S1300 query select WIPMessageCnt from waferdata where recipename in s and equipment an
  • Tkinter - 打开一个窗口并关闭另一个窗口

    我想要一个登录屏幕 当登录成功时 屏幕将关闭并创建一个新屏幕 问题是 当我执行以下代码时 两个屏幕同时打开 如果您有任何改进代码的建议 请提出 from Tkinter import import mysql connector impor
  • Opencv未找到所有轮廓

    我试图找到该图像的轮廓 但是该方法查找轮廓只返回1轮廓 轮廓突出显示image 2 我正在努力寻找all外部轮廓就像这些圆圈 里面有数字 我究竟做错了什么 我可以做什么来实现它 image 1 image 2 以下是我的代码的相关部分 th
  • 嵌套列表递归python的序列

    给定一些数字 n 我想生成一个大小为 n 的列表 其中以下示例显示列表中的第 n 个元素应该如何 对于 n 0 返回 对于 n 1 返回 对于 n 2 返回 对于 n 3 返回 基本上 它采用先前的列表并将它们附加到新列表中 我尝试过以下方
  • 在 Tensorflow 2.0 中的 tf.function input_signature 中使用字典

    我正在使用 Tensorflow 2 0 并面临以下情况 tf function def my fn items do stuff return 如果 items 是张量的字典 例如 item1 tf zeros 1 1 item2 tf
  • 所有模型的 SQLAlchemy 事件 after_create

    我正在开发一个项目 需要对创建的每个模型进行通用定制 迄今为止我完成大部分工作的方式是通过模型继承 这是我的代码块 可以为您提供更好的想法 app core dba mixins class AuditExtension MapperExt
  • 将 Django 模型映射到外部 API

    上下文 我有一个外部 API 提供数据并允许发布新数据或修补现有数据 API 响应示例 response requests get http api band 4 print response json id 4 name The Beat
  • 如何获取 ndarray 的 x 和 y 维度 - Numpy / Python

    我想知道是否可以分别获取 ndarray 的 x 和 y 维度 我知道我可以使用ndarray shape获取表示维度的元组 但如何在 x 和 y 信息中分离它 先感谢您 您可以使用元组拆包 y x a shape
  • 快速分类(分箱)

    我有大量条目 每个条目都是浮点数 这些数据x可以通过迭代器访问 我需要使用像这样的选择对所有条目进行分类10
  • 在散景中隐藏轴

    如何在散景图中隐藏 x 轴和 y 轴 我已经根据此进行了检查和尝试 p1 figure visible None p1 select type Axis visible 0 xaxis Axis plot p1 visible 0 和喜欢h
  • 您可以使用 Openpyxl 将全名拆分为名字和姓氏吗?

    我有一个 Excel 文件 我一直在尝试使用 openpyxl 将列 全名 拆分为两个单独的名字和姓氏列 例如 我有 from openpyxl import Workbook load workbook wb load workboo p
  • 获取小部件的背景颜色 - 真的

    我无法获取小部件的实际背景颜色 在我的特殊情况下 我在使用 QTabWidget 中的小部件时遇到问题 这是在Windows7上 因此 经典的小部件有一些灰色背景 而选项卡内的小部件通常用白色背景绘制 I tried def bgcolor
  • python seaborn:按色调显示 alpha

    在seaborn中 色调为组设置不同的颜色 我可以设置吗alpha取决于组中的JointGrid 或者甚至在单个数据点上 sns set theme jg sns JointGrid data df sns x x y y hue hue
  • 使用循环计算 Python 字典中元素的有效方法

    我有一个值列表 我希望在循环期间计算每个类的元素数量 即 1 2 3 4 5 mylist 1 1 1 1 1 1 2 3 2 2 2 2 3 3 4 5 5 5 5 mydict dict for index in mylist mydi
  • 如何在 Python 中从平面列表构建嵌套列表? [关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 我有一个简单的列表 例如 flat 1 1 1 1 1 1 1 2 2 2 1 2 2 3 我需要转换为嵌套列表 其中每个级别 破折号后跟数
  • 从纪元到相对日期的秒数

    我正在处理自纪元以来的日期 并且已经得到了 例如 date 6928727 56235 我想将其转换为另一种相对格式 以便我能够将其转换为与纪元相关的格式 使用 time gmtime date 它返回 year 1970 mon 3 da
  • 在 Python 中使用列表理解来执行类似于 zip() 的操作?

    我是一名 Python 新手 我想做的事情之一就是围绕列表理解进行思考 我可以看到这是一个非常强大的功能 值得学习 cities Chicago Detroit Atlanta airports ORD DTW ATL print zip
  • 如何在 Windows 上的 Python 2.7 上安装 Tensorflow?

    我尝试通过 pip 安装 TensorFlow pip install tensorflow 但是得到这个错误 找不到满足tensorflow要求的版本 来自版本 这个问题有解决办法吗 我还是想通过pip安装 如果您只因为 Keras 而需
  • Pandas DataFrame 中多列的映射方法

    我有一个 Pandas 数据框 其中的值是列表 import pandas as pd DF pd DataFrame X 1 5 1 2 Y 1 2 5 1 3 5 DF X Y 0 1 5 1 2 5 1 1 2 1 3 5 我想检查

随机推荐

  • 服务器中激活刚安装好的anaconda

    在服务器安装anaconda的过程中 最后一步是初始化 选择yes 然后在命令行输入conda info envs 发现conda not found 是因为conda环境未激活 此时直接输入source bashrc 即可成功激活环境 一
  • element-ui表格+分页器数据分页展示

  • SpringBoot从0到实战8:简单使用Swagger生成接口开发文档

    初识Swagger Swagger 是一个规范和完整的框架 广泛用于生成 描述 调用和可视化 RESTful 风格的 Web服务 总体目标是使客户端和文件系统作为服务器以相同速度更新 文件的方法 参数和模型紧密集成到服务器端的代码 允许AP
  • 测量学4_距离测量

    测量学 lesson 4 距离测量是确定地面点位时的基本测量工作之一 距离测量的方法有钢尺量距 视距测量和电磁波测距等 距离测量 钢尺量距 利用卷钢尺直接沿地面丈量距离 受地形影响较大 仅用于平坦地区的近距离测量 地面上两点之间距离较远时
  • Windbg+VMware双机调试/1394/串口/常见问题处理+下载符号文件离线包

    目录 1 调试工具VisualDDK 2 Vista以下的版本系统设置 3 Vista以上的版本系统设置 4 1394火线调试 5 使用串口线双机调试 6 调试过程中出现的问题及解决方案 7 快速下载符号文件离线包 1 调试工具Visual
  • SQL IF语句实际应用--返回输出

    SQL IF语句输出 SQL IF语句我们有时会用到用到这个通常是对某个属性进行判断操作 类似我们编程那种三元表达式一样 但有时候业务上不会让你去简简单单去判断操作 还会让你把结果返回过去 通过接口展示出去在前端 你写一个带有if的查询结果
  • B tree、B- tree、B+ tree、B*tree

    目录 1 B tree B tree 2 B tree B 树 2 1为什么需要B 树 B 树比B树更好呢 2 1数据库索引采用B 树的主要原因 3 B tree B 树 4 小结 1 B tree B tree B树 B tree 是一种
  • Pytorch-GPU配置

    自己电脑Window 10下pytorch GPU的配置 CUDA 10 1 cuDNN v7 6 4 pytorch 1 4 参考 1 Windows10安装cuda cudnn pytorch jupyter fastai 2 wind
  • C#系列-基础

  • 理解广度优先遍历(持续更新)

    文章的目录如下方便翻阅 广度优先搜索 BFS 如何实现广度优先搜索 简单的描述广度优先搜索的大致过程 下面结合例题理解广度优先搜索 广度优先遍历在树中的应用 广度优先遍历在数组中的应用 last 广度优先搜索 BFS 如何理解广度优先搜索
  • 传统图像处理算法总结

    1 图像滤波 目的 保证图像细节特征的条件下抑制图像噪声 1 1 线性滤波 1 11 方框滤波 原图像与内核的系数加权求和 方框滤波的核 normalize true 时 方框滤波就变成了均值滤波 也就是说 均值滤波是方框滤波归一化 nor
  • 【Java】【排序算法】【冒泡排序】(代码示例)

    文章目录 冒泡排序概念 冒泡排序的实现步骤如下 以下是冒泡排序的Java实现代码 总结 冒泡排序概念 冒泡排序 Bubble Sort 是一种简单的排序算法 它重复地遍历待排序的列表 每次比较相邻的两个元素 并交换它们的位置 直到整个列表排
  • Docker 如何保存对容器的修改

    1 docker ps 查看正在运行的容器 2 docker exec it d81abcfd2e3b bash 进入正在运行的容器内 3 进入容器后 就可以修改镜像了 比如修改镜像中已经部署的代码或者安装新的软件或包等 修改完成之后 ex
  • 【Hibernate】Hibernate.cfg.xml配置文件详解

    Hibernate配置文件主要用于配置数据库连接和Hibernate运行时所需的各种属性 这个配置文件应该位于应用程序或Web程序的类文件夹 classes中 Hibernate配置文件支持两种形式 一种是xml格式的配置文件 另一种是Ja
  • linux下安装Tkinter及python升级

    1 首先安装Tkinter模块 yum y install tkinter 在python下运行import Tkinter发现正确 但是使用的是默认版的python2 4 3 5 再次运行import Tkinter后报错 Type he
  • java中的输入输出

    java与C语言和C 不同 java的输入输出比较复杂 下面我将来介绍一下java的输入输出 输出 java中有三种方法进行输出 class Main public static void main String args System o
  • iview table使用自定义按钮取消某个选中的单项

    实现效果 选中选项后然后弹出选中的选项框 点击删除按钮删除某一个选项 table中的选中状态也随之变化 ivew坑 给data设置 checked其实对table上的checkBox并没有作用 用js给data数据设置该属性并没有作用 具体
  • 标准的遗传算法求函数最大值

    最近看了下遗传算法 刚看了一点 就觉得手痒 非要把程序编制出来看看效果 我现在总认为那些理论再高深 无法用计算机实现就是空话 呵呵 下面是我调试了好久的代码 无赖没有学过数据结构 算法 程序写的很差 单效果还是出来了 高兴 和大家共同分享下
  • ipmitool工具的安装遇到的问题

    1 从https gitee com mirrors ipmitool git下载ipmitool源码 https gitee com mirrors ipmitool git 因为官网的下载速度比较慢 推荐使用gitee下载 2 进行编译
  • python练习题之

    本文来源于公众号 csdn2299 喜欢可以关注公众号 程序员学府 安装Tornado 省事点可以直接用grequests库 下面用的是tornado的异步client 异步用到了tornado 根据官方文档的例子修改得到一个简单的异步爬虫