python - 重置 Flask render_template 输出
问题描述
我目前正在为 Battlefy 网站制作解析器,以快速提取结果并将其转换为 wikicode。
网站:http ://tomshoe02.pythonanywhere.com/scraper
实际操作示例:https ://i.imgur.com/1lj98cP.png
要解析的示例链接:https ://dtmwra1jsgyb0.cloudfront.net/stages/6000c862d9155d46db7f41ca/rounds/1/matches
完整的 app.py:https://pastebin.com/J2nsfmFa
app.py 代码片段:
@app.route("/", methods=["GET", "POST"])
@app.route("/lol", methods=["GET", "POST"])
@app.route("/scraper", methods=["GET", "POST"])
def scraper():
form = BattlefyForm()
if form.validate_on_submit():
url = form.matchhistory.data
result = jloader(url)
'''
#result = url
result = subprocess.check_output([sys.executable,
"{}/stuff.py".format(directory), url]).decode('iso-8859-1')
'''
return render_template("scraper.html", form=form, result=result)
return render_template("scraper.html", form=form)
每次我在不重新加载 Web 应用程序的情况下提交时,新结果都会显示在旧结果中。是否有一个模块可以用来清除会话缓存并重置网站的状态,而无需在每次提交要解析的新 URL 时完全重新加载应用程序?
解决方案
I disagree with Akib. It doesn't matter whether a redirect is carried out after the form data has been received or the entire page is re-rendered and sent as a response from the server.
After each call, regardless of whether via POST or GET request, the entire page is reloaded and rendered. This could be reduced using ajax. However, this does not cause your issue.
The problem is not within your route, but within your stuff.py
module.
You use global variables to save the results extracted from the loaded JSON files in lists.
The first solution would be to empty these lists every time
jloader(url)
is called. But that doesn't completely solve the problem.
If several users start calls at the same time, this would lead to unexpectedly incorrect results. Since the previous request could not be completed if the list were emptied again and filled with further results.
In addition, global variables should be avoided as long as they are not absolutely necessary.
Because of the reasons listed, I advise you not to use the global variables and
to keep the lists as local variables within the function, which are kept for each
request and are returned at the end.
This is an approach how you could make your code clearer and do without global variables. I have only rewritten excerpts of your code. I think you can add the rest yourself.
import requests
from collections import namedtuple
from datetime import datetime
import gspread
class Match(namedtuple('Match', ['team_a', 'team_b', 'score_a', 'score_b'])):
@property
def winner(self):
if self.score_a > self.score_b:
return self.team_a
elif self.score_a < self.score_b:
return self.team_b
return None
def fmt(self):
return '{{'\
f'MatchSchedule|team1={self.team_a}|team2={self.team_b}'\
f'|team1score={self.score_a}|team2score={self.score_b}'\
f'|winner={self.winner}|date=...|time=...|timezone=PST|'\
'dst=yes|vod1=|stream='\
'}}'
def _get(data, key_path, default=None):
tmp = data
for k in key_path.split('.'):
try:
tmp = tmp[k]
except KeyError:
return default
return tmp
def get_matches(url, team_alias={}):
data = requests.get(url).json()
for item in data:
top_team = _get(item, 'top.name', _get(item, 'top.team.name'))
low_team = _get(item, 'bottom.name', _get(item, 'bottom.team.name'))
top_score = _get(item, 'top.score')
low_score = _get(item, 'bottom.score')
# Test for results that are None and react accordingly.
# The date and time queries are missing here.
top_team = team_alias.get(top_team, top_team)
low_team = team_alias.get(low_team, low_team)
match = Match(top_team, low_team, top_score, low_score)
yield(match)
def get_teams():
gc = gspread.service_account(filename='credentials.json')
sh = gc.open_by_key('1N7wnIRWJRbULKychJU-EOyisuZBX1rgXwdW91Keki4M')
col_name = worksheet.col_values(1)
col_alias = worksheet.col_values(2)
return dict(zip(col_name, col_alias))
def load_data(url):
'''Use this instead of jloader(url).'''
team_alias = get_teams()
return '\n'.join(match.fmt() for match in get_matches(url, team_alias))
def main():
url = 'https://dtmwra1jsgyb0.cloudfront.net/groups/5f60cffb30d29b119e36b42b/matches'
dat = load_data(url)
print(dat)
if __name__ == '__main__':
main()
``
推荐阅读
- java - Thymeleaf 客户端验证
- angular - 一个组件中的多个服务
- apache-spark - 如何在没有 Hadoop 的情况下让 Spark 在 Windows 10 上运行?
- networking - 在 ifcfg-eth0 中设置静态 ip 后 GCP 上的虚拟机丢失网络
- c++ - 实现所有虚方法,但只改变其中的一部分
- angular - 使用管道和地图对 Angular HttpClient 帖子的响应运行逻辑
- java - 膨胀类 android.support.v7.widget_Toolbar 时出错
- vba - VBA 从类中调用类属性
- javascript - Treeview 在 angularjs 中效果不佳
- android - ARCore – SFA 文件格式的参数