项目管理软件在团队项目开发中是必不可少的,像钉钉自带的星任务,还有禅道等。今天要说的是关于我们项目管理中使用的禅道,因为有时候同事在禅道上面创建了任务,但是被指派的同事并没有实时去刷新禅道,所以被指派的同事经常要过一段时间才真正得知任务,所以想能不能把禅道的一些比如创建任务,解决任务的操作实时同步通知到外部,这样就可以提高团队的办公效率。百度了下禅道确实可以添加机器人,具体操作可以参考该文章确实可行。效果如下

python钉钉机器人程序 钉钉机器人爬虫_爬虫

但是本文章真正要讲的并不是这个,因为这功能是大厂帮我们都集成好的一些功能,对于开发程序员来说能不能自己手动去写一个工具,能够把禅道上面的一些任务数据获取到并转发出去,这才是有挑战性的。

那如何能够获取到禅道上面的数据,这就要用到python爬虫了,我们可以爬虫自己需要的数据这样就可以通过钉钉机器人转发出去了,下面是该功能的具体代码,有兴趣的可以参考研究下

入口 main 文件:

# coding:utf8

from zentao import account
from zentao import my_task

__author__ = "qingsen"

if __name__ == '__main__':
    cfg = account.Account()
    task = my_task.MyTask(cfg)
    task.request()

配置文件读取类:

# coding:utf8

import json
import sys
import os

class Account(object):
    def __init__(self):
        config = os.path.join(sys.path[0], "config.json")
        if not os.path.exists(config):
            print(u"config.json 配置文件不存在")
        else:
            with open(config, "r") as configFile:
                table = json.load(configFile)
                self._host = table["host"]
                self._account = table["account"]
                self._password = table["password"]

    def get_host(self):
        # print("Host: " + self._host)
        return self._host

    def get_account(self):
        print("Account: " + self._account)
        return self._account

    def get_password(self):
        print("Password: " + self._password)
        return self._password

账号配置文件 config.json ,用于禅道登入:

{
 "host": "http://192.168.6.254",
 "account": "禅道账号",
 "password": "禅道密码"
}

禅道基类,用于登入并保留会话信息:

# coding:utf8

import requests
import random
from dingtalkchatbot.chatbot import DingtalkChatbot


class MyZenTao(object):
    def __init__(self, config):
       self._config = config
       self._loginurl = config.get_host() + "/zentao/user-login.html"
       self._session = requests.session()

       # 钉钉机器人
       webhook = 'https://oapi.dingtalk.com/robot/send?access_token=xxxxxxxxxxxx'  # 填写你自己创建的机器人
       self._robot = DingtalkChatbot(webhook)

    def login(self):
        ua_list = [
            'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36',
            'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36',
            'Mozilla/5.0 (X11; CrOS x86_64 10066.0.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'
        ]
        ua = random.choice(ua_list)

        body = {
            "account": self._config.get_account(),
            "password": self._config.get_password(),
            # "referer": "http://127.0.0.1/zentao/my/",
            "keepLogin[]": "on",
        }

        response = self._session.post(self._loginurl, headers = {
            "User-agent": ua,
        }, data = body)

        with response:
            content = response.text
            if "parent.location=" in content:
                print("登录成功!")
                return True
            elif "登录失败,请检查您的用户名或密码是否填写正确" in content:
                print("登录失败,用户名或密码不对")
                return False
            else:
                print("登录失败,其它问题:%s" % content)
                return False

    #钉钉机器人发送禅道任务链接
    def send_link(self, title, text, message_url, pic_url=''):
        self._robot.send_link(title, text, message_url, pic_url)

具体用于爬虫的禅道任务类:

# coding:utf8

from zentao import my_zentao
from lxml import etree

class MyTask(my_zentao.MyZenTao):
    def request(self):
        url = self._config.get_host() + "/zentao/my-task.html"

        success = self.login()
        if success is True:
            response = self._session.get(url)
            with response:
                content = response.text
                html = etree.HTML(content)
                tasks = html.xpath("//table[@class='table has-sort-head table-fixed']//tr")
                for i, task in enumerate(tasks):
                    id = task.xpath("./td[@class='c-id']/text()")  #任务id
                    if len(id) == 0 :
                        continue

                    print('-' * 30)
                    print(id[1].strip())

                    pri = task.xpath("./td[@class='c-pri']//text()")  #优先级
                    print(pri[0].strip())

                    project = task.xpath("./td[@class='c-project']//text()")  #所属项目
                    print(project[0].strip())

                    taskname = task.xpath("./td[@class='c-name']//text()")  # 任务名称
                    print(taskname[len(taskname) - 2].strip())

                    tasklink = task.xpath("./td[@class='c-name']/a/@href")  # 任务链接
                    print(tasklink[0].strip())

                    user = task.xpath("./td[@class='c-user']//text()")  # 创建者
                    print(user[0].strip())

                    status = task.xpath("./td[@class='c-status']//text()")  # 状态
                    print(status[0].strip())

                    if status[0].strip() != "已完成":
                        tip = "%s创建的任务%s 还没完成" % (user[0].strip(), taskname[len(taskname) - 2].strip())
                        self.send_link("禅道消息", tip, self._config.get_host() + tasklink[0].strip())

具体效果如下,禅道网页内容

python钉钉机器人程序 钉钉机器人爬虫_爬虫_02

 登入并爬虫网页数据:

python钉钉机器人程序 钉钉机器人爬虫_禅道_03

钉钉机器人发送消息:

python钉钉机器人程序 钉钉机器人爬虫_禅道_04