2014-01-11 18 views
11

Ich möchte die Webseite http://dcsd.nutrislice.com/menu/meadow-view/lunch/ parsen, um das heutige Mittagsmenü zu ergattern. (Ich habe einen Adafruit #IoT Thermodrucker gebaut und ich möchte das Menü jeden Tag automatisch drucken.)Parsen Sie das von BeautifulSoup zurückgegebene JavaScript

Ich ging anfänglich mit BeautifulSoup, aber es stellt sich heraus, dass die meisten Daten in JavaScript und ich geladen sind bin mir nicht sicher, ob BeautifulSoup damit umgehen kann. Wenn Sie die Quelle anzeigen, werden die relevanten Daten in bootstrapData['menuMonthWeeks'] angezeigt.

import urllib2 
from BeautifulSoup import BeautifulSoup 

url = "http://dcsd.nutrislice.com/menu/meadow-view/lunch/" 
soup = BeautifulSoup(urllib2.urlopen(url).read()) 

Dies ist ein einfacher Weg, um die Quelle und Überprüfung zu erhalten.

Meine Frage ist: Was ist der einfachste Weg, um diese Daten zu extrahieren, damit ich etwas damit machen kann? Buchstäblich alles, was ich will, ist eine Zeichenfolge so etwas wie:

Southwest Käse Omelette, Potato Wedges, The Harvest Bar (THB), THB - Cheesy Pesto Brot, Schinken Deli Sandwich, Red Pepper Sticks, Erdbeeren

Ich habe darüber nachgedacht, Webkit zu verwenden, um die Seite zu bearbeiten und HTML zu erhalten (dh was ein Browser tut), aber das scheint unnötig komplex zu sein. Ich würde eher etwas finden, das die bootstrapData['menuMonthWeeks'] Daten analysieren kann.

Antwort

10

So etwas wie PhantomJS kann robuster sein, aber hier ist einige grundlegende Python-Code es das vollständige Menü zu extrahieren:

import json 
import re 
import urllib2 

text = urllib2.urlopen('http://dcsd.nutrislice.com/menu/meadow-view/lunch/').read() 
menu = json.loads(re.search(r"bootstrapData\['menuMonthWeeks'\]\s*=\s*(.*);", text).group(1)) 

print menu 

Danach wollen Sie für das Datum durch das Menü suchen, du bist . Interesse an

EDIT: Einige Overkill meinerseits:

import itertools 
import json 
import re 
import urllib2 

text = urllib2.urlopen('http://dcsd.nutrislice.com/menu/meadow-view/lunch/').read() 
menus = json.loads(re.search(r"bootstrapData\['menuMonthWeeks'\]\s*=\s*(.*);", text).group(1)) 

days = itertools.chain.from_iterable(menu['days'] for menu in menus) 

day = next(itertools.dropwhile(lambda day: day['date'] != '2014-01-13', days), None) 

if day: 
    print '\n'.join(item['food']['description'] for item in day['menu_items']) 
else: 
    print 'Day not found.' 
4

Alles, was Sie brauchen, ist ein wenig String Slicing:

import json 

soup = BeautifulSoup(urllib2.urlopen(url).read()) 
script = soup.findAll('script')[1].string 
data = script.split("bootstrapData['menuMonthWeeks'] = ", 1)[-1].rsplit(';', 1)[0] 
data = json.loads(data) 

JSON ist schließlich eine Teilmenge von JavaScript.

+0

Sehr hilfreich! Benötigt ein paar mehr Importe und die URL definiert, aber letztlich funktioniert das auch gut um diesen Wert zu bekommen. – Wade

0

ohne BeautifulSoup, eine einfache Art und Weise können wir:

import urllib2 
import json 
url = "http://dcsd.nutrislice.com/menu/meadow-view/lunch/" 
for line in urllib2.urlopen(url): 
    if "bootstrapData['menuMonthWeeks']" in line: 
     data = json.loads(line.split("=")[1].strip('\n;')) 
     print data[0]["last_updated"] 

Ausgang:

2013-11-11T11:18:13.636 

, eine generische Art und Weise JavaScript parser in Python

0

Ohne mit json Messing sehen, wenn Sie es vorziehen, die Es wird nicht empfohlen, Sie können Folgendes versuchen:

import urllib2 
import re 

url = "http://dcsd.nutrislice.com/menu/meadow-view/lunch/" 
data = urllib2.urlopen(url).readlines()[60].partition('=')[2].strip() 

foodlist = [] 

prev = 'name' 
for i in re.findall('"([^"]*)"', data): 
    if "The Harvest Bar (THB)" in i or i == "description" or i == "start_date": 
     prev = i 
     continue 
    if prev == 'name': 
     if i.startswith("THB - "): 
      i = i[6:] 
     foodlist.append(i) 
    prev = i 

Ich denke, das ist, was Sie schließlich brauchen werden:

Orange Chicken Bowl 
Roasted Veggie Pesto Pizza 
Cheese Sandwich & Yogurt Tube 
Steamed Peas 
Peaches 
Southwest Cheese Omelet 
Potato Wedges 
Cheesy Pesto Bread 
Ham Deli Sandwich 
Red Pepper Sticks 
Strawberries 
Hamburger 
Cheeseburger 
Potato Wedges 
Chicken Minestrone Soup 
Veggie Deli Sandwich 
Baked Beans 
Green Beans 
Fruit Cocktail 
Cheese Pizza 
Pepperoni Pizza 
Diced Chicken w/ Cornbread 
Turkey Deli Sandwich 
Celery Sticks 
Blueberries 
Cowboy Mac 
BYO Asian Salad 
Sunbutter Sandwich 
Stir Fry Vegetables 
Pineapple Tidbits 
Enchilada Blanco 
Sausage & Black Olive Pizza 
Cheese Sandwich & Yogurt Tube 
Southwest Black Beans 
Red Pepper Sticks 
Applesauce 
BBQ Roasted Chicken. 
Hummus Cup w/ Pita bread 
Ham Deli Sandwich 
Mashed potatoes w/ gravy 
Celery Sticks 
Kiwi 
Popcorn Chicken Bowl 
Tuna Salad w/ Pita Bread 
Veggie Deli Sandwich 
Corn Niblets 
Blueberries 
Cheese Pizza 
Pepperoni Pizza 
BYO Chef Salad 
BYO Vegetarian Chef Salad 
Turkey Deli Sandwich 
Steamed Cauliflower 
Banana, Whole 
Bosco Sticks 
Chicken Egg Roll & Chow Mein Noodles 
Sunbutter Sandwich 
California Blend Vegetables 
Fresh Pears 
Baked Mac & Cheese 
Italian Dunker 
Ham Deli Sandwich 
Red Pepper Sticks 
Pineapple Tidbits 
Hamburger 
Cheeseburger 
Baked Fries 
BYO Taco Salad 
Veggie Deli Sandwich 
Baked Beans 
Coleslaw 
Fresh Grapes 
Cheese Pizza 
Pepperoni Pizza 
Diced Chicken w/ Cornbread 
Turkey Deli Sandwich 
Steamed Cauliflower 
Fruit Cocktail 
French Dip w/ Au Jus 
Baked Fries 
Turkey Noodle Soup 
Sunbutter Sandwich 
Green Beans 
Warm Cinnamon Apples 
Rotisserie Chicken 
Mashed potatoes w/ gravy 
Bacon Cheeseburger Pizza 
Cheese Sandwich & Yogurt Tube 
Steamed Peas 
Apple Wedges 
Turkey Chili 
Cornbread Muffins 
BYO Chef Salad 
BYO Vegetarian Chef Salad 
Ham Deli Sandwich 
Celery Sticks 
Fresh Pears 
Beef, Bean & Red Chili Burrito 
Popcorn Chicken & Breadstick 
Veggie Deli Sandwich 
California Blend Vegetables 
Strawberries 
Cheese Pizza 
Pepperoni Pizza 
Hummus Cup w/ Pita bread 
Turkey Deli Sandwich 
Green Beans 
Orange Wedges 
Bosco Sticks 
Cheesy Bean Soft Taco Roll Up 
Sunbutter Sandwich 
Pinto Bean Cup 
Baby Carrots 
Blueberries 

Mit json:

import urllib2 
import json 
url = "http://dcsd.nutrislice.com/menu/meadow-view/lunch/" 
for line in urllib2.urlopen(url): 
    if "bootstrapData['menuMonthWeeks']" in line: 
     data = json.loads(line.split("=")[1].strip('\n;')) 
     print data[0]["name"] 
    break 
Verwandte Themen