web-dev-qa-db-ja.com

BeautifulSoupから返されたJavaScriptを解析します

Webページを解析したい http://dcsd.nutrislice.com/menu/meadow-view/lunch/ 今日のランチメニューを取得します。 (Adafruit #IoTサーマルプリンターを構築し、毎日メニューを自動的に印刷したいと思います。)

私は最初にBeautifulSoupを使用してこれにアプローチしましたが、データのほとんどがJavaScriptでロードされ、BeautifulSoupがそれを処理できるかどうかわかりません。ソースを表示すると、bootstrapData['menuMonthWeeks']に保存されている関連データが表示されます。

import urllib2
from BeautifulSoup import BeautifulSoup

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

これは、ソースを取得してレビューする簡単な方法です。

私の質問は、このデータを使用して何かを実行できるように、このデータを抽出する最も簡単な方法は何ですか?文字通り、私が欲しいのは次のような文字列だけです:

南西チーズオムレツ、ポテトウェッジ、ザハーベストバー(THB)、THB-安っぽいペストパン、ハムデリサンドイッチ、レッドペッパースティック、イチゴ

Webkitを使用してページを処理し、HTML(つまり、ブラウザーが実行するもの)を取得することを考えましたが、それは不必要に複雑に思えます。むしろ、bootstrapData['menuMonthWeeks']データを解析できるものを見つけたいだけです。

16
Wade

PhantomJSのようなものはより堅牢かもしれませんが、基本的なPythonフルメニューを抽出するためのコード:

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

その後、メニューから興味のある日付を検索します。

[〜#〜] edit [〜#〜]:私の側でやり過ぎ:

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.'
10
smarx

必要なのは、小さな文字列のスライスです:

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はJavaScriptのサブセットです。

5
Martijn Pieters

これは約4年後ですが、nutrisliceには(少なくとも現在)直接のJSONを取得できるAPIがあります。数日前のお子様のランチ: http://dcsd.nutrislice.com/menu/api/digest/school/meadow-view/menu-type/lunch/date/2018/03/14/

1
chad

beautifulSoupがなければ、1つの簡単な方法があります。

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"]

出力:

2013-11-11T11:18:13.636

より一般的な方法については、 PythonのJavaScriptパーサー を参照してください。

1
Guy Gavriely

jsonをいじらずに、お好みであれば、これはお勧めできませんが、次を試すことができます:

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

これが最終的に必要なものだと思います:

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

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
0
alvas