RouterOS之python调用API

本文主要讲述官方提供的客户端以及自己写的增删查改工具:

ros_tool.py 功能总汇,展示界面用了python的GUL,模块用的为  tkinter  模块

其他文件为单个功能文件。

链接:https://pan.baidu.com/s/1_NIjG6gCQcnbp9Vwfi9Jyw 密码:98ex

运行方式:python3  ros_tool.py  ip  username  password    (LINUX下,装过ros,改为自己的 ip,用户名,密码 直接运行即可)


ros为python以及其他语言提供了接口,官方给出了一个   TCP客户端的例子:


# !/usr/bin/env python3

# -*- coding:utf-8 -*-

import sys, time, binascii, socket, select

import hashlib

class ApiRos:

    "Routeros api"

    def __init__(self, sk):

        self.sk = sk

        self.currenttag = 0

    def login(self, username, pwd):

        for repl, attrs in self.talk(["/login"]):

            chal = binascii.unhexlify((attrs['=ret']).encode('UTF-8'))

        md = hashlib.md5()

        md.update(b'\x00')

        md.update(pwd.encode('UTF-8'))

        md.update(chal)

        self.talk(["/login", "=name=" + username,

                  "=response=00" + binascii.hexlify(md.digest()).decode('UTF-8')])

    def talk(self, words):

        if self.writeSentence(words) == 0: return

        r = []

        while 1:

            i = self.readSentence();

            if len(i) == 0: continue

            reply = i[0]

            attrs = {}

            for w in i[1:]:

                j = w.find('=', 1)

                if (j == -1):

                    attrs[w] = ''

                else:

                    attrs[w[:j]] = w[j + 1:]

            r.append((reply, attrs))

            if reply == '!done': return r

    def writeSentence(self, words):

        ret = 0

        for w in words:

            self.writeWord(w)

            ret += 1

        self.writeWord('')

        return ret

    def readSentence(self):

        r = []

        while 1:

            w = self.readWord()

            if w == '': return r

            r.append(w)

    def writeWord(self, w):

        print(("<<< " + w))

        self.writeLen(len(w))

        self.writeStr(w)

    def readWord(self):

        ret = self.readStr(self.readLen())

        print((">>> " + ret))

        return ret

    def writeLen(self, l):

        if l < 0x80:

            self.writeStr(chr(l))

        elif l < 0x4000:

            l |= 0x8000

            self.writeStr(chr((l >> 8) & 0xFF))

            self.writeStr(chr(l & 0xFF))

        elif l < 0x200000:

            l |= 0xC00000

            self.writeStr(chr((l >> 16) & 0xFF))

            self.writeStr(chr((l >> 8) & 0xFF))

            self.writeStr(chr(l & 0xFF))

        elif l < 0x10000000:

            l |= 0xE0000000

            self.writeStr(chr((l >> 24) & 0xFF))

            self.writeStr(chr((l >> 16) & 0xFF))

            self.writeStr(chr((l >> 8) & 0xFF))

            self.writeStr(chr(l & 0xFF))

        else:

            self.writeStr(chr(0xF0))

            self.writeStr(chr((l >> 24) & 0xFF))

            self.writeStr(chr((l >> 16) & 0xFF))

            self.writeStr(chr((l >> 8) & 0xFF))

            self.writeStr(chr(l & 0xFF))

    def readLen(self):

        c = ord(self.readStr(1))

        if (c & 0x80) == 0x00:

            pass

        elif (c & 0xC0) == 0x80:

            c &= ~0xC0

            c <<= 8

            c += ord(self.readStr(1))

        elif (c & 0xE0) == 0xC0:

            c &= ~0xE0

            c <<= 8

            c += ord(self.readStr(1))

            c <<= 8

            c += ord(self.readStr(1))

        elif (c & 0xF0) == 0xE0:

            c &= ~0xF0

            c <<= 8

            c += ord(self.readStr(1))

            c <<= 8

            c += ord(self.readStr(1))

            c <<= 8

            c += ord(self.readStr(1))

        elif (c & 0xF8) == 0xF0:

            c = ord(self.readStr(1))

            c <<= 8

            c += ord(self.readStr(1))

            c <<= 8

            c += ord(self.readStr(1))

            c <<= 8

            c += ord(self.readStr(1))

        return c

    def writeStr(self, str):

        n = 0;

        while n < len(str):

            r = self.sk.send(bytes(str[n:], 'UTF-8'))

            if r == 0: raise RuntimeError("connection closed by remote end")

            n += r

    def readStr(self, length):

        ret = ''

        while len(ret) < length:

            s = self.sk.recv(length - len(ret))

            if s == '': raise RuntimeError("connection closed by remote end")

            ret += s.decode('UTF-8', 'replace')

        return ret

def main():

    s = None

    for res in socket.getaddrinfo(sys.argv[1], "8728", socket.AF_UNSPEC, socket.SOCK_STREAM):

        af, socktype, proto, canonname, sa = res

        try:

            s = socket.socket(af, socktype, proto)

        except (socket.error, msg):

            s = None

            continue

        try:

            s.connect(sa)

        except (socket.error, msg):

            s.close()

            s = None

            continue

        break

    if s is None:

        print('could not open socket')

        sys.exit(1)

    apiros = ApiRos(s);

    apiros.login(sys.argv[2], sys.argv[3]);

    #模拟用户自己输入代码进行api控制

    tmpcommand=input('请输入你想查询的命令')

    inputsentence = []

    inputsentence.append(tmpcommand)

    apiros.writeSentence(inputsentence)

    while 1:

        x = apiros.readSentence()

        #print(x)

        if x == ['!done'] or x==['!re', '=status=finished']:

            break

    #导出ros配置到ROS本地ghg1.rsc文件

    # inputsentence = []

    #

    # inputsentence.append('/export')

    # inputsentence.append('=file=ghg1.rsc')

    # apiros.writeSentence(inputsentence)

    # while 1:

    #    x = apiros.readSentence()

    #    #print(x)

    #    if x == ['!done'] or x==['!re', '=status=finished']:

    #        break

    #从ros上传文件到ftp的代码

    # inputsentence = []

    # inputsentence.append('/tool/fetch')

    # inputsentence.append('=address=192.168.0.108')

    # inputsentence.append('=src-path=ghg1.rsc')

    # inputsentence.append('=user=xxxxx')

    # inputsentence.append('=mode=ftp')

    # inputsentence.append('=password=xxxxx')

    # inputsentence.append('=dst-path=123.rsc')

    # inputsentence.append('=upload=yes')

    # apiros.writeSentence(inputsentence)

    # inputsentence = []

    # while 1:

    #    x = apiros.readSentence()

    #    #print(x)

    #    if x == ['!done'] or x==['!re', '=status=finished']:

    #        break

    #删除文件代码

    # inputsentence = []

    # inputsentence.append('/file/remove')

    # inputsentence.append('=numbers=ghg1.rsc')

    # apiros.writeSentence(inputsentence)

    # while 1:

    #    x = apiros.readSentence()

    #    print(x)

    #    if x == ['!done'] or x==['!re', '=status=finished']:

    #        break

            #官方循环代码,等待你输入命令行,可以用来测试代码命令行

            # while 1:

            #    r = select.select([s, sys.stdin], [], [], None)

            #    if s in r[0]:

            #        # something to read in socket, read sentence

            #        x = apiros.readSentence()

            #

            #    if sys.stdin in r[0]:

            #        # read line from input and strip off newline

            #        l = sys.stdin.readline()

            #        print(l)

            #        l = l[:-1]

            #        print(l)

            #

            #

            #        # if empty line, send sentence and start with new

            #        # otherwise append to input sentence

            #        if l == '':

            #            apiros.writeSentence(inputsentence)

            #            inputsentence = []

            #        else:

            #            inputsentence.append(l)

if __name__ == '__main__':

    main()

下面是本人写的一个小工具,可以进行路由的增删改查,代码有很多不足之处,删除功能时 容易出现问题,做了死循环,根据时间控制结束,性能非常低,有兴趣的可以改下:

运行方式:python3  ros_tool.py  ip  username  password    (LINUX下,装过ros,改为自己的 ip,用户名,密码 直接运行即可)

# !/usr/bin/env python

# -*- coding:utf-8 -*-

# Author:yhq

import sys, time, binascii, socket, select

from datetimeimport datetime

# import posix,

import hashlib

from tkinterimport *

# import subprocess

root = Tk()

root.title("ros工具")

root.geometry('1100x800')

class ApiRos:

"Routeros api"

    def __init__(self, sk):

"""

初始化函数

        :paramsk:

"""

        self.sk = sk

self.currenttag =0

    def login(self, username, pwd):

"""

登录函数

        :paramusername:

        :parampwd:

        :return:

"""

        for repl, attrsin self.talk(["/login"]):

chal = binascii.unhexlify((attrs['=ret']).encode('UTF-8'))

# 对 pwd 进行加密

        md = hashlib.md5()

md.update(b'\x00')

md.update(pwd.encode('UTF-8'))

md.update(chal)

self.talk(["/login", "=name=" + username,

                  "=response=00" + binascii.hexlify(md.digest()).decode('UTF-8')])

def talk(self, words):

"""

        :paramwords:

        :return:

"""

        if self.writeSentence(words) ==0:

return

        r = []

while 1:

# python2 中  while 1 比 while True 执行速度快  大概快1/3  python3中两者基本没区别

            i =self.readSentence()

if len(i) ==0:

continue

            reply = i[0]

attrs = {}

for win i[1:]:

j = w.find('=', 1)

if j == -1:

attrs[w] =''

                else:

attrs[w[:j]] = w[j +1:]

r.append((reply, attrs))

if reply =='!done':

return r

def writeSentence(self, words):

"""

        :paramwords:

        :return:

"""

        ret =0

        for win words:

self.writeWord(w)

ret +=1

        self.writeWord('')

return ret

def readSentence(self):

"""

        :return:

"""

        r = []

while 1:

w =self.readWord()

if w =='':

return r

r.append(w)

def writeWord(self, w):

"""

        :paramw:

        :return:

"""

        print(("<<< " + w))

self.writeLen(len(w))

self.writeStr(w)

def readWord(self):

"""

        :return:

"""

        ret =self.readStr(self.readLen())

print((">>> " + ret))

return ret

def writeLen(self, l):

"""

        :paraml:

        :return:

"""

        if l <0x80:

self.writeStr(chr(l))

elif l <0x4000:

l |=0x8000

            self.writeStr(chr((l >>8) &0xFF))

self.writeStr(chr(l &0xFF))

elif l <0x200000:

l |=0xC00000

            self.writeStr(chr((l >>16) &0xFF))

self.writeStr(chr((l >>8) &0xFF))

self.writeStr(chr(l &0xFF))

elif l <0x10000000:

l |=0xE0000000

            self.writeStr(chr((l >>24) &0xFF))

self.writeStr(chr((l >>16) &0xFF))

self.writeStr(chr((l >>8) &0xFF))

self.writeStr(chr(l &0xFF))

else:

self.writeStr(chr(0xF0))

self.writeStr(chr((l >>24) &0xFF))

self.writeStr(chr((l >>16) &0xFF))

self.writeStr(chr((l >>8) &0xFF))

self.writeStr(chr(l &0xFF))

def readLen(self):

"""

        :return:

"""

        c =ord(self.readStr(1))

if (c &0x80) ==0x00:

pass

        elif (c &0xC0) ==0x80:

c &= ~0xC0

            c <<=8

            c +=ord(self.readStr(1))

elif (c &0xE0) ==0xC0:

c &= ~0xE0

            c <<=8

            c +=ord(self.readStr(1))

c <<=8

            c +=ord(self.readStr(1))

elif (c &0xF0) ==0xE0:

c &= ~0xF0

            c <<=8

            c +=ord(self.readStr(1))

c <<=8

            c +=ord(self.readStr(1))

c <<=8

            c +=ord(self.readStr(1))

elif (c &0xF8) ==0xF0:

c =ord(self.readStr(1))

c <<=8

            c +=ord(self.readStr(1))

c <<=8

            c +=ord(self.readStr(1))

c <<=8

            c +=ord(self.readStr(1))

return c

def writeStr(self, str):

"""

        :paramstr:

        :return:

"""

        n =0

        while n

r =self.sk.send(bytes(str[n:], 'UTF-8'))

if r ==0:

raise RuntimeError("connection closed by remote end")

n += r

def readStr(self, length):

"""

        :paramlength:

        :return:

"""

        ret =''

        while len(ret) < length:

s =self.sk.recv(length -len(ret))

if s =='':

raise RuntimeError("connection closed by remote end")

ret += s.decode('UTF-8', 'replace')

return ret

def check_interface():

"""

查看interface

    :return:

"""

    s =None

    for resin socket.getaddrinfo(sys.argv[1], "8728", socket.AF_UNSPEC, socket.SOCK_STREAM):

af, socktype, proto, canonname, sa = res

try:

s = socket.socket(af, socktype, proto)

except socket.error:

s =None

continue

        try:

s.connect(sa)

except socket.error:

s.close()

s =None

continue

break

    if sis None:

print('could not open socket')

sys.exit(1)

global apiros

apiros = ApiRos(s)

apiros.login(sys.argv[2], sys.argv[3])

ls = ['/interface/print', '=.proplist=name']

apiros.writeSentence(ls)

ls1 = []

while 1:

x = apiros.readSentence()

if len(x) >1:

ls1.append(x[1][6:])

if x == ['!done']or x == ['!re', '=status=finished']:

break

    # print('可用interface名字:%s' % ls1)

    te.insert('1.0', " 可用interface名字: %s\n" % ls1)

te.insert('1.0', "*******************************\n")

l1 = Label(root, text="输入interface名:")

l1.pack()# 这里的side可以赋值为LEFT  RIGHT TOP  BOTTOM

    global xls

xls = Entry()

xls.pack()

l2 = Label(root, text="输入ip地址段前三位(如192.168.3):")

l2.pack()# 这里的side可以赋值为LEFT  RTGHT TOP  BOTTOM

    global sheet

sheet = Entry()

sheet.pack()

def add_ip():

n =0

    t1 = time.time()

interface = xls.get()

ip = sheet.get()

for iin range(0, 25):

address ='%s.%s/24' % (ip, i)

network ='%s.0' % ip

inputsentence = ['/ip/address/add', '=address=%s' % address, '=interface=%s' % interface,

                        '=network=%s' % network, '=comment=%s %s' % (address, interface)]

apiros.writeSentence(inputsentence)

x = apiros.readSentence()

# print("添加address:%s成功" % address)

        te.insert('1.0', "添加ip:%s成功\n" % address)

n +=1

    t2 = time.time()

t = t2 - t1

# print('添加ip数量:%s' % n)

    te.insert('1.0', "添加ip数量:%s\n" % n)

print('添加ip用时:%s' % t)

te.insert('1.0', "添加ip用时:%s\n" % t)

te.insert('1.0', "*******************************\n")

def remove_ip():

"""

批量删除ip

    :return:

"""

    s =None

    for resin socket.getaddrinfo(sys.argv[1], "8728", socket.AF_UNSPEC, socket.SOCK_STREAM):

af, socktype, proto, canonname, sa = res

try:

s = socket.socket(af, socktype, proto)

except socket.error:

s =None

continue

        try:

s.connect(sa)

except socket.error:

s.close()

s =None

continue

break

    if sis None:

print('could not open socket')

sys.exit(1)

apiros = ApiRos(s)

apiros.login(sys.argv[2], sys.argv[3])

# 批量删除ip

    global count

count = -1

    global n

n =0

    inputsentence = ['/ip/address/print', '=.proplist=.id,comment']

apiros.writeSentence(inputsentence)

while 1:

x = apiros.readSentence()

count +=1

        if len(x) >2:

# x[1]为ip 的 id

            while 1:

inputsentence = ['/ip/address/remove', x[1]]

apiros.writeSentence(inputsentence)

y = apiros.readSentence()

n +=1

                if y == ['!done']or y == ['!re', '=status=finished']:

break

            # print("删除%s成功" % x[2])

            te.insert('1.0', "删除ip:%s成功\n" % x[2])

else:

pass

        if x == ['!done']or x == ['!re', '=status=finished']:

break

def start_remove_ip():

"""

执行remove_ip

    :return:

"""

    t1 = time.time()

while 1:

remove_ip()

if n ==0:

break

    t2 = time.time()

t = t2 - t1

# print('剩余ip总数:%s' % count)

    te.insert('1.0', "剩余ip总数:%s成功\n" % count)

# print('删除ip用时:%s' % t)

    te.insert('1.0', "删除ip用时:%s\n" % t)

te.insert('1.0', "*******************************\n")

def backup():

"""

备份设备

    :return:

"""

    s =None

    for resin socket.getaddrinfo(sys.argv[1], "8728", socket.AF_UNSPEC, socket.SOCK_STREAM):

af, socktype, proto, canonname, sa = res

try:

s = socket.socket(af, socktype, proto)

except socket.error:

s =None

continue

        try:

s.connect(sa)

except socket.error:

s.close()

s =None

continue

break

    if sis None:

print('could not open socket')

sys.exit(1)

apiros = ApiRos(s)

apiros.login(sys.argv[2], sys.argv[3])

inputsentence = []

inputsentence.append('/system/backup/save')

# 按日期生成文件名

    filename = datetime.now().strftime('%Y%m%d %H%M%S')

inputsentence.append(' =name=%s.backup' % filename)

apiros.writeSentence(inputsentence)

while 1:

x = apiros.readSentence()

print(x)

if x == ['!done']or x == ['!re', '=status=finished']:

# print("备份成功")

            te.insert('1.0', "备份:%s.backup成功\n" % filename)

break

    te.insert('1.0', "*******************************\n")

def check_ip():

"""

查看ip

    :return:

"""

    s =None

    for resin socket.getaddrinfo(sys.argv[1], "8728", socket.AF_UNSPEC, socket.SOCK_STREAM):

af, socktype, proto, canonname, sa = res

try:

s = socket.socket(af, socktype, proto)

except socket.error:

s =None

continue

        try:

s.connect(sa)

except socket.error:

s.close()

s =None

continue

break

    if sis None:

print('could not open socket')

sys.exit(1)

apiros = ApiRos(s)

apiros.login(sys.argv[2], sys.argv[3])

# 查看ip

    inputsentence = ['/ip/address/print', ]

apiros.writeSentence(inputsentence)

count1 = -1

    while 1:

x = apiros.readSentence()

count1 +=1

        if x == ['!done']or x == ['!re', '=status=finished']:

break

    print('ip总数:%s' % count1)

te.insert('1.0', "ip总数:%s\n" % count1)

te.insert('1.0', "*******************************\n")

def check_route():

"""

查看route

    :return:

"""

    s =None

    for resin socket.getaddrinfo(sys.argv[1], "8728", socket.AF_UNSPEC, socket.SOCK_STREAM):

af, socktype, proto, canonname, sa = res

try:

s = socket.socket(af, socktype, proto)

except socket.error:

s =None

continue

        try:

s.connect(sa)

except socket.error:

s.close()

s =None

continue

break

    if sis None:

print('could not open socket')

sys.exit(1)

apiros = ApiRos(s)

apiros.login(sys.argv[2], sys.argv[3])

# 查看route

    inputsentence = ['/ip/route/print', ]

apiros.writeSentence(inputsentence)

count2 = -1

    while 1:

x = apiros.readSentence()

count2 +=1

        if x == ['!done']or x == ['!re', '=status=finished']:

break

    # print('route总数:%s' % count2)

    te.insert('1.0', "route总数:%s\n" % count2)

te.insert('1.0', "*******************************\n")

def add_route():

"""

批量添加route

    :return:

"""

    gateway = xls.get()

ip = sheet.get()

for iin range(0, 10):

dst_address ='%s.%s.0/24' % (ip[:ip.rfind('.')], i)

# pref_src = '%s.%s.%s' % (ip, i, i)

        inputsentence = ['/ip/route/add', '=dst-address=%s' % dst_address, '=gateway=%s' % gateway,

                        '=comment=%s ' % dst_address]

apiros.writeSentence(inputsentence)

x = apiros.readSentence()

# print("添加route:%s成功" % dst_address)

        te.insert('1.0', "添加route:%s成功\n" % dst_address)

te.insert('1.0', "*******************************\n")

def remove_route():

"""

批量删除route

    :return:

"""

    s =None

    for resin socket.getaddrinfo(sys.argv[1], "8728", socket.AF_UNSPEC, socket.SOCK_STREAM):

af, socktype, proto, canonname, sa = res

try:

s = socket.socket(af, socktype, proto)

except socket.error:

s =None

continue

        try:

s.connect(sa)

except socket.error:

s.close()

s =None

continue

break

    if sis None:

print('could not open socket')

sys.exit(1)

apiros = ApiRos(s)

apiros.login(sys.argv[2], sys.argv[3])

# 批量删除route

    global count

count = -1

    global n

n =0

    inputsentence = ['/ip/route/print', '?>comment=', '=.proplist=.id,gateway']

apiros.writeSentence(inputsentence)

while 1:

x = apiros.readSentence()

count +=1

        if len(x) ==3:

inputsentence = ['/ip/route/remove', x[1]]

apiros.writeSentence(inputsentence)

y = apiros.readSentence()

n +=1

            # print ("删除%s成功" % x[2])

            te.insert('1.0', "删除%s成功\n" % x[2])

if x == ['!done']or x == ['!re', '=status=finished']:

break

def start_remove_route():

"""

执行 remove_route

    :return:

"""

    t1 = time.time()

t2 = t1 +15

    while 1:

remove_route()

t3 = time.time()

if t3 > t2:

te.insert('1.0', "*******************************\n")

break

def remove_re():

"""

route去重

    :return:

"""

    s =None

    for resin socket.getaddrinfo(sys.argv[1], "8728", socket.AF_UNSPEC, socket.SOCK_STREAM):

af, socktype, proto, canonname, sa = res

try:

s = socket.socket(af, socktype, proto)

except socket.error:

s =None

continue

        try:

s.connect(sa)

except socket.error:

s.close()

s =None

continue

break

    if sis None:

print('could not open socket')

sys.exit(1)

apiros = ApiRos(s)

apiros.login(sys.argv[2], sys.argv[3])

# 批量删除重复route

    global count

count = -1

    global n

n =0

    inputsentence = ['/ip/route/print', '?=active=false', '=.proplist=.id,gateway']

apiros.writeSentence(inputsentence)

while 1:

x = apiros.readSentence()

count +=1

        if len(x) ==3:

inputsentence = ['/ip/route/remove', x[1]]

apiros.writeSentence(inputsentence)

y = apiros.readSentence()

n +=1

            # print("删除%s成功" % x[2])

            te.insert('1.0', "去重%s成功\n" % x[2])

if x == ['!done']or x == ['!re', '=status=finished']:

break

def start_remove_re():

"""

执行remove_re

    :return:

"""

    t1 = time.time()

t2 = t1 +15

    while 1:

remove_re()

t3 = time.time()

if t3 > t2:

te.insert('1.0', "*******************************\n")

break

te = Text()

te.pack()

Button(root, text="备份设备", bg='green', command=backup).pack(padx=10, pady=10, ipadx=3, side=LEFT)

Button(root, text="查看可用interface", bg='green', command=check_interface).pack(padx=5,  pady=20, side=LEFT)

Button(root, text="查看ip", bg='green', command=check_ip).pack(padx=5, pady=10,  ipadx=3, side=LEFT)

Button(root, text="查看route", bg='green', command=check_route).pack(padx=5,  pady=15, ipadx=3, side=LEFT)

Button(root, text="删除ip", bg='#ff3300', command=start_remove_ip).pack(padx=5, pady=10,  ipadx=3, side=RIGHT)

Button(root, text="删除route", bg='#ff3300', command=start_remove_route).pack(padx=5,  pady=10, ipadx=3, side=RIGHT)

Button(root, text="route去重", bg='#ff3300', command=start_remove_re).pack(padx=5,  pady=10, ipadx=3, side=RIGHT)

Button(root, text="增加ip", bg='#9900ff', command=add_ip).pack(padx=5, pady=10,  ipadx=3,  side=RIGHT)

Button(root, text="增加route", bg='#9900ff', command=add_route).pack(padx=5, pady=10, ipadx=3, side=RIGHT)

root.mainloop()

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,636评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,890评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,680评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,766评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,665评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,045评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,515评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,182评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,334评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,274评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,319评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,002评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,599评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,675评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,917评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,309评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,885评论 2 341

推荐阅读更多精彩内容

  • 学习新东西当要用到我们的3W方法了(what why how),下面我们来学习下ros的api, 地址:https...
    追寻823阅读 9,644评论 0 0
  • http://python.jobbole.com/85231/ 关于专业技能写完项目接着写写一名3年工作经验的J...
    燕京博士阅读 7,543评论 1 118
  • Python 面向对象Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对...
    顺毛阅读 4,205评论 4 16
  • 今天是我每天一篇文章的第120篇。 这两天才知道一个消息,一家电商公司准备解散了,因为这个公司跟我颇有渊源...
    很温暖阅读 192评论 0 0
  • 【奇谈杂阅】农历鸡年来了。找了一下关于鸡的成语,发现很多都和狗在一起——鸡飞狗跳,鸡鸣狗盗,偷鸡摸狗,斗鸡走狗,鸡...
    奇妙的奇阅读 151评论 0 0