龙与地下城角色 Sheet 解析器来自 Python
Dungeons and Dragons Character Sheet parser via Python
这个项目的要点很简单,但是如果有人觉得自己有什么可以补充的,我们将不胜感激。
目的:该应用程序的目的是在 Myth-Weavers (https://www.myth-weavers.com/) 和 return 上创建的所有龙与地下城 sheet 上输入一个帐户帐户。这个
该应用程序还应该能够直接 link (https://www.myth-weavers.com/sheet.html#id=2311944)。这在理论上是可行的,因为您无需登录 Myth-Weavers 即可访问 link 和关联的 sheet。
第一部分:
我需要能够让应用程序进入站点并使用我的登录凭据进入我的帐户。当我登录该站点时,网络上会发送以下表单数据:
vb_login_username: Testbug Jones
vb_login_password:
s:
securitytoken: guest
do: login
vb_login_md5password: fea5ff2cf4764d2e76ea81e68bb458d1
vb_login_md5password_utf: fea5ff2cf4764d2e76ea81e68bb458d1
我正在使用以下代码通过登录检查我的进度:
import requests
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/85.0.4183.121 Safari/537.36'
}
login_data = {
's' : '',
'securitytoken' : 'guest',
'vb_login_username' : 'Testbug Jones',
'vb_login_password' : 'TeStBuG',
'redirect' : 'index.php',
'login' : 'Login',
'vb_login_md5password' : 'fea5ff2cf4764d2e76ea81e68bb458d1',
'vb_login_md5password_utf' : 'fea5ff2cf4764d2e76ea81e68bb458d1'
}
#get page
url = 'https://www.myth-weavers.com/'
source = requests.get(url)
#isolates login form, along with an sid
print('\n\n***CURRENT LOGIN STATUS***')
login_status = source.text
login_status = login_status.split("<!-- login form -->")[1]
login_status = login_status.split("<!-- / login form -->")[0]
print(login_status)
#nab sid and update library
sid = login_status.split('<input type="hidden" name="s" value="')[1]
sid = sid.split('" /')[0]
login_data['s'] = sid
#create session and attempt to log in
with requests.Session() as s:
print('\n\n***ATTEMPTING TO LOGIN***')
r = s.post(url, data = login_data, headers = headers)
login_status = r.text
login_status = login_status.split("<!-- login form -->")[1]
login_status = login_status.split("<!-- / login form -->")[0]
print(login_status)
至于登录表单本身,它通常看起来像:
<li class="smallfont" id="login" style="width: auto; float: right; text-align: right; padding-right: 6px;">
<span id="login_register"><a href="#" onclick="fetch_object('login_register').style.display = 'none'; fetch_object('login_form').style.display = ''; return false;" tabindex="0">Log In</a> / <a href="https://www.myth-weavers.com/register.php?s=f4cde1e552e96a9a2b4c4479559e6510">Register</a> <a href="//www.myth-weavers.com/login.php?do=lostpw" style="font-size:smaller">forgot password?</a></span>
<form id="login_form" style="display: none;" action="https://www.myth-weavers.com/login.php?do=login" method="post" onsubmit="md5hash(vb_login_password, vb_login_md5password, vb_login_md5password_utf, 0)">
<script type="text/javascript" src="//static.myth-weavers.com/clientscript/vbulletin_md5.js?v=388"></script>
<input type="text" class="bginput" style="font-size: 10px" name="vb_login_username" id="navbar_username" size="10" accesskey="u" tabindex="0" value="User Name" onfocus="if (this.value == 'User Name') this.value = '';" onblur="if (this.value == '') this.value = 'User Name';" />
<input type="password" class="bginput" style="font-size: 10px" name="vb_login_password" id="navbar_password" size="10" tabindex="0" value="Password" onfocus="if (this.value == 'Password') this.value = '';" onblur="if (this.value == '') this.value = 'Password';" />
<label for="cb_cookieuser_navbar"><input type="checkbox" name="cookieuser" value="1" tabindex="0" id="cb_cookieuser_navbar" accesskey="c" />Remember Me?</label>
<input type="submit" class="button" value="Log in" tabindex="0" title="Enter your username and password in the boxes provided to login, or click the 'register' button to create a profile for yourself." accesskey="s" />
<input type="hidden" name="s" value="f4cde1e552e96a9a2b4c4479559e6510" />
<input type="hidden" name="securitytoken" value="guest" />
<input type="hidden" name="do" value="login" />
<input type="hidden" name="vb_login_md5password" />
<input type="hidden" name="vb_login_md5password_utf" />
</form>
</li>
在这一点上,我认为阻止我的是 1) 语法,因为我显然是新手,2) cookie 没有被正确处理或 3) securitytoken/sid 没有被正确处理,但我达到我可以看到我的错误但不知道克服它们的方法的地步。任何帮助或见解都将非常有帮助!
第二部分:
这将允许我访问网站上的一个页面,特别是“工作表”页面,并打印出在那里找到的所有字符表的列表。它还将能够检索存储在找到字符名称的 table 行中的 JSON 文件。
您应该使用 requests.Session()
发出第一个请求以获取 cookie,并在您发出 post /login.php 时将它们发回。此外,您可以使用 beautifulsoup 获取登录表单中的所有输入 name/value,因此您只需添加 username/password(这样您就不会对 username/password 以外的任何内容进行硬编码)
密码是md5散列的,所以你可以使用hashlib
到encode it
以下进行登录调用:
import requests
from bs4 import BeautifulSoup
import hashlib
url = "https://www.myth-weavers.com"
username = "Testbug Jones"
password = "TeStBuG"
s = requests.Session()
r = s.get(url)
soup = BeautifulSoup(r.text, "html.parser")
form = soup.find("form",{"id":"login_form"})
payload = dict([(t.get("name"),t.get("value",""))
for t in form.findAll("input")
if t.get("name")
])
md5 = hashlib.md5(password.encode('utf-8')).hexdigest()
payload["vb_login_username"] = username
payload["vb_login_password"] = password
payload["vb_login_md5password"] = md5
payload["vb_login_md5password_utf"] = md5
r = s.post(f"{url}/login.php",
params= {"do": "login"},
data = payload
)
然后,您可以使用 s.get(".....")
来获取工作表数据,如下所示:
r = s.get(f"{url}/sheets")
soup = BeautifulSoup(r.text, "html.parser")
rows = soup.find("table").find_all("tr")[1:]
sheet_data = []
for row in rows:
tds = row.find_all("td")
download_link = f'{url}{tds[5].find("a")["href"]}'
json = s.get(download_link)
sheet_data.append({
"name": tds[1].text.strip(),
"template": tds[2].text.strip(),
"game": tds[3].text.strip(),
"download_link": download_link,
"json": json.json()
})
print(sheet_data)
这个项目的要点很简单,但是如果有人觉得自己有什么可以补充的,我们将不胜感激。
目的:该应用程序的目的是在 Myth-Weavers (https://www.myth-weavers.com/) 和 return 上创建的所有龙与地下城 sheet 上输入一个帐户帐户。这个
该应用程序还应该能够直接 link (https://www.myth-weavers.com/sheet.html#id=2311944)。这在理论上是可行的,因为您无需登录 Myth-Weavers 即可访问 link 和关联的 sheet。
第一部分: 我需要能够让应用程序进入站点并使用我的登录凭据进入我的帐户。当我登录该站点时,网络上会发送以下表单数据:
vb_login_username: Testbug Jones
vb_login_password:
s:
securitytoken: guest
do: login
vb_login_md5password: fea5ff2cf4764d2e76ea81e68bb458d1
vb_login_md5password_utf: fea5ff2cf4764d2e76ea81e68bb458d1
我正在使用以下代码通过登录检查我的进度:
import requests
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/85.0.4183.121 Safari/537.36'
}
login_data = {
's' : '',
'securitytoken' : 'guest',
'vb_login_username' : 'Testbug Jones',
'vb_login_password' : 'TeStBuG',
'redirect' : 'index.php',
'login' : 'Login',
'vb_login_md5password' : 'fea5ff2cf4764d2e76ea81e68bb458d1',
'vb_login_md5password_utf' : 'fea5ff2cf4764d2e76ea81e68bb458d1'
}
#get page
url = 'https://www.myth-weavers.com/'
source = requests.get(url)
#isolates login form, along with an sid
print('\n\n***CURRENT LOGIN STATUS***')
login_status = source.text
login_status = login_status.split("<!-- login form -->")[1]
login_status = login_status.split("<!-- / login form -->")[0]
print(login_status)
#nab sid and update library
sid = login_status.split('<input type="hidden" name="s" value="')[1]
sid = sid.split('" /')[0]
login_data['s'] = sid
#create session and attempt to log in
with requests.Session() as s:
print('\n\n***ATTEMPTING TO LOGIN***')
r = s.post(url, data = login_data, headers = headers)
login_status = r.text
login_status = login_status.split("<!-- login form -->")[1]
login_status = login_status.split("<!-- / login form -->")[0]
print(login_status)
至于登录表单本身,它通常看起来像:
<li class="smallfont" id="login" style="width: auto; float: right; text-align: right; padding-right: 6px;">
<span id="login_register"><a href="#" onclick="fetch_object('login_register').style.display = 'none'; fetch_object('login_form').style.display = ''; return false;" tabindex="0">Log In</a> / <a href="https://www.myth-weavers.com/register.php?s=f4cde1e552e96a9a2b4c4479559e6510">Register</a> <a href="//www.myth-weavers.com/login.php?do=lostpw" style="font-size:smaller">forgot password?</a></span>
<form id="login_form" style="display: none;" action="https://www.myth-weavers.com/login.php?do=login" method="post" onsubmit="md5hash(vb_login_password, vb_login_md5password, vb_login_md5password_utf, 0)">
<script type="text/javascript" src="//static.myth-weavers.com/clientscript/vbulletin_md5.js?v=388"></script>
<input type="text" class="bginput" style="font-size: 10px" name="vb_login_username" id="navbar_username" size="10" accesskey="u" tabindex="0" value="User Name" onfocus="if (this.value == 'User Name') this.value = '';" onblur="if (this.value == '') this.value = 'User Name';" />
<input type="password" class="bginput" style="font-size: 10px" name="vb_login_password" id="navbar_password" size="10" tabindex="0" value="Password" onfocus="if (this.value == 'Password') this.value = '';" onblur="if (this.value == '') this.value = 'Password';" />
<label for="cb_cookieuser_navbar"><input type="checkbox" name="cookieuser" value="1" tabindex="0" id="cb_cookieuser_navbar" accesskey="c" />Remember Me?</label>
<input type="submit" class="button" value="Log in" tabindex="0" title="Enter your username and password in the boxes provided to login, or click the 'register' button to create a profile for yourself." accesskey="s" />
<input type="hidden" name="s" value="f4cde1e552e96a9a2b4c4479559e6510" />
<input type="hidden" name="securitytoken" value="guest" />
<input type="hidden" name="do" value="login" />
<input type="hidden" name="vb_login_md5password" />
<input type="hidden" name="vb_login_md5password_utf" />
</form>
</li>
在这一点上,我认为阻止我的是 1) 语法,因为我显然是新手,2) cookie 没有被正确处理或 3) securitytoken/sid 没有被正确处理,但我达到我可以看到我的错误但不知道克服它们的方法的地步。任何帮助或见解都将非常有帮助!
第二部分: 这将允许我访问网站上的一个页面,特别是“工作表”页面,并打印出在那里找到的所有字符表的列表。它还将能够检索存储在找到字符名称的 table 行中的 JSON 文件。
您应该使用 requests.Session()
发出第一个请求以获取 cookie,并在您发出 post /login.php 时将它们发回。此外,您可以使用 beautifulsoup 获取登录表单中的所有输入 name/value,因此您只需添加 username/password(这样您就不会对 username/password 以外的任何内容进行硬编码)
密码是md5散列的,所以你可以使用hashlib
到encode it
以下进行登录调用:
import requests
from bs4 import BeautifulSoup
import hashlib
url = "https://www.myth-weavers.com"
username = "Testbug Jones"
password = "TeStBuG"
s = requests.Session()
r = s.get(url)
soup = BeautifulSoup(r.text, "html.parser")
form = soup.find("form",{"id":"login_form"})
payload = dict([(t.get("name"),t.get("value",""))
for t in form.findAll("input")
if t.get("name")
])
md5 = hashlib.md5(password.encode('utf-8')).hexdigest()
payload["vb_login_username"] = username
payload["vb_login_password"] = password
payload["vb_login_md5password"] = md5
payload["vb_login_md5password_utf"] = md5
r = s.post(f"{url}/login.php",
params= {"do": "login"},
data = payload
)
然后,您可以使用 s.get(".....")
来获取工作表数据,如下所示:
r = s.get(f"{url}/sheets")
soup = BeautifulSoup(r.text, "html.parser")
rows = soup.find("table").find_all("tr")[1:]
sheet_data = []
for row in rows:
tds = row.find_all("td")
download_link = f'{url}{tds[5].find("a")["href"]}'
json = s.get(download_link)
sheet_data.append({
"name": tds[1].text.strip(),
"template": tds[2].text.strip(),
"game": tds[3].text.strip(),
"download_link": download_link,
"json": json.json()
})
print(sheet_data)