python discuz_[Python代码]Discuz!论坛(X2.5)发帖及回复脚本

更多

昨天,我介绍了Discuz!论坛登录的Python脚本实现(点击进入)。今天,我继续这一系列,介绍Discuz!论坛最常见的一类脚本操作——发帖及回复。这里,我只实现普通主题的发表以及回复的脚本。

首先,我们依然要来分析发主题帖和回复时传输的数据包所post的数据:

1x1.trans.gif

上面这张图是发帖时的post数据。

formhash是昨天登录脚本中在登录后页面中获得的formhash。如果没有正确的formhash,发帖时就会显示“您的来路请求不正确”的错误提示,请大家一定要注意!

subject和message分别是发表的新主题帖的题目和帖子内容。

上面三项是必须要post的数据。下面再对剩下的几组键值对进行简要的介绍,这些键值对不是必需出现的,在程序中就不对其进行实现了。

posttime是发帖时间,会由程序自动生成,不需要我们关心。

wysiwyg全称为“What You See Is What You Get”,翻译成中文就是“所见即所得”。在Discuz!论坛发贴的高级界面我们会看到这一复选框,目前的名字为“纯文本”。

replycredit相关的一组键是回帖奖励。这里不对其进行具体的介绍。

readperm是阅读权限,Discuz!最高的阅读权限是255。

price是主题价格,Discuz!论坛允许对一些用户组设置可以发布付费主题,这样用户查看主题需要花费某种积分给发帖人。

tags是主题的标签,目前Discuz!默认每个主题最多有5个标签。

rushreplyfrom以及后续的几项是抢楼帖相关的选项,我们在这里也不再具体介绍。不过,当设置为抢楼帖时还会有一个叫做rushreply的选项出现。

usesig的含义是是否使用用户的个人签名档。

allownoticeauthor是指发帖后,如果有其他用户回复这个主题,是否已“提醒”的方式通知楼主。

当然,还有一些其他选项,需要勾选后,其相关的键值对才会出现在post数据中,我在这里也就不再做介绍了。

下面再来看回复时候的post数据。

1x1.trans.gif

这次的post数据不多,和上面发帖时也有很多一样的。不过在回复时,不再需要subject这一选项,我们只需要把formhash和message两项post过去就可以了。

接下来就是我的代码了。

第一个文件,依然是配置文件config.py,和昨天相比增加了如下的代码:

config.py

Python

POSTURL = DOMAIN + r'forum.php?mod=post&action=newthread&fid=FID&extra=&topicsubmit=yes'

REPLYURL = DOMAIN + r'forum.php?mod=post&action=reply&tid=TID&extra=&replysubmit=yes'

1

2

3

POSTURL=DOMAIN+r'forum.php?mod=post&action=newthread&fid=FID&extra=&topicsubmit=yes'

REPLYURL=DOMAIN+r'forum.php?mod=post&action=reply&tid=TID&extra=&replysubmit=yes'

这两行分别是发新主题和回复时的对应地址,我们可以从post的数据包中看到这个地址。

然后,我们修改discuz.py这个基类所在的文件,在Discuz类里添加一个字符串截断的代码,其余部分不变,可以参考昨天的文章:

discuz.py

Python

def _interception(self, string, length):

'''字符串截取(为简单起见,认为所有字均占3个字符)'''

if (len(string) > (length / 3)):

return string[0:(length / 3 - 1)] + '...'

else:

return string

1

2

3

4

5

6

def_interception(self,string,length):

'''字符串截取(为简单起见,认为所有字均占3个字符)'''

if(len(string)>(length/3)):

returnstring[0:(length/3-1)]+'...'

else:

returnstring

由于Discuz!默认主题题目不超过80个字符,对于utf-8来说也就是26个汉字,因此我们需要一个字符串截断方法,防止由于主题题目过长造成的发帖失败。在这里,为简单起见,认为任何字均为3个字符,不考虑英文字符、数字、半角标点等情况。

接下来,就是最重要的Post类了,我在post.py文件中进行实现。

post.py

Python

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

import re

import config

import discuz

class Post(discuz.Discuz):

def __init__(self):

super(Post, self).__init__()

self.post_success_pattern = re.compile(r'') # 发帖成功时匹配

self.post_fail_pattern = re.compile(r'

') # 发贴失败时匹配

self.post_error_pattern = re.compile(r'

(?u)(.+)

') # 发贴失败的错误信息

def newthread(self, fid, subject, message):

postdata = {

'subject': self._interception(subject, 80),

'message': message,

'formhash': self.formhash,

}

base_url = config.POSTURL

url = base_url.replace('FID', fid)

self.operate = self._get_response(url, postdata)

prefix = '主题 "%s" ' % postdata['subject']

self.__verify_post_status(prefix)

def reply(self, tid, message):

postdata = {

'message': message,

'formhash': self.formhash,

}

base_url = config.REPLYURL

url = base_url.replace('TID', tid)

self.operate = self._get_response(url, postdata)

prefix = '回复 "%s" ' % self._interception(message, 80)

self.__verify_post_status(prefix)

def __verify_post_status(self, prefix):

page_content = self.operate.read().decode('utf-8')

if self.post_success_pattern.search(page_content):

print "%s发布成功!" % prefix

elif self.post_fail_pattern.search(page_content):

post_error_message = self.post_error_pattern.search(page_content)

try:

print "%s发布失败!原因是:%s。" % (prefix, post_error_message.group(1))

except:

print "%s发布失败!原因是:未知原因。" % prefix

else:

print "无法确定%s发布状态" % prefix

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

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

importre

importconfig

importdiscuz

classPost(discuz.Discuz):

def__init__(self):

super(Post,self).__init__()

self.post_success_pattern=re.compile(r'')# 发帖成功时匹配

self.post_fail_pattern=re.compile(r'

')# 发贴失败时匹配

self.post_error_pattern=re.compile(r'

(?u)(.+)

')# 发贴失败的错误信息

defnewthread(self,fid,subject,message):

postdata={

'subject':self._interception(subject,80),

'message':message,

'formhash':self.formhash,

}

base_url=config.POSTURL

url=base_url.replace('FID',fid)

self.operate=self._get_response(url,postdata)

prefix='主题 "%s" '%postdata['subject']

self.__verify_post_status(prefix)

defreply(self,tid,message):

postdata={

'message':message,

'formhash':self.formhash,

}

base_url=config.REPLYURL

url=base_url.replace('TID',tid)

self.operate=self._get_response(url,postdata)

prefix='回复 "%s" '%self._interception(message,80)

self.__verify_post_status(prefix)

def__verify_post_status(self,prefix):

page_content=self.operate.read().decode('utf-8')

ifself.post_success_pattern.search(page_content):

print"%s发布成功!"%prefix

elifself.post_fail_pattern.search(page_content):

post_error_message=self.post_error_pattern.search(page_content)

try:

print"%s发布失败!原因是:%s。"%(prefix,post_error_message.group(1))

except:

print"%s发布失败!原因是:未知原因。"%prefix

else:

print"无法确定%s发布状态"%prefix

这里包含两个公开的方法,分别是发新主题的newthread和发回复的reply。还有一个私有方法__verify_post_status,是用于验证发表状态的。

最后是发帖和回复的使用方法。

post-demo.py

Python

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

import config

import post

if __name__ == "__main__":

my_account = post.Post()

my_account.login(config.USERNAME, config.PASSWORD)

my_account.newthread('2', u'发帖主题', u'发帖内容')

my_account.reply('10', u'发帖回复')

1

2

3

4

5

6

7

8

9

10

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

importconfig

importpost

if__name__=="__main__":

my_account=post.Post()

my_account.login(config.USERNAME,config.PASSWORD)

my_account.newthread('2',u'发帖主题',u'发帖内容')

my_account.reply('10',u'发帖回复')

这样,我们就实现了Discuz!最基本的发帖(普通帖)和回复功能的脚本,一般的使用也以这种发帖为主。当然,如果还有更高需求,要发表一些特殊类型帖(如悬赏帖、投票帖、辩论帖、活动帖、商品帖)的话,可以自己得到传输的post数据,分析需要填写的内容,在post.py中进行完善。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值