用Python制作检测Linux运行信息的工具的教程_python

在这篇文章里,我们将会探索如何使用Python语言作为一个工具来检测Linux系统各种运行信息。让我们一起来学习吧。

哪种Python?

当我提到Python时,我一般是指CPython 2(准确来说是2.7)。当同样的代码不能在CPython3(3.3)运行时,我们明确地把它指出并给出替代的代码,解释它们之间的不同点。请确保你已经安装了CPython,在终端输入python或者python3你会看到Python提示符出现在你的终端里。

请注意,所有的脚本程序都会以#!/usr/bin/env python作为第一行,意味着我们要Python解析器去运行这些脚本。因此,如果你使用 chmod +x your-script.py 命令给你的脚本添加可执行的权限,你可以使用./your-script.py命令直接运行你的脚本(你将会在这篇文章里看到这种操作)

探索platform模块

在标准库中的platform模块有大量的函数让我们去检查各种系统信息。我们一起来打开Python解释器(译者:直接在命令行输入python即可打开)并探索其中的一部分函数。我们先从platform.uname()函数开始:
 

>>> import platform
>>> platform.uname()
('Linux', 'fedora.echorand', '3.7.4-204.fc18.x86_64', '#1 SMP Wed Jan 23 16:44:29 UTC 2013', 'x86_64')

如果你知道Linux上的uname命令,你会意识到这个函数就是uname命令的一个接口。在Python 2,这个函数会返回一个由系统类型(或者内核类型),主机名,版本号,发行版号,主机硬件架构和处理器类型组成的元组。你可以使用索引来获取单个属性,像这样:
 

>>> platform.uname()[0]
'Linux'

在Python 3,这个函数会返回一个默认命名的元组:
 

>>> platform.uname()

uname_result(system='Linux', node='fedora.echorand',
release='3.7.4-204.fc18.x86_64', version='#1 SMP Wed Jan 23 16:44:29
UTC 2013', machine='x86_64', processor='x86_64')

因为返回值是个默认命名的元组,所以我们可以轻易地通过变量名来获取单个属性而不用去记住各个属性的下标,像这样:
 

>>> platform.uname().system
'Linux'

platfrom模块还提供了一些直接的接口来获取上面的属性值,像这些:
 

>>> platform.system()
'Linux'

>>> platform.release()
'3.7.4-204.fc18.x86_64'

函数linx_distribution()返回你正在使用的Linux发行版的详细信息。举个例子,在Fedora 18系统中,这条命令会返回下面的信息:
 

>>> platform.linux_distribution()
('Fedora', '18', 'Spherical Cow')

返回值是一个由发行版本名,版本号,代号组成的元组。你可以通过_supported_dists属性来打印你所用的Python版本支持哪些发行版本:
 

>>> platform._supported_dists
('SuSE', 'debian', 'fedora', 'redhat', 'centos', 'mandrake',
'mandriva', 'rocks', 'slackware', 'yellowdog', 'gentoo',
'UnitedLinux', 'turbolinux')

如果你的Linux发行版本不是上面那些的其中一个(或者是其中一个的衍生版),那么你调用上面的函数时不会看到任何有用的信息。

最后一个我们要探索的platfrom函数是architecture()函数。当你不添加任何的参数来调用这个函数时,这个函数会返回一个由位架构和Python可执行文件格式组成的元组。比如:
 

>>> platform.architecture()
('64bit', 'ELF')

在32位的Linux系统中,你会看到:
 

>>> platform.architecture()
('32bit', 'ELF')

如果你指定其他任意的系统可执行程序作为参数,你会得到类似的结果:
 

>>> platform.architecture(executable='/usr/bin/ls')
('64bit', 'ELF')

我们鼓励你去探索platfrom模块中的其他函数,让你找到你当前使用的Python的版本。如果你非常想知道这个模块是怎样获取这些信息的,你可以去看Python源代码目录下的Lib/platfrom.py文件。

os和sys模块同样是一个获取统属性的有用模块就像本地BYTEORDER一样。下一步,我们将会不使用Python你标准库模块来探索一些获取Linux系统信息的通用方法,这次我们通过proc和sys文件系统来实现。要注意的是,通过这些文件系统获取的信息在不同的硬件架构里会有所不同。因此,在阅读这篇文章和写脚本从这些文件里获取系统信息时要它记住。

CPU信息

/proc/cpuinfo这个文件包含了你系统的处理单元信息。比如,这里有一个与在命令行输入cat /proc/cpuinfo 具备同样功能的Python脚本
 

#! /usr/bin/env python
""" print out the /proc/cpuinfo
  file
"""

from __future__ import print_function

with open('/proc/cpuinfo') as f:
  for line in f:
    print(line.rstrip('n'))

当你用Python 2或者Python 3运行这个脚本时,你会看到/proc/cpuinfo文件的所有内容都在你的屏幕上显示出来。(在上面这个脚本,rstrip()方法把每一行的换行符去掉)

下个代码清单使用了startwith()这个字符串方法来显示你电脑的处理单元型号
 

#! /usr/bin/env python

""" Print the model of your
  processing units

"""

from __future__ import print_function

with open('/proc/cpuinfo') as f:
  for line in f:
    # Ignore the blank line separating the information between
    # details about two processing units
    if line.strip():
      if line.rstrip('n').startswith('model name'):
        model_name = line.rstrip('n').split(':')[1]
        print(model_name)

当你运行这个脚本,你会看到你机器的所有处理单元的型号。比如,下面是我在我计算机里看到的:
 

Intel(R) Core(TM) i7-3520M CPU @ 2.90GHz
Intel(R) Core(TM) i7-3520M CPU @ 2.90GHz
Intel(R) Core(TM) i7-3520M CPU @ 2.90GHz
Intel(R) Core(TM) i7-3520M CPU @ 2.90GHz

到目前为止我们已经有好几种方法用来获取我们的计算机系统构架了。从技术的角度准确地说,所有的这些方法实际上是呈现了你运行的系统内核的架构。因此,如果你计算机实际上是64位的机器,但是运行着32位的内核,那么上面的方法将会显现你的计算机是32位架构的。为了找出计算机的正确架构,你可以查看在/proc/cpuinfo中的属性列表的lm属性。1m属性代表着长模式(Long mode)并且只会在64位架构的计算机上出现。下面的脚本跟你展示是怎样做的:

#! /usr/bin/env python

""" Find the real bit architecture
"""

from __future__ import print_function

with open('/proc/cpuinfo') as f:
  for line in f:
    # Ignore the blank line separating the information between
    # details about two processing units
    if line.strip():
      if line.rstrip('n').startswith('flags')
          or line.rstrip('n').startswith('Features'):
        if 'lm' in line.rstrip('n').split():
          print('64-bit')
        else:
          print('32-bit')

正如目前我们所看到的,我们能够访问/proc/cpuinfo文件并且使用简单的文本处理技术去读取我们在查找的信息。为了友好地提供数据给其他程序使用,最好的方法可能是把从/proc/cpuinfo里获取的内容转换为标准的数据机构,比如转换为字典类型。方法很简单:如果你看了这个文件,你会发现对于每一个处理单元都是以键值对形式存在(在之前的一个例子中,我们打印的处理器机型名时,这里的model name就是一个键。)每个不同处理器单元的信息都会用空行来分开。这使我们能方便地以每个处理单元数据为键来构建字典数据结构。这些键(key)都有一个值(value),每个值又对应着每一个处理单元在/proc/cupinfo文件中的所有信息。下一个代码清单告诉你怎样做:

#!/usr/bin/env/ python

"""
/proc/cpuinfo as a Python dict
"""
from __future__ import print_function
from collections import OrderedDict
import pprint

def cpuinfo():
  ''' Return the information in /proc/cpuinfo
  as a dictionary in the following format:
  cpu_info['proc0']={...}
  cpu_info['proc1']={...}

  '''

  cpuinfo=OrderedDict()
  procinfo=OrderedDict()

  nprocs = 0
  with open('/proc/cpuinfo') as f:
    for line in f:
      if not line.strip():
        # end of one processor
        cpuinfo['proc%s' % nprocs] = procinfo
        nprocs=nprocs+1
        # Reset
        procinfo=OrderedDict()
      else:
        if len(line.split(':')) == 2:
          procinfo[line.split(':')[0].strip()] = line.split(':')[1].strip()
        else:
          procinfo[line.split(':')[0].strip()] = ''

  return cpuinfo

if __name__=='__main__':
  cpuinfo = cpuinfo()
  for processor in cpuinfo.keys():
    print(cpuinfo[processor]['model name'])

这段代码使用了一个OrderedDict(有序的字典)代替常用的字典类型,目的是先对在文件中找到的键值对排序后再保存。因此,先展示第一个处理单元的数据信息其次是第二个,以此类推。如果你调用这个函数,它会返回一个字典类型给你。字典的每一个键都是一个处理单元。然后你可以使用键来筛选要找的信息(就像if __name='__main__'语句块里展示的一样)。当上面的脚本运行时会再次打印出每个处理单元的model name(通过print(cpuinfo[processor]['model name']语句来展示)
 

Intel(R) Core(TM) i7-3520M CPU @ 2.90GHz
Intel(R) Core(TM) i7-3520M CPU @ 2.90GHz
Intel(R) Core(TM) i7-3520M CPU @ 2.90GHz
Intel(R) Core(TM) i7-3520M CPU @ 2.90GHz

内存信息

与/proc/cpuinfo类似,/proc/meminfo文件包含了你计算机的主存信息。下一个脚本产生一个包含这个文件内容的字典并把它输出。

#!/usr/bin/env python

from __future__ import print_function
from collections import OrderedDict

def meminfo():
  ''' Return the information in /proc/meminfo
  as a dictionary '''
  meminfo=OrderedDict()

  with open('/proc/meminfo') as f:
    for line in f:
      meminfo[line.split(':')[0]] = line.split(':')[1].strip()
  return meminfo

if __name__=='__main__':
  #print(meminfo())

  meminfo = meminfo()
  print('Total memory: {0}'.format(meminfo['MemTotal']))
  print('Free memory: {0}'.format(meminfo['MemFree']))

和前面看到的一样,你同样可以使用特定的键去获取任意你想要的信息(在if __name__=='__main__'语句快里有展示)。当你运行这个脚本,你可以看到类似下面的输出:
 

Total memory: 7897012 kB
Free memory: 249508 kB

网络统计

下面,我们会探索我们计算机系统的网络设备。我们将会检索系统的网络接口和系统开启后发送和接收到的字节数据。这些信息可以在/proc/net/dev文件中获取。如果你审查过这个文件的内容,你会发现前两行包含了头信息-i.e.文件中的第一列是网络接口名,第二和第三列展示了接收和传输的字节信息(比如,总发送字节,数据包数量,错误统计,等等)。我们感兴趣的是如何获取不同的网络设备的总数据发送和接受量。下一个代码清单展示了我们如何从/proc/net/dev提出这些信息:

#!/usr/bin/env python
from __future__ import print_function
from collections import namedtuple

def netdevs():
  ''' RX and TX bytes for each of the network devices '''

  with open('/proc/net/dev') as f:
    net_dump = f.readlines()

  device_data={}
  data = namedtuple('data',['rx','tx'])
  for line in net_dump[2:]:
    line = line.split(':')
    if line[0].strip() != 'lo':
      device_data[line[0].strip()] = data(float(line[1].split()[0])/(1024.0*1024.0),
                        float(line[1].split()[8])/(1024.0*1024.0))

  return device_data

if __name__=='__main__':

  netdevs = netdevs()
  for dev in netdevs.keys():
    print('{0}: {1} MiB {2} MiB'.format(dev, netdevs[dev].rx, netdevs[dev].tx))

当你运行上面的脚本时,会以MiB为单位输出从你最近的一次重启后你的网络设备接受和发送的数据。正如下面展示的:
 

em1: 0.0 MiB 0.0 MiB
wlan0: 2651.40951061 MiB 183.173976898 MiB

你可能会利用一个持久性存储机制和这个脚本来写一个你自己的数据使用监控程序。

进程

/proc目录同样包含了每个运行进程的目录。这些目录的名称以相应的进程ID来命名。因此,如果你遍历/proc目录下的所有以数字命名的目录,你会得到一个所有当前运行进程的ID列表。下面的代码清单里的process_list()函数返回一个包含所有当前运行进程ID的列表。这个列表的长度等于系统运行进程的总数,正如你运行这个脚本看到的一样:
 

#!/usr/bin/env python
"""
 List of all process IDs currently active
"""

from __future__ import print_function
import os
def process_list():

  pids = []
  for subdir in os.listdir('/proc'):
    if subdir.isdigit():
      pids.append(subdir)

  return pids

if __name__=='__main__':

  pids = process_list()
  print('Total number of running processes:: {0}'.format(len(pids)))

运行上面的脚本时,输出结果和下面输出类似:

每个进程目录都包含了大量的其他文件和目录,这些目录包含了各种关于进程调用命令,使用的共享库和其他的信息。

块设备

接下来的脚本通过访问sysfs虚拟文件系统列出了所有的块设备信息。你能够在/sys/block目录下找到系统上的所有块设备。因此,你的系统上会有/sys/block/sda,/sys/block/sdb和其他的类似目录。为了找到这些设备,我们可以遍历/sys/block目录然后通过简单的正则表达式去匹配我们要查找的内容。

#!/usr/bin/env python

"""
Read block device data from sysfs
"""

from __future__ import print_function
import glob
import re
import os

# Add any other device pattern to read from
dev_pattern = ['sd.*','mmcblk*']

def size(device):
  nr_sectors = open(device+'/size').read().rstrip('n')
  sect_size = open(device+'/queue/hw_sector_size').read().rstrip('n')

  # The sect_size is in bytes, so we convert it to GiB and then send it back
  return (float(nr_sectors)*float(sect_size))/(1024.0*1024.0*1024.0)

def detect_devs():
  for device in glob.glob('/sys/block/*'):
    for pattern in dev_pattern:
      if re.compile(pattern).match(os.path.basename(device)):
        print('Device:: {0}, Size:: {1} GiB'.format(device, size(device)))

if __name__=='__main__':
  detect_devs()

如果你运行了这个脚本,你将会看到与下面类似的输出结果:
 

Device:: /sys/block/sda, Size:: 465.761741638 GiB
Device:: /sys/block/mmcblk0, Size:: 3.70703125 GiB

当我运行这个脚本时,我额外插入了一张SD卡。所以你会看到这个脚本检测到了它(上面输出的第二行,译者注)。你同样可以扩展这个脚本去识别其他的块设备(比如虚拟硬盘)。

构建命令行工具

允许用户指定命令行参数去自定义程序的默认行为是所有Linux命令行工具的一个普遍特征。argparse模块能使你程序拥有与内置工具界面类似的界面。下一个代码清单展示了一个获取你系统上所有用户并把它们相应的登陆shell打印出来的程序。

#!/usr/bin/env python

"""
Print all the users and their login shells
"""

from __future__ import print_function
import pwd

# Get the users from /etc/passwd
def getusers():
  users = pwd.getpwall()
  for user in users:
    print('{0}:{1}'.format(user.pw_name, user.pw_shell))

if __name__=='__main__':
  getusers()

当运行上面的脚本时,它会打印出你系统上所有的用户和它们的登陆shell

现在,我们假设你想让脚本使用者能够选择是否想看到系统的其他用户(比如daemon,apache)。我们通过使用argparse模块扩展之前的代码来实现这个功能,就像下面的代码。

#!/usr/bin/env python

"""
Utility to play around with users and passwords on a Linux system
"""

from __future__ import print_function
import pwd
import argparse
import os

def read_login_defs():

  uid_min = None
  uid_max = None

  if os.path.exists('/etc/login.defs'):
    with open('/etc/login.defs') as f:
      login_data = f.readlines()

    for line in login_data:
      if line.startswith('UID_MIN'):
        uid_min = int(line.split()[1].strip())

      if line.startswith('UID_MAX'):
        uid_max = int(line.split()[1].strip())

  return uid_min, uid_max

# Get the users from /etc/passwd
def getusers(no_system=False):

  uid_min, uid_max = read_login_defs()

  if uid_min is None:
    uid_min = 1000
  if uid_max is None:
    uid_max = 60000

  users = pwd.getpwall()
  for user in users:
    if no_system:
      if user.pw_uid >= uid_min and user.pw_uid <= uid_max:
        print('{0}:{1}'.format(user.pw_name, user.pw_shell))
    else:
      print('{0}:{1}'.format(user.pw_name, user.pw_shell))

if __name__=='__main__':

  parser = argparse.ArgumentParser(description='User/Password Utility')

  parser.add_argument('--no-system', action='store_true',dest='no_system',
            default = False, help='Specify to omit system users')

  args = parser.parse_args()
  getusers(args.no_system)

使用–help选项来运行上面的脚本,你会看到一个带有可选项(和作用)的友好帮助信息
 

$ ./getusers.py --help
usage: getusers.py [-h] [--no-system]

User/Password Utility

optional arguments:
 -h, --help  show this help message and exit
 --no-system Specify to omit system users

上面脚本的一个例子调用如下:
 

$ ./getusers.py --no-system
gene:/bin/bash

当你传递一个无效的参数时,脚本会报错:
 

$ ./getusers.py --param
usage: getusers.py [-h] [--no-system]
getusers.py: error: unrecognized arguments: --param

让我们一起来简单地了解下在上面的脚本中我们是如何使用argparse模块的parser=argparse.ArgumentParser(description='User/Password Utility')这行代码使用一个描述脚本作用的可选参数创建了一个新的ArgumentParser对象。

然后,我们在下一行代码:parser.add_argument(‘–no-system', action='store_true', dest='no_system', default = False, help='Specify to omit system users')里使用了add_argument()方法添加一些参数,让脚本能够识别命令行选项。这个方法的第一个参数是脚本使用者在调用脚本时作为参数提供的选项名。下一个参数action=store_true表明了这是一个布尔选项。也就是说这个参数的有无在一定程度上会对程序产生影响。dest参数指定了一个变量来保存选项值并提供给脚本使用。如果用户没有提供选项,通过参数default=False可以设置默认值为False。最后一个参数是脚本展示关于这个选项的帮助信息。最后,使用parse_args()方法处理参数:args=parser.parse_args()。一旦处理完毕,使用args.option_dest可以获取到用户提供的选项值,这里的option_dest就是你设置参数时指定的dest变量。这行代码getusers(args.no_system)使用用户提供的no_system选项值作为参数调用了getusers()。

接下来的脚本展示了你该如何在你的脚本里提供用户一个非布尔值的选项。这个脚本重写了代码清单6,添加了额外的选项让你能够指定检测你感兴趣的网络设备。

#!/usr/bin/env python
from __future__ import print_function
from collections import namedtuple
import argparse

def netdevs(iface=None):
  ''' RX and TX bytes for each of the network devices '''

  with open('/proc/net/dev') as f:
    net_dump = f.readlines()

  device_data={}
  data = namedtuple('data',['rx','tx'])
  for line in net_dump[2:]:
    line = line.split(':')
    if not iface:
      if line[0].strip() != 'lo':
        device_data[line[0].strip()] = data(float(line[1].split()[0])/(1024.0*1024.0),
                          float(line[1].split()[8])/(1024.0*1024.0))
    else:
      if line[0].strip() == iface:
        device_data[line[0].strip()] = data(float(line[1].split()[0])/(1024.0*1024.0),
                          float(line[1].split()[8])/(1024.0*1024.0))
  return device_data

if __name__=='__main__':

  parser = argparse.ArgumentParser(description='Network Interface Usage Monitor')
  parser.add_argument('-i','--interface', dest='iface',
            help='Network interface')

  args = parser.parse_args()

  netdevs = netdevs(iface = args.iface)
  for dev in netdevs.keys():
    print('{0}: {1} MiB {2} MiB'.format(dev, netdevs[dev].rx, netdevs[dev].tx))

当你不提供任何参数运行这个脚本时,它的运行结果实际上和之前的版本一样。但是,你同样可以指定你可能感兴趣的网络设备。举个例子:
 

$ ./net_devs_2.py

em1: 0.0 MiB 0.0 MiB
wlan0: 146.099492073 MiB 12.9737148285 MiB
virbr1: 0.0 MiB 0.0 MiB
virbr1-nic: 0.0 MiB 0.0 MiB

$ ./net_devs_2.py --help
usage: net_devs_2.py [-h] [-i IFACE]

Network Interface Usage Monitor

optional arguments:
 -h, --help      show this help message and exit
 -i IFACE, --interface IFACE
            Network interface

$ ./net_devs_2.py -i wlan0
wlan0: 146.100307465 MiB 12.9777050018 MiB

使你的脚本能在任意地方运行

在这篇文章的帮助下,你可能已经能够给自己写一个或者更多的有用脚本,这些脚本你想每天都使用,就像Linux的其他命令一样。去实现这个愿望最简单的方式就是使这些脚本能够运行(给脚本添加运行权限,译者注)并且给这些命令设置BASH别名(BASH alias)。你同样可以删除.py后缀并且把这个文件放到一个标准位置比如/usr/local/sbin。

其他的有用标准库模块

除了到目前为止我们在这篇文章里看到过的标准库外,这里还有很多其它可能有用的标准库:subprocess,ConfigParser, readline 和 curses。

下一步?

在这个阶段,根据你自己的Python经验和深入探索Linux,你选择以下方式的一种。如果你已经写了大量的shell脚本或者命令管道去深入探索各种Linux,请试一下Python。如果你想以一种更简易的方式去写你自己的脚本工具去执行各种任务,请试一下Python。最后,如果你已经使用其他种类的Python在Linux上编程,祝你使用Python深入探索Linux愉快。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索linux
, python
CPython
linux运行python脚本、linux 运行python、python运行linux命令、linux python开发工具、linux下运行python,以便于您获取更多的相关知识。

时间: 2024-10-21 08:41:45

用Python制作检测Linux运行信息的工具的教程_python的相关文章

搭建Python的Django框架环境并建立和运行第一个App的教程_python

Django是python中目前风靡的Web Framework, 那么什么叫做Framework呢, 框架能够帮助你把程序的整体架构搭建好, 而我们所需要做的工作就是填写逻辑, 而框架能够在合适的时候调用你写的逻辑, 而不需要我们自己去调用逻辑, 让Web开发变的更敏捷. Django是一个高级Python Web框架, 鼓励快速,简洁, 以程序设计的思想进行开发. 通过使用这个框架, 可以减少很多开发麻烦, 使你更专注于编写自己的app, 而不需要重复造轮子. Django免费并且开源.Dj

用Python编写分析Python程序性能的工具的教程_python

虽然并非你编写的每个 Python 程序都要求一个严格的性能分析,但是让人放心的是,当问题发生的时候,Python 生态圈有各种各样的工具可以处理这类问题. 分析程序的性能可以归结为回答四个基本问题:     正运行的多快     速度瓶颈在哪里     内存使用率是多少     内存泄露在哪里 下面,我们将用一些神奇的工具深入到这些问题的答案中去.用 time 粗粒度的计算时间 让我们开始通过使用一个快速和粗暴的方法计算我们的代码:传统的 unix time 工具.   $ time pyth

利用python制作在Linux服务器后台定时运行的任务-邮件提醒

1. 自动任务的功能为:   定时扫描数据库中的记录,然后发邮件 代码如下 scheduleMail.py import pymysql import smtplib from email.mime.text import MIMEText from email.header import Header import time def sendMail(body): sender = 'xxx@163.com' receiver = ['abc@xxx.com', 'def@xxx.com',

使用Python编写类UNIX系统的命令行工具的教程_python

引言 您是否能编写命令行工具?也许您可以,但您能编写出真正好用的命令行工具吗?本文讨论使用 Python 来创建一个强健的命令行工具,并带有内置的帮助菜单.错误处理和选项处理.由于一些奇怪的原因,很多人并不了解 Python? 的标准库具有制作功能极其强大的 *NIX 命令行工具所需的全部工具. 可以这样说,Python 是制作 *NIX 命令行工具的最佳语言,因为它依照"batteries-included"的哲学方式工作,并且强调提供可读性高的代码.但仅作为提醒,当您发现使用 Py

Python中使用platform模块获取系统信息的用法教程_python

操作系统相关 system() : 操作系统类型(见例) version(): 操作系统版本 release(): 操作系统发布号, 例如win 7返回7, 还有如NT, 2.2.0之类. platform(aliased=0, terse=0): 操作系统信息字符串,扥与system()+win32_ver()[:3] win32_ver(release='', version='', csd='', ptype=''): win系统相关信息 linux_distribution(distna

Python的爬虫程序编写框架Scrapy入门学习教程_python

1. Scrapy简介Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中. 其最初是为了页面抓取 (更确切来说, 网络抓取 )所设计的, 也可以应用在获取API所返回的数据(例如 Amazon Associates Web Services ) 或者通用的网络爬虫.Scrapy用途广泛,可以用于数据挖掘.监测和自动化测试 Scrapy 使用了 Twisted异步网络库来处理网络通讯.整体架构大致如下 Scrapy主

在Python的Flask框架中使用模版的入门教程_python

 概述 如果你已经阅读过上一个章节,那么你应该已经完成了充分的准备工作并且创建了一个很简单的具有如下文件结构的Web应用:   microblog     |-flask文件夹     |-<一些虚拟环境的文件>     |-app文件夹     |  |-static文件夹     |  |-templates文件夹     |  |-__init__.py文件     |  |-views.py文件     |-tmp文件夹     |-run.py文件 亲,想要运行这个程序么?那就运行这

使用Python中的线程进行网络编程的入门教程_python

引言 对于 Python 来说,并不缺少并发选项,其标准库中包括了对线程.进程和异步 I/O 的支持.在许多情况下,通过创建诸如异步.线程和子进程之类的高层模块,Python 简化了各种并发方法的使用.除了标准库之外,还有一些第三方的解决方案,例如 Twisted.Stackless 和进程模块.本文重点关注于使用 Python 的线程,并使用了一些实际的示例进行说明.虽然有许多很好的联机资源详细说明了线程 API,但本文尝试提供一些实际的示例,以说明一些常见的线程使用模式. 全局解释器锁 (G

Python中用memcached来减少数据库查询次数的教程_python

本来我一直不知道怎么来更好地优化网页的性能,然后最近做python和php同类网页渲染速度比较时,意外地发现一个很简单很白痴但是 我一直没发现的好方法(不得不BS我自己):直接像某些php应用比如Discuz论坛那样,在生成的网页中打印出"本页面生成时间多少多少秒",然后在 不停地访问网页测试时,很直观地就能发现什么操作会导致瓶颈,怎样来解决瓶颈了. 于是我发现SimpleCD在 生成首页时,意外地竟然需要0.2秒左右,真真不能忍:对比Discuz论坛首页平均生成才0.02秒,而Dis