Discuz发帖器的实现
首先要清楚discuz论坛发帖的流程,简单地说就是以下流程:
进入登录页 ->登录 -> 进入版面 ->发帖
登录和发帖时要获取到页面的formhash值,否则会失败,如果启用了验证码,还得去分析验证码,这就比较复杂了。这里只用python来描述这一系列过程,涉及到验证码还请大家自行去实现。
#!/usr/bin/env python
#coding=utf-8
from urllib import urlencode
import cookielib, urllib2,urllib
import os,sys
import urllib2,cookielib,urllib,httplib,re
import getpass
import time
from Queue import Queue
import threading
class Discuz:
def __init__(self,uid,pwd,debug = False,**param):
self.username = uid
self.password = pwd
self.para = param
#self.timelimit = timelimit
self.regex = {
'loginreg':'<input\s*type="hidden"\s*name="formhash"\s*value="([\w\W]+?)"\s*\/>',
'postreg':'<input\s*type="hidden"\s*name="formhash"\s*id="formhash"\s*value="([\w\W]+?)"\s*\/>'
}
self.opener = None
self.request = None
self.islogin = False
self.donecount = 0
self.__login()
self.threadcount = 10
def __login(self):
try:
loginPage = urllib2.urlopen(self.para['loginurl']).read()
formhash = re.search(self.regex['loginreg'],loginPage)
formhash = formhash.group(1)
print 'start login......'
cookiejar = cookielib.CookieJar()
self.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookiejar))
values = {
'formhash':formhash,
'username':self.username,
'password':self.password,
'loginsubmit':'true'
}
data = urllib.urlencode(values)
self.request = urllib2.Request(self.para['loginsubmiturl'], data)
rq = self.opener.open(self.request)
print 'login success......'
self.islogin = True
except Exception ,e:
print e
def Post(self,subject,wysiwyg,content):
threads = []
for i in range(self.threadcount):
t = threading.Thread(
target=self.__postTopic,
kwargs={'_subject':subject,'_wysiwyg':wysiwyg,'_body':content}
)
threads.append(t)
for i in range(self.threadcount):
threads[i].start()
for i in range(self.threadcount):
threads[i].join()
print 'done'
def __postTopic(self,**para):
if not self.islogin:
print 'please login......'
return
while True:
try:
self.request = urllib2.Request(self.para['posturl'])
rq = self.opener.open(self.request)
data = rq.read()
formhash = re.search(self.regex['postreg'],data)
formhash = formhash.group(1)
postdata = {
'addtags':'+可用标签',
'checkbox':'0',
'formhash':formhash,
'iconid':'',
'message':para['_body'],
'subject':para['_subject'],
'tags':'',
'updateswfattach' : '0',
'wysiwyg' : para['_wysiwyg']
}
self.request = urllib2.Request(self.para['postsubmiturl'],urllib.urlencode(postdata))
self.opener.open(self.request)
self.donecount+=1
print '%d done.....' % self.donecount
except Exception,e:
print e
time.sleep(2)
if __name__=='__main__':
name = raw_input('username:')
password = getpass.getpass('password:')
dz = Discuz(name,password,
loginurl='http://xxx/logging.php?action=login',
loginsubmiturl='http://xxx/logging.php?action=login&loginsubmit=yes',
posturl='http://xxx/post.php?action=newthread&fid=5',
postsubmiturl='http://xxx/post.php?&action=newthread&fid=5&extra=&topicsubmit=yes')
content='''这是帖子内容'''
dz.Post('这是帖子标题','1',content)
Discuz类中只有一个公开方法
def Post(self,subject,wysiwyg,content)
三个参数,分别是帖子标题、是否是可视化编辑、帖子内容。
类实例化时会进行登录操作,并同时记录下cookie以备用,Post方法中会启用多个线程执行私有方法__postTopic(self,**para)进行真正的发帖操作。
所以,基本上Discuz生成的formhash就是一个鸡肋 -_-
转载时务必以超链接形式标明文章原始出处和作者信息。
如果导出论坛列表群发。
多个论坛站点如何处理。opener的Session是一个问题。
不过学习了。最近也在研究这个。呵呵
[回复Ta]