0

I am creating a Flask app that I want to use to display some scraped information. I have imported my scraping file into Flask, and for its scraping function, I have to pass a name to search as a parameter. I want to get this name from an input box in my HTML code. I am trying to accomplish this using an Ajax call in jQuery, but I am currently getting a 404 error.

I have tried outputting the raw json data, versus a python list. I have tried using two separate Ajax calls. I have also tried looking at another post that I was pointed to on here, but I have run into this said 404 error.

Flask app code

#Start the flask app
app = Flask(__name__)

#Start page
@app.route('/')
def index():
    return render_template('index.html')

#What happens when our button is clicked
@app.route('/_get_data')
def _get_data():
    #Get the name we want to search for
    searchName = request.args.get('searchName')
    #Call the function and pass our search name parameter
    dataList = scrape_data(searchName)

    #Return the json format of the data we scraped
    return jsonify(dataList = dataList)

#Run the app
if __name__ == "__main__":
    app.run(debug = True)

index.html code

<!DOCTYPE html>
<html lang = "en">
<head>
    <meta charset = "utf-8">

    <title>NBA Data Web App</title>
</head>

<body>
    <script src = "http://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js" crossorigin = "anonymous"></script>
    <script type = text/javascript src = "{{url_for('static', filename = 'jquery.js') }}"></script>
    <form id = "nameForm" role = "form">
        <input name = "text">
        <button id = "searchBtn"> Search </button>
    </form>

    <div id = "container"></div>

    <script type = text/javascript> $SCRIPT_ROOT = {{ request.script_root|tojson|safe }}; //Get the root of our data </script>
    <script type = "text/javascript">         

        //Root so we can get the data from our form
        $('button#searchBtn').click(function(e) {
            //Prevent our form from submitting
            e.preventDefault();
            //Get the root
            $.getJSON($SCRIPT_ROOT + '/_get_data', {
                //Our searchName variable will be the one from our HTML input box
                searchName: $('input[name = "text"]').val(),
            }, function(data) {
                    console.log(data.dataList);
            });
        });

    </script>

</body>
</html>

Again, to be clear, my goal is to take the data from my HTML input form once by searchBtn is clicked, and use this data as a string in my parameter to webscrape data. Then, once the scraped data is return, I am trying to log it to my console.py

Robert Smith
  • 673
  • 10
  • 25
  • For starters you need to prevent the default action of the button click which will submit the form and reload the page. – charlietfl Nov 03 '19 at 01:44
  • ok so now need more debugging detail on what does and what doesn't work. A 404 is clearly a path problem so for starters does `$SCRIPT_ROOT + '/_get_data'` give you a valid path? Really not enough known here and need to isolate if it is a front end or back end issue – charlietfl Nov 03 '19 at 01:55
  • @charlietfl what would be the easiest way to test that? – Robert Smith Nov 03 '19 at 01:57
  • `console.log($SCRIPT_ROOT + '/_get_data')`... should be able to then put that into address bar with a sample query string and see some json output. A more advanced look is to inspect the actual request in browser dev tools network and copy the url generated from there – charlietfl Nov 03 '19 at 01:58
  • @charlietfl I just did that. My problem is I was following another StackOverflow post to create this, so there is no ```'static'```. I'm not sure what I do need the url for in the box at the top however. Maybe my index page? – Robert Smith Nov 03 '19 at 02:01
  • @charlietfl the error I get is 2%7B%7Burl_for('static',%20filename%20=%20'jquery.js')%20%7D%7D:1 Failed to load resource: the server responded with a status of 404 (Not Found), and also another error for unexpected '{' in the definition of ```$SCRIPT_ROOT``` – Robert Smith Nov 03 '19 at 02:02
  • So look at the generated source code for that script tag. Is it valid? – charlietfl Nov 03 '19 at 02:13
  • @charlietfl I’m not sure. I’m new to jQuery/Ajax. Do I need to replace script_root with the name of my python file? – Robert Smith Nov 03 '19 at 02:16
  • `$SCRIPT_ROOT` is a javascript variable that needs to be a valid url string. Just realizing you likely need quotes around the `{{ }}` (note I'm not a python dev) but the `{{}}` produced string needs to be quoted for javascript so it ends up looking like `$SCRIPT_ROOT = '/path/to/server';` – charlietfl Nov 03 '19 at 02:20
  • @charlietfl no worries, any help is appreciated. I'm not sure that's the problem, I am referencing this post https://stackoverflow.com/questions/52870184/get-data-from-html-and-do-some-operation-on-it-and-pass-the-data-back-to-the-f/52883461#52883461 – Robert Smith Nov 03 '19 at 02:21

1 Answers1

0

After re-reading some Flask documentation, here is my working code. The biggest change I had to make, however, was downloading the jQuery file itself and putting it in my working directory in a folder named 'static' so that my index.html could load it properly.

Here is my working code

Flask app code


#Import our external web scraping file
from scrape import *

#Flask dependencies
from flask import Flask, render_template, jsonify, request, escape, url_for

#Get our lists to post
headers = data_headers()

#Start the flask app
app = Flask(__name__)

#Start page
@app.route('/')
def index():
    return render_template('index.html')

#What happens when our button is clicked
@app.route('/_get_data')
def _get_data():
    #Get the name we want to search for
    searchName = request.args.get('searchName')
    #Call the function and pass our search name parameter
    dataList = scrape_data(searchName)

    #Return the json format of the data we scraped
    return jsonify(dataList = dataList)

#Run the app
if __name__ == "__main__":
    app.run(debug = True)

index.html code

<!DOCTYPE html>
<html lang = "en">
<head>
    <meta charset = "utf-8">

    <title>NBA Data Web App</title>
</head>

<body>
    <script src = "http://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js" crossorigin = "anonymous"></script>
    <script type = text/javascript src = "{{
        url_for('static', filename = 'jquery.js') }}"></script>
    <form id = "nameForm" role = "form">
        <input name = "text">
        <button id = "searchBtn"> Search </button>
    </form>

    <div id = "container"></div>

    <script type = text/javascript> 
    //Root stuff
    $SCRIPT_ROOT = {{ request.script_root|tojson|safe }};

        //Root so we can get the data from our form
        $('button#searchBtn').click(function(e) {
            //Prevent our form from submitting, which is its default action/purpose
            e.preventDefault();
            //Get the data from our function in the Flask App
            $.getJSON($SCRIPT_ROOT + '/_get_data', {
                //Our searchName variable will be the one from our HTML input box
                searchName: $('input[name = "text"]').val(),
            }, function(data) {
                //Rename the variable so I can reuse some code 
                data_list = data.dataList;

                //HTML table variables
                var perRow = 1, count = 0, table = document.createElement("table"),
                row = table.insertRow();

                //Loop through the data and get each piece
                for (var i of data_list) {
                    //Create a cell for each piece of data
                    var cell = row.insertCell();
                    //Then actually add the data to the cell
                    cell.innerHTML = i;

                    //Increment our count variable so we can decide when to start a new row
                    count++;
                    if (count % perRow == 0) {
                        //If we have reached our set limit of items per row, start a new row
                        row = table.insertRow();
                    }
                }
                //Attach the table to the HTML doc when finished
                document.getElementById("container").appendChild(table);
            });
        }); 

    </script>

</body>
</html>
Robert Smith
  • 673
  • 10
  • 25