我的 Python Flask网络应用存在问题。
我的代码在本地主机上正常运行,没有任何错误。 但是在我使用相同的代码和文件在Heroku上部署它后,当我在网络应用上执行搜索时,它给出了错误500 。
我已经尝试将 global 放在变量前面,但是仍然失败。我不知道这样做的正确方法。
https://unifit-web-app.herokuapp.com/
日志在heroku应用中:
[2019-06-28 08:09:43,471] ERROR in app: Exception on /result [POST]
Traceback (most recent call last):
File "/app/.heroku/python/lib/python3.7/site-packages/flask/app.py", line 2292, in wsgi_app
response = self.full_dispatch_request()
File "/app/.heroku/python/lib/python3.7/site-packages/flask/app.py", line 1815, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/app/.heroku/python/lib/python3.7/site-packages/flask/app.py", line 1718, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/app/.heroku/python/lib/python3.7/site-packages/flask/_compat.py", line 35, in reraise
raise value
File "/app/.heroku/python/lib/python3.7/site-packages/flask/app.py", line 1813, in full_dispatch_request
rv = self.dispatch_request()
File "/app/.heroku/python/lib/python3.7/site-packages/flask/app.py", line 1799, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/app/unifit.py", line 16, in result
results = extract(query)
File "/app/unifit.py", line 86, in extract
lazada = data['itemListElement']
UnboundLocalError: local variable 'data' referenced before assignment
10.13.226.47 - - [28/Jun/2019:08:09:43 +0000] "POST /result HTTP/1.1" 500 291 "https://unifit-web-app.herokuapp.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36"
这是我的网络应用程序的完整代码,不包括模板文件unifit.py:
from flask import Flask, render_template, flash, redirect, url_for, session, request, logging, jsonify
from flaskext.mysql import MySQL
from wtforms import Form, StringField, TextAreaField, PasswordField, validators
from passlib.hash import sha256_crypt
from functools import wraps
import requests
import json
from bs4 import BeautifulSoup as soup
app = Flask(__name__)
# Results
@app.route('/result', methods=['GET', 'POST'])
def result():
query = request.form['keyword']
results = extract(query)
return jsonify(results)
class Products(object):
def __init__(self, name=None, price=None, image=None, url=None, origin=None):
self.name = name
self.price = price
self.image = image
self.url = url
self.origin = origin
# Extract
@app.route('/extract', methods=['GET', 'POST'])
def extract(keyword):
global link
if request.method == 'POST':
x = {}
x['items'] = []
# Shopee Starts Here
l1 = []
url = "https://shopee.com.my/api/v2/search_items/"
querystring = {"by":"relevancy","keyword":keyword,"limit":"20","locations":"-1","match_id":"174","newest":"0","order":"desc","page_type":"search","rating_filter":"4"}
payload = ""
headers = {
'accept-language': "en-US,en;q=0.9",
'accept-encoding': "gzip, deflate, br",
'accept': "*/*",
'x-api-source': "pc",
'user-agent': "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36",
'if-none-match-': "55b03-e2b4b3f247507f7c1a18fda4a09f1340",
'x-requested-with': "XMLHttpRequest",
'connection': "keep-alive",
'host': "shopee.com.my"
}
response = requests.request("GET", url, data=payload, headers=headers, params=querystring)
json_data = json.loads(response.text)
results = json_data["items"]
for item in results:
name = item["name"]
price = float(item["price"])/100000
imagex = item["image"]
image = "https://cf.shopee.com.my/file/" + imagex
shopid = item["shopid"]
itemid = item["itemid"]
url = "https://shopee.com.my/"+name+"-i."+str(shopid)+"."+str(itemid)
origin = "Shopee"
l1.append(Products(name, float(price), image, url, origin))
# Shopee Ends Here
# Lazada Starts Here
l2 = []
page_link = 'https://www.lazada.com.my/catalog/?_keyori=ss&from=input&page=1&q='+keyword+'&sort=priceasc'
page_response = requests.get(page_link, timeout=5)
page_content = soup(page_response.text, "html.parser")
json_tags = page_content.find_all('script',{'type':'application/ld+json'})
for jtag in json_tags:
json_text = jtag.get_text()
data = json.loads(json_text)
lazada = data['itemListElement']
for item in lazada:
name = item["name"]
image = item["image"]
price = item["offers"]["price"]
url = item["url"]
origin = "Lazada"
l2.append(Products(name, float(price), image, url, origin))
# Lazada Stops Here
# Lelong Starts Here
l3 = []
url = "https://www.lelong.com.my/catalog/all/list?TheKeyword="+keyword+"&CategoryID=51"
payload = ""
headers = {
'accept-language': "en-US,en;q=0.9",
'accept-encoding': "gzip, deflate, br",
'accept': "*/*",
'x-api-source': "pc",
'user-agent': "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36",
'if-none-match-': "55b03-e2b4b3f247507f7c1a18fda4a0f91340",
'x-requested-with': "XMLHttpRequest",
'connection': "keep-alive",
}
response = requests.request("GET", url, data=payload, headers=headers)
#print(response.text)
page_content = soup(response.text, "html.parser")
json_tags = page_content.find_all('script',{'type':'application/ld+json'})
for jtag in json_tags:
json_text = jtag.get_text()
json_dict = json.loads(json_text)
lelong = json_dict['itemListElement']
for item in lelong:
name = item["name"]
image = item["image"]
price = item["offers"]["price"].replace(',', '')
url = item["url"]
origin = "Lelong"
l3.append(Products(name, float(price), image, url, origin))
# Lelong Stops Here
# Combine result
mergelist = l1+l2+l3
import operator
mergelist.sort(key=operator.attrgetter('price'))
# Tukar dari list ke json
for elem in mergelist:
x['items'].append({
'name': elem.name,
'price': float(elem.price),
'image': elem.image,
'url': elem.url,
'origin': elem.origin
})
#print(json.dumps(x, indent=2))
mergelist = json.dumps(x, indent=2)
return mergelist
# Main
@app.route('/')
def index():
return render_template('main.html')
# Main
if __name__ == '__main__':
app.run(debug=True)
谢谢。
答案 0 :(得分:1)
未创建数据。可能是因为json_tags
为空。记录page_response.text
的结果,并检查其看起来是否应该正确。
page_link = 'https://www.lazada.com.my/catalog/?_keyori=ss&from=input&page=1&q='+keyword+'&sort=priceasc'
page_response = requests.get(page_link, timeout=5)
page_content = soup(page_response.text, "html.parser")
答案 1 :(得分:1)
您正在for jtag in json_tags
循环中创建数据列表/字典,并且您正在尝试访问其外部的data []!不知道是否声明了全局数据[],因为在您发布的代码中看不到该数据。
编辑:我看到了您的网页,并且看起来工作正常!您是否已解决问题或仍在挣扎?
答案 2 :(得分:0)
更新
我通过将这三个部分置于if else条件下解决了这个问题。
下面是我系统的新完整代码。
但是lazada阻止了来自heroku的ip的问题,因此系统仅显示shopee和lelong的结果。
这是新链接:https://unifit-web-app.herokuapp.com/
就这样。谢谢!
from flask import Flask, render_template, flash, redirect, url_for, session, request, logging, jsonify
from flaskext.mysql import MySQL
from wtforms import Form, StringField, TextAreaField, PasswordField, validators
from passlib.hash import sha256_crypt
from functools import wraps
import requests
import json
from bs4 import BeautifulSoup as soup
app = Flask(__name__)
# Results
@app.route('/result', methods=['GET', 'POST'])
def result():
query = request.form['keyword']
results = extract(query)
return jsonify(results)
class Products(object):
def __init__(self, name=None, price=None, image=None, url=None, origin=None):
self.name = name
self.price = price
self.image = image
self.url = url
self.origin = origin
# Extract
@app.route('/extract', methods=['GET', 'POST'])
def extract(keyword):
if request.method == 'POST' or request.method == 'GET':
x = {}
x['items'] = []
# Shopee Starts Here
l1 = []
url = "https://shopee.com.my/api/v2/search_items/"
querystring = {"by":"relevancy","keyword":keyword,"limit":"20","locations":"-1","match_id":"174","newest":"0","order":"desc","page_type":"search","rating_filter":"4"}
payload = ""
headers = {
'accept-language': "en-US,en;q=0.9",
'accept-encoding': "gzip, deflate, br",
'accept': "*/*",
'x-api-source': "pc",
'user-agent': "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36",
'if-none-match-': "55b03-e2b4b3f247507f7c1a18fda4a09f1340",
'x-requested-with': "XMLHttpRequest",
'connection': "keep-alive",
'host': "shopee.com.my"
}
response = requests.request("GET", url, data=payload, headers=headers, params=querystring)
json_data = json.loads(response.text)
results = json_data["items"]
if results:
for item in results:
name = item["name"]
price = float(item["price"])/100000
imagex = item["image"]
image = "https://cf.shopee.com.my/file/" + imagex
shopid = item["shopid"]
itemid = item["itemid"]
url = "https://shopee.com.my/"+name+"-i."+str(shopid)+"."+str(itemid)
origin = "Shopee"
l1.append(Products(name, float(price), image, url, origin))
# Shopee Ends Here
# Lazada Starts Here
l2 = []
page_link = 'https://www.lazada.com.my/catalog/?_keyori=ss&from=input&page=1&q='+keyword+'&sort=priceasc'
# https://www.lazada.com.my/shop-computers-laptops/?q=arctis&from=input
page_response = requests.get(page_link)
page_content = soup(page_response.text, "html.parser")
json_tags = page_content.find_all('script',{'type':'application/ld+json'})
if json_tags:
for jtag in json_tags:
json_text = jtag.get_text()
data = json.loads(json_text)
lazada = data['itemListElement']
for item in lazada:
name = item["name"]
image = item["image"]
price = item["offers"]["price"]
url = item["url"]
origin = "Lazada"
l2.append(Products(name, float(price), image, url, origin))
# Lazada Stops Here
# Lelong Starts Here
l3 = []
url = "https://www.lelong.com.my/catalog/all/list?TheKeyword="+keyword+"&CategoryID=51"
payload = ""
headers = {
'accept-language': "en-US,en;q=0.9",
'accept-encoding': "gzip, deflate, br",
'accept': "*/*",
'x-api-source': "pc",
'user-agent': "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36",
'if-none-match-': "55b03-e2b4b3f247507f7c1a18fda4a0f91340",
'x-requested-with': "XMLHttpRequest",
'connection': "keep-alive",
}
response = requests.request("GET", url, data=payload, headers=headers)
page_content = soup(response.text, "html.parser")
json_tags = page_content.find_all('script',{'type':'application/ld+json'})
if json_tags:
for jtag in json_tags:
json_text = jtag.get_text()
json_dict = json.loads(json_text)
lelong = json_dict['itemListElement']
for item in lelong:
name = item["name"]
image = item["image"]
price = item["offers"]["price"].replace(',', '')
url = item["url"]
origin = "Lelong"
l3.append(Products(name, float(price), image, url, origin))
# Lelong Stops Here
# Combine result
mergelist = l1+l2+l3
import operator
mergelist.sort(key=operator.attrgetter('price'))
# Tukar dari list ke json
for elem in mergelist:
x['items'].append({
'name': elem.name,
'price': float(elem.price),
'image': elem.image,
'url': elem.url,
'origin': elem.origin
})
#print(json.dumps(x, indent=2))
mergelist = json.dumps(x, indent=2)
return mergelist
# Main
@app.route('/')
def index():
return render_template('main.html')
# Main
if __name__ == '__main__':
app.run(debug=True)