У меня проблема с моим Python Flask Web App .

Мой код работает нормально, без ошибок на локальном хосте . Но после того, как я развернул его на Heroku с тем же кодом и файлами , он дал мне ошибку 500 при выполнении поиска в веб-приложении.

Я уже пытался поместить global перед переменными, но все равно не получается. Я не знал правильный способ сделать это.

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

На локальном хосте: localhost

По герою приложения: 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)

Спасибо.

-1
Firdhaus Saleh 28 Июн 2019 в 11:19

3 ответа

Лучший ответ

Вы создаете список данных / словарь в цикле for jtag in json_tags и пытаетесь получить доступ к данным [] вне его! Не уверен, что вы объявили глобальные данные [], потому что я не вижу этого в размещенном вами коде.

РЕДАКТИРОВАТЬ: Я видел вашу веб-страницу, и, кажется, работает нормально! Вы исправили свою проблему или все еще боретесь?

1
Ronnie 29 Июн 2019 в 22:11

Данные не создаются. Возможно, потому что 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
Wytamma Wirth 28 Июн 2019 в 08:31

< Сильный > UPDATE

Я решил проблему, просто поместив эти 3 части в условие if else.

Ниже приведен новый полный код моей системы.

Но есть проблема, когда lazada заблокировал ip от heroku, поэтому система показывает только результат shopee & lelong.

Вот новая ссылка: https://unifit-apps.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)
0
Firdhaus Saleh 11 Окт 2019 в 02:59