-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
* Support login * Finish all * fix workflow: "./sign.py: Permission denied" * test: "No module named 'ddddocr'" * test: "No module named 'ddddocr'" * test: "No module named 'ddddocr'" * fix: "A module that was compiled using NumPy 1.x cannot be run in NumPy 2.0.0 as it may crash. To support both 1.x and 2.x" * fix: "No module named 'ddddocr'"
- Loading branch information
Showing
8 changed files
with
369 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
name: jietiandi-dev | ||
on: | ||
push: | ||
branches: | ||
- 18-post-in-jietiandi-forum-automatically | ||
jobs: | ||
dev: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- name: Set up Python | ||
# This is the version of the action for setting up Python, not the Python version. | ||
uses: actions/setup-python@v5 | ||
with: | ||
# Semantic version range syntax or exact version of a Python version | ||
python-version: '3.12' | ||
- name: Install requirements | ||
working-directory: jietiandi | ||
run: pip3 install -r requirements.txt | ||
- name: Sign | ||
env: | ||
USERNAME: ${{ secrets.JIETIANDI_USERNAME }} | ||
PASSWORD: ${{ secrets.JIETIANDI_PASSWORD }} | ||
run: | | ||
chmod u+x sign.py | ||
python ./sign.py | ||
working-directory: jietiandi | ||
- name: Post | ||
env: | ||
USERNAME: ${{ secrets.JIETIANDI_USERNAME }} | ||
PASSWORD: ${{ secrets.JIETIANDI_PASSWORD }} | ||
run: | | ||
chmod u+x post.py | ||
python ./post.py | ||
working-directory: jietiandi | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
name: jietiandi-prod-post | ||
on: | ||
push: | ||
branches: | ||
- main | ||
schedule: | ||
- cron: '0/12 1-4 * * *' | ||
jobs: | ||
post: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- name: Set up Python | ||
# This is the version of the action for setting up Python, not the Python version. | ||
uses: actions/setup-python@v5 | ||
with: | ||
# Semantic version range syntax or exact version of a Python version | ||
python-version: '3.x' | ||
- name: Install requirements | ||
run: pip3 install -r requirements.txt | ||
working-directory: jietiandi | ||
- name: Post | ||
env: | ||
USERNAME: ${{ secrets.JIETIANDI_USERNAME }} | ||
PASSWORD: ${{ secrets.JIETIANDI_PASSWORD }} | ||
run: | | ||
chmod u+x post.py | ||
python ./post.py | ||
working-directory: jietiandi | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
name: jietiandi-prod-sign | ||
on: | ||
push: | ||
branches: | ||
- main | ||
schedule: | ||
- cron: '0 23 * * *' | ||
jobs: | ||
sign: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- name: Set up Python | ||
# This is the version of the action for setting up Python, not the Python version. | ||
uses: actions/setup-python@v5 | ||
with: | ||
# Semantic version range syntax or exact version of a Python version | ||
python-version: '3.x' | ||
- name: Install requirements | ||
run: pip3 install -r requirements.txt | ||
working-directory: jietiandi | ||
- name: Sign | ||
env: | ||
USERNAME: ${{ secrets.JIETIANDI_USERNAME }} | ||
PASSWORD: ${{ secrets.JIETIANDI_PASSWORD }} | ||
run: | | ||
chmod u+x sign.py | ||
python ./sign.py | ||
working-directory: jietiandi | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
__pycache__ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
#!/usr/bin/python3 | ||
|
||
import pickle | ||
from os import listdir | ||
import sys | ||
import logging | ||
# import requests | ||
import ddddocr | ||
import re | ||
from curl_cffi import requests | ||
|
||
# 日志输出至控制台 | ||
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(filename)s %(funcName)s:line %(lineno)d %(levelname)s %(message)s") | ||
|
||
class Login: | ||
def __init__(self, hostname, username, password, questionid='0', answer=None, cookies_flag=True): | ||
self.session = requests.Session() | ||
self.session.headers.update({'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36'}) | ||
self.hostname = hostname | ||
self.username = str(username) | ||
self.password = str(password) | ||
|
||
self.questionid = questionid | ||
self.answer = answer | ||
self.cookies_name = 'cookies.pk' | ||
self.cookies_flag = cookies_flag | ||
self.ocr = ddddocr.DdddOcr() | ||
|
||
|
||
def form_hash(self): | ||
rst = self.session.get(f'https://{self.hostname}/member.php?mod=logging&action=login').text | ||
# logging.info(f'{rst}') | ||
loginhash = re.search(r'<div id="main_messaqge_(.+?)">', rst).group(1) | ||
formhash = re.search(r'<input type="hidden" name="formhash" value="(.+?)" />', rst).group(1) | ||
logging.info(f'loginhash : {loginhash} , formhash : {formhash} ') | ||
return loginhash, formhash | ||
|
||
def verify_code_once(self): | ||
rst = self.session.get(f'https://{self.hostname}/misc.php?mod=seccode&action=update&idhash=cSA&0.3701502461393815&modid=member::logging').text | ||
update = re.search(r'update=(.+?)&idhash=', rst).group(1) | ||
|
||
code_headers = { | ||
'Accept': 'image/webp,image/apng,image/*,*/*;q=0.8', | ||
'Accept-Encoding': 'gzip, deflate, br', | ||
'Accept-Language': 'zh-CN,zh;q=0.9', | ||
'Connection': 'keep-alive', | ||
'hostname': f'{self.hostname}', | ||
'Referer': f'https://{self.hostname}/member.php?mod=logging&action=login', | ||
'Sec-Fetch-Mode': 'no-cors', | ||
'Sec-Fetch-Site': 'same-origin', | ||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36' | ||
} | ||
rst = self.session.get(f'https://{self.hostname}/misc.php?mod=seccode&update={update}&idhash=cSA', | ||
headers=code_headers) | ||
|
||
return self.ocr.classification(rst.content) | ||
|
||
|
||
def verify_code(self,num = 10): | ||
while num>0: | ||
num -=1 | ||
code = self.verify_code_once() | ||
verify_url = f'https://{self.hostname}/misc.php?mod=seccode&action=check&inajax=1&modid=member::logging&idhash=cSA&secverify={code}' | ||
res = self.session.get(verify_url).text | ||
|
||
if 'succeed' in res: | ||
logging.info('验证码识别成功,验证码:'+code) | ||
return code | ||
else: | ||
logging.info('验证码识别失败,重新识别中...') | ||
|
||
logging.error('验证码获取失败,请增加验证次数或检查当前验证码识别功能是否正常') | ||
return '' | ||
|
||
def account_login_without_verify(self): | ||
|
||
loginhash, formhash = self.form_hash() | ||
login_url = f'https://{self.hostname}/member.php?mod=logging&action=login&loginsubmit=yes&loginhash={loginhash}&inajax=1' | ||
formData = { | ||
'formhash': formhash, | ||
'referer': f'https://{self.hostname}/', | ||
'username': self.username, | ||
'password': self.password, | ||
} | ||
login_rst = self.session.post(login_url, data=formData).text | ||
if 'succeed' in login_rst: | ||
logging.info('登陆成功') | ||
return True | ||
else: | ||
logging.info('登陆失败,请检查账号或密码是否正确') | ||
return False | ||
|
||
|
||
|
||
def account_login(self): | ||
try: | ||
if self.account_login_without_verify(): | ||
return True | ||
except Exception: | ||
logging.error('存在验证码,登陆失败,准备获取验证码中', exc_info=True) | ||
|
||
code = self.verify_code() | ||
if code =='': | ||
return False | ||
|
||
loginhash, formhash = self.form_hash() | ||
login_url = f'https://{self.hostname}/member.php?mod=logging&action=login&loginsubmit=yes&loginhash={loginhash}&inajax=1' | ||
formData = { | ||
'formhash': formhash, | ||
'referer': f'https://{self.hostname}/', | ||
'loginfield': self.username, | ||
'username': self.username, | ||
'password': self.password, | ||
'questionid': self.questionid, | ||
'answer': self.answer, | ||
'cookietime': 2592000, | ||
'seccodehash': 'cSA', | ||
'seccodemodid': 'member::logging', | ||
'seccodeverify': code, # verify code | ||
} | ||
login_rst = self.session.post(login_url, data=formData).text | ||
if 'succeed' in login_rst: | ||
logging.info('登陆成功') | ||
return True | ||
else: | ||
logging.info('登陆失败,请检查账号或密码是否正确') | ||
return False | ||
|
||
|
||
def cookies_login(self): | ||
if self.cookies_name in listdir(): | ||
try: | ||
with open(self.cookies_name, 'rb') as f: | ||
self.session.cookies.jar._cookies = pickle.load(f) | ||
response = self.session.get(f'https://{self.hostname}/home.php?mod=space').text | ||
|
||
if "退出" in response and "登录" not in response: | ||
logging.info('从文件中恢复Cookie成功,跳过登录。') | ||
return True | ||
except Exception: | ||
logging.warning('Cookie失效,使用账号密码登录。') | ||
else: | ||
logging.info('初次登录未发现Cookie,使用账号密码登录。') | ||
return False | ||
|
||
|
||
def go_home(self): | ||
return self.session.get(f'https://{self.hostname}/forum.php').text | ||
|
||
def main(self): | ||
|
||
try: | ||
if self.cookies_flag and self.cookies_login(): | ||
logging.info('成功使用cookies登录') | ||
else: | ||
self.account_login() | ||
with open(self.cookies_name, 'wb') as f: | ||
pickle.dump(self.session.cookies.jar._cookies, f) | ||
logging.info('新的Cookie已保存。') | ||
|
||
except Exception: | ||
logging.error('失败,发生了一个错误!', exc_info=True) | ||
sys.exit() | ||
|
||
|
||
if __name__ == '__main__': | ||
login = Login('','','') | ||
login.main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
#!/usr/bin/python3 | ||
|
||
import login | ||
|
||
import logging | ||
import re | ||
import requests | ||
import os | ||
logging.basicConfig(level=logging.INFO ,format="%(asctime)s %(filename)s %(funcName)s:line %(lineno)d %(levelname)s %(message)s") | ||
|
||
|
||
class Post: | ||
def __init__(self, hostname, username, password, questionid='0', answer=None, cookies_flag=True,pub_url = ''): | ||
self.hostname = hostname | ||
if pub_url !='': | ||
self.hostname = self.get_host(pub_url) | ||
|
||
self.discuz_login = login.Login(self.hostname, username, password, questionid, answer, cookies_flag) | ||
|
||
def login(self): | ||
self.discuz_login.main() | ||
self.session = self.discuz_login.session | ||
self.formhash = self.get_formhash() | ||
|
||
def get_formhash(self): | ||
rst = self.session.get(f'https://{self.hostname}/forum.php?mod=viewthread&tid=2951721&extra=page%3D1').text | ||
formhash = re.search(r'<input type="hidden" name="formhash" value="(.+?)" />', rst).group(1) | ||
return formhash | ||
|
||
def get_host(self,pub_url): | ||
res = requests.get(pub_url) | ||
res.encoding = "utf-8" | ||
url = re.search(r'a href="https://(.+?)/".+?>.+?入口</a>', res.text) | ||
if url != None: | ||
url = url.group(1) | ||
logging.info(f'获取到最新的论坛地址:https://{url}') | ||
return url | ||
else: | ||
logging.error(f'获取失败,请检查发布页是否可用{pub_url}') | ||
return self.hostname | ||
|
||
def post(self): | ||
post_url = f'https://{self.hostname}/forum.php?mod=post&action=reply&fid=294&tid=2951721&extra=page%3D1&replysubmit=yes&infloat=yes&handlekey=fastpost&inajax=1' | ||
data = { | ||
'message': 'ddddddddddddddddddd', | ||
'formhash': self.formhash, | ||
'usesig': 1, | ||
'subject': '' | ||
} | ||
res = self.session.post(post_url, data=data).text | ||
# logging.info(res) | ||
if 'succeed' in res: | ||
logging.info('回复发送成功') | ||
else : | ||
logging.error('回复发送失败') | ||
|
||
if __name__ == '__main__': | ||
hostname = 'jietiandi.net' | ||
username = os.getenv('USERNAME') | ||
password = os.getenv('PASSWORD') | ||
post = Post(hostname,username,password) | ||
post.login() | ||
post.post() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
curl_cffi==0.6.4 | ||
ddddocr==1.5.4 | ||
Requests==2.32.3 | ||
numpy==1.26.4 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
#!/usr/bin/python3 | ||
|
||
import login | ||
import logging | ||
import re | ||
import os | ||
|
||
logging.basicConfig(level=logging.INFO ,format="%(asctime)s %(filename)s %(funcName)s:line %(lineno)d %(levelname)s %(message)s") | ||
|
||
class Sign: | ||
def __init__(self, hostname, username, password, questionid='0', answer=None, cookies_flag=True): | ||
self.hostname = hostname | ||
self.discuz_login = login.Login(self.hostname, username, password, questionid, answer, cookies_flag) | ||
|
||
def login(self): | ||
self.discuz_login.main() | ||
self.session = self.discuz_login.session | ||
|
||
def sign(self): | ||
# 未来可以考虑直接用formhash拼接,目测是同一个formhash | ||
rst = self.session.get(f'https://{self.hostname}/plugin.php?id=zqlj_sign').text | ||
# logging.info(rst) | ||
sign = re.search(r'a href="plugin.php\?id=zqlj_sign&sign=(.+?)".+?>.+?打卡</a>', rst).group(1) | ||
rst = self.session.get(f'https://{self.hostname}/plugin.php?id=zqlj_sign&sign={sign}').text | ||
# logging.info(rst) | ||
if '已经打过卡' in rst: | ||
logging.warning('已经打过卡') | ||
else: | ||
logging.info('打卡成功') | ||
|
||
if __name__ == '__main__': | ||
hostname = 'jietiandi.net' | ||
username = os.getenv('USERNAME') | ||
password = os.getenv('PASSWORD') | ||
sign = Sign(hostname,username,password) | ||
sign.login() | ||
sign.sign() |