python selenium 操作记录

python selenium 操作记录

官方文档说的很详细了,可以见 Selenium with Python
这里只是对使用 selenium 登录网站等操作做一些记录和说明,方便下次需要使用时,能很快的从这里产生代码,完成新的需求。

为什么使用 selenium

总是有需要才会用到它的。

登录网站获取 cookies 时,我们可以通过分析登录接口,分析密码加密方式,分析各种参数的传递,然后再回来提交登录需要的参数,这个过程,在一些网站上,处理起来很困难且耗时太多,而我们登陆后,需要的仅仅时 cookies,作为后续操作的 session 维护,所以,有些一次性任务或者为了快速开发,我们可以选择使用 selenium 来模拟登录,无需考虑太多的情况,登录成功后,再导出 cookies 给其他网络库程序使用。并且 selenium 处理验证码非常方便啊,人工输入就行了。

Django models 学习

Django models

开发 web app 后端,必然会涉及到存储,和数据库如何打交道,各有各的不同,我习惯了写 sql 直接操作数据库表,现在用 Django,虽然也可以使用 Classname.objects.raw() 来处理,但是这样的方法肯定不是 Django 特别推崇的首选方法,所以需要看看在 Django 中,是如何把 sql 语句与 python 代码结合起来的,通过一定的抽象,编写 python 代码就可以完成对数据库表的各种操作。在 Django 中,对数据库的操作的抽象是通过 models 类来完成的,下面就是我看了官方文档后,对其中一些我感兴趣的内容的一个笔记。

主键与表名

在 Django 中,model 即对应了一个数据库表结构,同时还提供了数据访问的接口,但是直到 Django 1.7,Django 的这个模型和数据库表的映射关系上还是有些差异和隐晦的地方(以 mysql 为例,其他数据库类似,只是具体语法有些差异)。

  1. 默认使用名为 id 类型为 int 的自增变量作为表的 primary key,且不需要用户显式的在 class 中定义;
  2. 主键仅支持单列,联合主键是不被支持的;
  3. 默认情况下,创建的表名为 app 名字,下划线,类名小写字符的拼接,比如 blog_article。

关于第一个问题,如果不想用默认的 id 作为主键,需要在类定义的时候,显式的指定某个列为 primary_key = True

关于第二个问题,django 实践建议的方法是,修改数据库表,改为让原来的联合主键为联合 unique key,增加名为 id 的字段为主键,然后使用 unique_together = ("driver", "restaurant") 这样的语句来控制唯一性。

当执行 scrapy crawl spidername 时,scrapy 代码的执行方式2

当执行 scrapy crawl spidername 时,scrapy 代码的执行方式二

接上篇的分析,我们已经获得了配置信息,下一步就是 import 对应命令实现的模块进入,在分析具体的导入之前,先来看看名字的实现代码。

本文基于 linux 系统 scrapy 0.24.4

关于 scrapy 的背景知识,这里就不介绍了,google 随便搜索一下,都是非常多的介绍与或赞美或分析的文章,如何使用 scrapy 不是本文关注的重点,本文打算走到 scrapy 的背后,看看 scrapy 的实现是怎样的。

为什么要看看 scrapy 是如何实现的呢?两个原因:

  • 更好的理解 scrapy 的运行机制
  • 学习如何开发一个爬虫框架,从这里来取点经

虽然 scrapy 官方文档的 data flow 图似乎很清楚的说明白了 scrapy 的运行和数据的流向,但是实际上,那个图太抽象了,对于我这个想要深入的理解它的框架结构、实现方法的人而言,太简略了。所以,跟着文档和示例代码,看看 scrapy 运行的背后是如何用代码组织起来的。这就是本文的目的。

当执行 scrapy crawl spidername 时,scrapy 代码的执行方式1

当执行 scrapy crawl spidername 时,scrapy 代码的执行方式一

本文基于 linux 系统 scrapy 0.24.4

关于 scrapy 的背景知识,这里就不介绍了,google 随便搜索一下,都是非常多的介绍与或赞美或分析的文章,如何使用 scrapy 不是本文关注的重点,本文打算走到 scrapy 的背后,看看 scrapy 的实现是怎样的。

为什么要看看 scrapy 是如何实现的呢?两个原因:

  • 更好的理解 scrapy 的运行机制
  • 学习如何开发一个爬虫框架,从这里来取点经

虽然 scrapy 官方文档的 data flow 图似乎很清楚的说明白了 scrapy 的运行和数据的流向,但是实际上,那个图太抽象了,对于我这个想要深入的理解它的框架结构、实现方法的人而言,太简略了。所以,跟着文档和示例代码,看看 scrapy 运行的背后是如何用代码组织起来的。这就是本文的目的。

下划线在 python 中的使用详解

下划线在 python 中的使用详解

原文见 Underscores in Python。是一篇很好的总结文章,我这里做一个二手翻译。

python 中的下划线 _ 在不同的情况下,不同的使用方式,有不同的含义。下面依次来看看。

单独使用的一个下划线 _

典型的使用场景有 3 个:

  • 在解释器中,_ 指向在交互解释器环境中的最近一次执行结果。通过执行 _ 就可以输出最近一次的执行结果。

tornado 中多进程模型代码分析

tornado 中多进程模型代码分析


基于 tornado 4.0.1

程序中使用的原型

在 tornado 的启动过程中,可以使用多进程模型,它有两种多进程的启动模型,分别的代码如下:

1
2
3
4
5
# 简单多进程启动方式
server = TCPServer()
server.bind(8888)
server.start(0) # Forks multiple sub-processes
IOLoop.instance().start()
1
2
3
4
5
6
# 更先进的多进程启动方式
sockets = bind_sockets(8888)
tornado.process.fork_processes(0)
server = TCPServer()
server.add_sockets(sockets)
IOLoop.instance().start()

两种模型中,都调用到了 process.fork_processes() 这个函数。

  • 在简单模型中,通过 server.start(0) 中 调用 fork_processes() 来生成子进程;
  • 在第二种模式中,通过明晰的调用 fork_processes() 来生成子进程;

也就是说,生成子进程的关键代码就是在 fork_processes() 中了(通过名字也可以看出来这个函数是干什么的)。
下面来看看它的代码实现。

在 tornado 中异步无阻塞的执行耗时任务

在 tornado 中异步无阻塞的执行耗时任务

在 linux 上 tornado 是基于 epoll 的事件驱动框架,在网络事件上是无阻塞的。但是因为 tornado 自身是单线程的,所以如果我们在某一个时刻执行了一个耗时的任务,那么就会阻塞在这里,无法响应其他的任务请求,这个和 tornado 的高性能服务器称号不符,所以我们要想办法把耗时的任务转换为不阻塞主线程,让耗时的任务不影响对其他请求的响应。

在 python 3.2 上,增加了一个并行库 concurrent.futures,这个库提供了更简单的异步执行函数的方法。

如果是在 2.7 之类的 python 版本上,可以使用 pip install futures 来安装这个库。

关于这个库的具体使用,这里就不详细展开了,可以去看官方文档,需要注意的是,前两个例子是示例错误的用法,可能会产生死锁。

下面说说如何在 tornado 中结合使用 futures 库,最好的参考莫过于有文档+代码。正好, tornado 中解析 ip 使用的 dns 解析服务是多线程无阻塞的。(netutils.ThreadedResolver)

我们来看看它的实现,看看如何应用到我们的程序中来。

Queue.py 源码阅读

Queue.py 源码阅读

本文基于 python 2.7.3 的 Queue.py 而成。
Queue.py 文件本身行数很少,只有 244 行(以以上版本为例),所以是快速浏览其实现的好文件。

提供的功能

库参考手册可以从 python lib 手册中查看。https://docs.python.org/2/library/queue.html

Queue 支持多生产者、多消费者模式的队列,它在多线程编程模型中非常有用,能够安全的在线程间共享数据,Queue 类实现了所有需要的锁原语(它的支持依赖于 threading 模块)。

一句话总结:Queue 是线程安全的队列。

Queue 模块定义了下面几个类和异常

  • class Queue.Queue(maxsize=0)
  • class Queue.LifoQueue(maxsize=0)
  • class Queue.PriorityQueue(maxsize=0)
  • exception Queue.Empty
  • exception Queue.Full

更详细的内容可以参考官方文档和这里的文档。http://pymotw.com/2/Queue/index.html
这里不做过多的阐述了。

pthread 及 python threading 学习

pthread 及 python threading 学习

(本文内容均基于 linux pthread 和 python threading 而写)

线程基础知识

共享及独享信息

线程相比进程来说,创建速度更快,基本上大于十倍的速度,并且在线程间共享信息比进程要方便和快速的多。
对于线程来说,有很多信息是共享的,这里列出来一部分。

  • 进程 ID 和父进程 ID
  • 进程组 ID 和会话 ID
  • 控制终端
  • 进程凭证信息
  • 打开的文件描述符
  • 信号处置
  • 文件系统相关信息,比如掩码、当前工作目录、根目录等
  • 内部计时器、POSIX 计时器
  • 资源限制
  • CPU 时间消费
  • 资源消费
  • nice value

使用 python 自动化管理 vsftpd ftp 账户

0x01 业务需求

系统能够根据新注册用户的类别,为这个用户创建对应的 ftp 账户、密码,并能在其账户失效后,停止这个账户的 ftp 权限。
这就要求我们的程序能够自动的处理这些事情,所以经过查询文档,使用 pam 认证的方式来管理 vsftpd 账户是非常可行的。

0x02 vsftpd 相关配置及 pam 认证

以下所有内容均基于 centos7 x64 系统

0x0201 安装 vsftpd pam db4

需要安装的软件包含 vsftd, pam, db4

yum -y install vsftpd* pam* db4*

确认以上内容全部安装完毕。