2

I'm wondering if it's possible to run the script below from or inside an AppleScript App.

The idea behind all this, is that people would not need to run and deal with the code, say they won't need to run it from SublimeText or so, instead just click an app and let the script run and to the job. If that make sens to you ?

from bs4 import BeautifulSoup
import requests
import csv

class_1 = {"class": "productsPicture"}
class_2 = {"class": "product_content"}
class_3 = {"class": "id-fix"}

# map a column number to the required find parameters
class_to_find = {
0 : class_3,    # Not defined in question
1 : class_1,    
2 : class_1,
3 : class_3,    # Not defined in question
4 : class_2, 
5 : class_2}

with open('urls.csv', 'r') as csvFile, open('results.csv', 'w', newline='') as results:
reader = csv.reader(csvFile)
writer = csv.writer(results)

for row in reader:
    # get the url

    output_row = []

    for index, url in enumerate(row):
        url = url.strip()

        # Skip any empty URLs
        if len(url):
            #print('col: {}\nurl: {}\nclass: {}\n\n'.format(index, url, class_to_find[index]))

            # fetch content from server

            try:
                html = requests.get(url).content
            except requests.exceptions.ConnectionError as e:
                output_row.extend([url, '', 'bad url'])
                continue
            except requests.exceptions.MissingSchema as e:
                output_row.extend([url, '', 'missing http...'])
                continue

            # soup fetched content
            soup = BeautifulSoup(html, 'html.parser')


            divTag = soup.find("div", class_to_find[index])

            if divTag:
                # Return all 'a' tags that contain an href
                for a in divTag.find_all("a", href=True):
                    url_sub = a['href']

                    # Test that link is valid
                    try:
                        r = requests.get(url_sub)
                        output_row.extend([url, url_sub, 'ok'])
                    except requests.exceptions.ConnectionError as e:
                        output_row.extend([url, url_sub, 'bad link'])
            else:
                output_row.extend([url, '', 'no results'])      

    writer.writerow(output_row)
9
  • How do you currently invoke the python script? Do you run something similar to: python path/to/the/python-script.py via your CLI tool ? Commented May 30, 2018 at 7:22
  • @RobC I'm just running it from SublimeText app, It does the job, but there's all this code which regular people don't need to be seeing it. Make sens ? Commented May 30, 2018 at 7:40
  • 1
    Does it also run successfully if you 1. Open "Terminal" application on macOS and 2. Type python path/to/the/python-script.py and hit the return key? (The path/to/the/python-script.py part should be the replaced with the actual path to the .py file) Commented May 30, 2018 at 7:45
  • 1
    If you're unsure how to obtain the path to the file you can: 1. Open a new Terminal window. 2. Type python (with trailing space). 3. Drag and drop the .py file from the Finder into the Terminal window - the actual path to the file will be auto added to the Terminal window. 4. Then type return to run it..... If that works then the answer provided in my last comment should work for running via AppleScript too. Commented May 30, 2018 at 8:09
  • 1
    If trying the method in my last comment works successfully, (i.e. running it via the Terminal) then let me know what the path part is and I'll provide a formal answer for running via AppleScript for you if you'd like me to. Just let me know. Commented May 30, 2018 at 8:19

1 Answer 1

4
  1. Open AppleScript Editor on macOS.

  2. In a new window add the following two lines of code:

    set desktop_folder to "$HOME/Desktop"
    do shell script "python " & desktop_folder & "/Pricematch/foo.py"
    

    Note: This assumes the foo.py file is saved to a folder named Pricemacth which exists in the users Desktop folder. You'll need to replace the foo.py part with the actual real filename.

    Because the desktop_folder variable is set to "$HOME/Desktop" you should be able to roll this out to multiple users without any issues. You just need to make sure the folder named Pricematch is located in their Desktop folder and it contains the .py file to be run. The $HOME part will automatically assume the User folder, so you won't need to specify different usernames for each user.

    If you decide to change the location of .py you'll need to update the path in the AppleScript accordingly.

  3. To save the AppleScript:

    • select File > Save As from the menu bar.
    • Choose File Format > Application
    • Enter a filename. E.g. run-python-script.app
    • Click Save button. (it can be saved in any folder location)
  4. Double click run-python-script.app in the Finder to run it.


EDIT

In response to the comment:

is it possible to somehow get a notification when python script finished he's job.

Here's a couple of suggestions - it assumes the python script returns a zero/success exit status. You could try changing line two in the AppleScript to:

  1. For displaying a dialog message:

    do shell script "python " & desktop_folder & "/Pricematch/foo.py && osascript -e 'tell application \"Finder\" to activate' -e 'tell application \"Finder\" to display dialog \"Finished Python Script\"'"
    
  2. Or, for speaking something:

    do shell script "python " & desktop_folder & "/Pricematch/foo.py && osascript -e 'set Volume 4' -e 'tell application \"Finder\" to say \"Finished!\"' -e 'set Volume 0'"
    
Sign up to request clarification or add additional context in comments.

8 Comments

almost there ! I got this error when running the app Traceback (most recent call last): File "/Users/imaging-adrian/Desktop/Pricematch/PriceMatcher.py", line 29, in <module> with open('/Users/imaging-adrian/Desktop/Pricematch/urls.csv', 'r') as csvFile, open('results.csv', 'w', newline='') as results: TypeError: 'newline' is an invalid keyword argument for this function this is how the line 29 is looking right now with open('/Users/imaging-adrian/Desktop/Pricematch/urls.csv', 'r') as csvFile, open('results.csv', 'w', newline='') as results:
it worked fine in Terminal, printed what I was expected. The lineterminator='\n' got me this : Traceback (most recent call last): File "/Users/imaging-adrian/Desktop/Pricematch/PriceMatcher.py", line 29, in <module> with open('/Users/imaging-adrian/Desktop/Pricematch/urls.csv', 'r') as csvFile, open('results.csv', 'w', lineterminator='\n') as results: TypeError: 'lineterminator' is an invalid keyword argument for this function (1)
Ok, try the following: 1 Revert .py file to to original code. 2 In Terminal type which python and take note of the path returned (should be something like this: /usr/bin/python) 3. Change line two in the AppleScript to do shell script "/usr/bin/python " & desktop_folder & "/Pricematch/foo.py" - Note the addition of /usr/bin/python instead of just do shell script "python " & ...- this part should be the same as the value returned from running the which python command.
Also worth trying to set line 2 of the AppleScript to: do shell script "/usr/bin/env python " & desktop_folder & "/Pricematch/foo.py"
you're so close ! I got an error saying this : Traceback (most recent call last): File "/Users/imaging-adrian/Desktop/Pricematch/PriceMatcher.py", line 29, in <module> with open('/Users/imaging-adrian/Desktop/Pricematch/urls.csv', 'r') as csvFile, open('results.csv', 'w', newline='') as results: PermissionError: [Errno 13] Permission denied: 'results.csv' (1) basically we need to allow it to save that file, right ?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.