iBu*_*Bug 5 python bots python-requests
我正在尝试开发一个能够在Stack Overflow上标记帖子的机器人.
from stackoverflow import StackOverflow
aaa = StackOverflow()
aaa.login("some email", "some password")
aaa.login_site()
response = aaa.add_flag(random_answer, "AnswerNotAnAnswer")
print(response.json())
Run Code Online (Sandbox Code Playgroud)
当然,您希望在.login()通话中替换电子邮件和密码,并替换random_answer为真实的答案ID.
我得到的结果是:
{'Success': False, 'Message': 'You do not have permission to flag this post', 'ResultChangedState': False, 'Outcome': 2}
Run Code Online (Sandbox Code Playgroud)
我还尝试使用浏览器登录并手动标记帖子.响应(在F12控制台中)是正确的:
{"Success":true,"Message":"Thanks, we'll take a look at it","FlagType":17,"ResultChangedState":false,"Outcome":0}
Run Code Online (Sandbox Code Playgroud)
简而言之,我正在尝试使用Stack Exchange OpenID登录,登录到Stack Overflow,并向其发送POST请求/flags/posts/<post_id>/add/<flag_type>.
这是代码(MCVE)的一部分,文件名stackoverflow.py当然是.
import requests
from bs4 import BeautifulSoup
class StackOverflow:
def __init__(self):
self.session = requests.Session()
self.session.headers.update({
"User-Agent": "StackOverflow/0.dev (+/dev/null)",
})
self.host = "stackoverflow.com"
self.root = "https://" + self.host
self.fkey = None
def get(self, url, data=None, headers=None, root=True):
if root:
url = self.root + url
return self.session.get(url, data=data, headers=headers, timeout=5.0)
def post(self, url, data=None, headers=None, root=True):
if root:
url = self.root + url
return self.session.post(url, data=data, headers=headers, timeout=5.0)
def get_soup(self, url, data=None, headers=None, root=True):
response = self.get(url, data, headers, root)
return BeautifulSoup(response.text, "html.parser")
def login_site(self):
return self._login_openid(
'https://{}/users/login?returnurl=%2F'.format(self.host),
'https://{}/users/authenticate'.format(self.host),
{
'oauth_version': "",
'oauth_server': "",
'openid_identifier': "https://openid.stackexchange.com/",
})
def login(self, email, password):
return self._login_openid(
'https://openid.stackexchange.com/account/login',
'https://openid.stackexchange.com/account/login/submit',
{'email': email, 'password': password})
def _login_openid(self, fkey_url, post_url, data):
fkey_soup = self.get_soup(fkey_url, root=False)
fkey_input = fkey_soup.find('input', {'name': 'fkey'})
if not fkey_input:
raise ValueError("fkey not found")
self.fkey = fkey_input['value']
data['fkey'] = self.fkey
response = self.post(post_url, data=data, root=False)
return response
def add_flag(self, post_id, flag_type="AnswerNotAnAnswer"):
response = self.post("/flags/posts/{}/add/{}".format(post_id, flag_type), data={
'fkey': self.fkey,
}, headers={
'Origin': "https://stackoverflow.com",
'Referer': "https://stackoverflow.com/",
}, root=True)
return response
Run Code Online (Sandbox Code Playgroud)