使用 pycharm 编辑 pyspider 脚本

0. 前言

最近看文章觉得有必要换一下行文风格,现在趁除草试一下。

经常使用 pyspider 抓一些小网站,看久了自带的网页编辑器实在不友好,还是用本地编辑器会来得更顺手一点。于是开始寻找用 pycharm 当编辑器的方法。

1. pyspider 项目挂载到本地

本地用的是 Windows 系统,虽然资源管理器原生支持添加 WebDAV 文件夹,但是体验很糟糕,这里使用一个更好用的第三方客户端 RaiDrive 来挂载 WebDAV. 在 RaiDrive 中挂载 WebDAV 非常方便,点击「添加」按钮,服务类型选择 NAS 标签页里的 WebDAV,然后输入 pyspider webui 的地址、路径、用户名、密码就可以完成添加,路径对 pyspider 而言是固定的/dav

RaiDrive 挂载 WebDAV

2. pycharm 打开项目

目前为止, pycharm 作为最好用的 python IDE 并不原生支持 WebDAV,所以才有了上面那一步。现在用 pycharm 直接打开上面挂载好的文件夹,立马会感受到熟悉的味道,不过还没完,直接这样操作脚本会带来两个问题。一是脚本无法保存,二是项目文件本身无法保存,都是由于无法直接在挂载到本地的这个文件夹里创建文件造成的。修改文件夹里已有的文件是可以的。

那么有没有可以不新建文件而可以保存脚本和项目文件的方法呢,沿着这个思路去谷歌最终找到了答案。

  • 对保存脚本来说,需要在 pycharm 设置里关闭默认开启的 safe write 选项,关于 safe write 这里摘引一段 pycharm 文档的描述:

Use “safe write” (save changes to a temporary file first)

If this checkbox is selected, a changed file is first saved in a temporary file. If the save operation succeeds, the file being saved is replaced with the saved file. (Technically, the original file is deleted and the temporary file is renamed.)

Also, the ownership of such file changes.

If this checkbox is not selected, the ownership of a file does not change, but all the advantages of safe write will be lost.

https://www.jetbrains.com/help/pycharm/system-settings.html#Synchronization

看来 safe write 还是有用处的,作为默认勾选可以最大限度防止意外丢数据,合情合理。但是在这里用 WebDAV 就不得不关闭了,挂载到本地的文件夹不能创建这个临时文件,其实 safe write 的优势在 WebDAV 这里也发挥不出来,毕竟更新文件操作对 pyspider 来说是更新数据库会比文件操作更可靠,只是要注意 safe write 是 pycharm 里的全局设置,这里改了对其他非 pyspider 项目一样生效。

权衡结束之后还是要关闭,禁用 safe write 步骤如下:Settings > Appearance and Behavior > System Settings > Synchronization

禁用 safe write
  • 对保存项目文件来说,项目的 meta 信息默认保存在项目所在目录下,通俗讲就是打开的项目文件夹下会生成一个 .idea 文件夹用来存放这个项目在 pycharm 里的配置等等。由于挂载后的目录不可创建文件,因此需要把 .idea 放在其他位置。

不过 pycharm 并没有提供迁移项目配置信息的选项,因此查到一个 workaround 的方法:在 pycharm 中新建一个空项目(Pure Python),设定好项目路径确定即可,然后依次找到 Settings > Project > Project Structure,移除已有的 content root,点击 Add Content Root,定位到上一步挂载的 WebDAV 目录(RaiDrive 映射的盘符)完成添加。

移除已有的 content root

至此,便可以开始使用 pycharm 编辑 pyspider 脚本了。

Python 时间日期

感觉最近很常用到 Python 的时间与日期相关模块,之前也有碰到就去查,不过最近既然比较频繁还是作个备忘偷个懒。
表示时间的两种方式:

  • 时间戳(timestamp),即相对于 1970.1.1 00:00:00 以秒计算的偏移量,是唯一的
  • 时间元组(struct_time),共计 9 个元素,同一时间戳的时间元组会因时区不同而不同

datetime 模块常用方法

主要用到这两个类:

  • datetime.datetime: 年月日构成的日期加上时分秒微秒构成了日期与时间
  • datetime.timedelta: 表示时间间隔对象,可以由两个时间点对象相减得到
    (比如 datetime 对象),访问该对象相应属性可以得到间隔的天数、分钟
    数等等

datetime.datetime 类

datetime.datetime.strptime(),从一个日期时间字符串生成 datetime.datetime 对象,比如

In [1]: import datetime
In [2]: d_str = "2016-01-01 12:34:56"
In [3]: datetime.datetime.strptime(d_str, '%Y-%m-%d %H:%M:%S')
Out[3]: datetime.datetime(2016, 1, 1, 12, 34, 56)

datetime.datetime.strftime(), 跟上一个类方法功能相反,是从 datetime.datetime 对象生成日期时间字符串
datetime.datetime.fromtimestamp(),从一个时间戳生成 datetime.datetime 对象,


# time.time() 用于得到当前时间的时间戳

In [4]: import time
In [5]: datetime.datetime.fromtimestamp(time.time())
Out[5]: datetime.datetime(2016, 2, 21, 10, 50, 37, 481266)
# 此时跟 datetime.datetime.now()等效
In [6]: datetime.datetime.now()
Out[6]: datetime.datetime(2016, 2, 21, 10, 53, 2, 687602)

datetime.timedelta 类

主要用于得到间隔时间的相关值

from datetime import datetime
publish_time = "2016-01-01 12:34:56"
delta = datetime.now() - datetime.strptime(publish_time, '%Y-%m-%d %H:%M:%S')
delta_day = delta.days