Flask Web应用程序无法在Heroku上运行,但可以在localhost上正常运行

时间:2019-06-28 08:19:25

标签: python heroku flask

我的 Python Flask网络应用存在问题。

我的代码在本地主机上正常运行,没有任何错误。 但是在我使用相同的代码和文件在Heroku上部署它后,当我在网络应用上执行搜索时,它给出了错误500

我已经尝试将 global 放在变量前面,但是仍然失败。我不知道这样做的正确方法。

https://unifit-web-app.herokuapp.com/

在localhost上: localhost

在heroku应用上: heroku

日志在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)

谢谢。

3 个答案:

答案 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)