2013-09-26 25 views
20

içindeki verileri notlama, bir web sitesindeki kazıyıcının verilerini görüntülemek için scrapy kullanıyorum. Ancak, istediğim veriler html'nin içinde değildi, bunun yerine javascript'ten geliyor. Yani, benim sorum:Bir Javascript

Bu gibi durumların değerleri (metin değerleri) nasıl alınır? Ben almaya çalışıyorum https://www.mcdonalds.com.sg/locate-us/

Nitelikler: Adres, İletişim, İşletme saatleri

Bu, ben ekran kazımaya çalışıyorum sitesidir.

"Sağ tıklama" yaparsanız, bir krom tarayıcının içinde "kaynağı görüntüle" yaparsanız, bu değerlerin HTML'de mevcut olmadığını görürsünüz.


Düzenleme

Sry paul, sana şimdi gerçekten sıkışıp kaldım, bana admin-ajax.php bulundu ve vücudu gördüm ama olanı yaptı.

Değerleri json nesnesinden nasıl alıp kendi değişken alanımdaki bir alana depolarım? Halk için sadece bir öznitelik ve sadece terapi yapmaya yeni başlayanları nasıl paylaşacağınızı paylaşırsanız iyi olur. İşte benim kod kısacası bu yüzden, nasıl saklamak yapmak, uzun düzenlemek için bugüne kadar

Items.py

class McDonaldsItem(Item): 
name = Field() 
address = Field() 
postal = Field() 
hours = Field() 

McDonalds.py

from scrapy.spider import BaseSpider 
from scrapy.selector import HtmlXPathSelector 
import re 

from fastfood.items import McDonaldsItem 

class McDonaldSpider(BaseSpider): 
name = "mcdonalds" 
allowed_domains = ["mcdonalds.com.sg"] 
start_urls = ["https://www.mcdonalds.com.sg/locate-us/"] 

def parse_json(self, response): 

    js = json.loads(response.body) 
    pprint.pprint(js) 

Sry var

json değeri benim özümüme mi? eg

*** madde [ 'adresi'] = * nasıl alınacağını ****

PS, emin değilim bu ama yardımcı olur, ben kullanarak cmd hattında bu komut dosyalarını çalıştırmak

scrub taraması mcdonalds -o McDonalds.json -t json (tüm verilerimi bir json dosyasına kaydetmek için)

Ne kadar minnettar olduğum hakkında yeterince stres yapıyorum. Bunu sormak mantıksız bir şey biliyorum, bunun için zamanınız olmasa bile tamam olacak.

cevap

18

(Ben scrapy-users posta listesine bu yayınlanmıştır ama shell komut etkileşimi ile cevap tamamlar olarak Pavlus'un öneri ile ben burada post ediyorum.) Genellikle

, bir üçüncü taraf hizmeti kullanmak web siteleri bazı veri görselleştirme işlemek için (harita, tablo vb.) verileri bir şekilde göndermelidir ve çoğu durumda bu verilere tarayıcıdan erişilebilir. Bu durum için

, bir teftiş (yani tarayıcı tarafından yapılan istekleri keşfetmek) temelde güzel bir istediğiniz tüm verileri orada var, veri https://www.mcdonalds.com.sg/wp-admin/admin-ajax.php Yani

için bir POST isteğinden yüklenir göstermektedir json formatı tüketime hazır. Kısacası

$ scrapy shell https://www.mcdonalds.com.sg/locate-us/ 
2013-09-27 00:44:14-0400 [scrapy] INFO: Scrapy 0.16.5 started (bot: scrapybot) 
... 

In [1]: from scrapy.http import FormRequest 

In [2]: url = 'https://www.mcdonalds.com.sg/wp-admin/admin-ajax.php' 

In [3]: payload = {'action': 'ws_search_store_location', 'store_name':'0', 'store_area':'0', 'store_type':'0'} 

In [4]: req = FormRequest(url, formdata=payload) 

In [5]: fetch(req) 
2013-09-27 00:45:13-0400 [default] DEBUG: Crawled (200) <POST https://www.mcdonalds.com.sg/wp-admin/admin-ajax.php> (referer: None) 
... 

In [6]: import json 

In [7]: data = json.loads(response.body) 

In [8]: len(data['stores']['listing']) 
Out[8]: 127 

In [9]: data['stores']['listing'][0] 
Out[9]: 
{u'address': u'678A Woodlands Avenue 6<br/>#01-05<br/>Singapore 731678', 
u'city': u'Singapore', 
u'id': 78, 
u'lat': u'1.440409', 
u'lon': u'103.801489', 
u'name': u"McDonald's Admiralty", 
u'op_hours': u'24 hours<br>\r\nDessert Kiosk: 0900-0100', 
u'phone': u'68940513', 
u'region': u'north', 
u'type': [u'24hrs', u'dessert_kiosk'], 
u'zip': u'731678'} 

:

scrapy örümcek yazmadan önce web sitesi ile düşünür için çok uygundur shell komutu sağlayan örümcek içinde daha sonra geri dönüşünde yük, yukarıda FormRequest(...) dönmek zorunda response.body'dan json nesnesi ve son olarak her bir mağazadaki data['stores']['listing'] listesindeki veriler için istenen değerlere sahip bir öğe oluşturun. Böyle

şey:

class McDonaldSpider(BaseSpider): 
    name = "mcdonalds" 
    allowed_domains = ["mcdonalds.com.sg"] 
    start_urls = ["https://www.mcdonalds.com.sg/locate-us/"] 

    def parse(self, response): 
     # This receives the response from the start url. But we don't do anything with it. 
     url = 'https://www.mcdonalds.com.sg/wp-admin/admin-ajax.php' 
     payload = {'action': 'ws_search_store_location', 'store_name':'0', 'store_area':'0', 'store_type':'0'} 
     return FormRequest(url, formdata=payload, callback=self.parse_stores) 

    def parse_stores(self, response): 
     data = json.loads(response.body) 
     for store in data['stores']['listing']: 
      yield McDonaldsItem(name=store['name'], address=store['address']) 
+0

Yardım için Thx Rho bilgilendirici ve işe yaradı! * Benim gibi aynı soruna bakanlar için bu mesajı kontrol et * – HeadAboutToExplode

7

Seçtiğiniz tarayıcıda https://www.mcdonalds.com.sg/locate-us/ açtığınızda, "incelemek" aracını açın (umarım bir tane vardır, örneğin Chrome veya Firefox) ve "Ağ" sekmesini arayın.

Sen ayrıca "XHR" (XMLHttpRequest) olaylar için filtre edebilir ve bu bedene

action=ws_search_store_location&store_name=0&store_area=0&store_type=0 

o POST isteğine yanıt ile https://www.mcdonalds.com.sg/wp-admin/admin-ajax.php bir POST isteği göreceksiniz

tüm sahip bir JSON nesnesidir bilgi istediğiniz

import json 
import pprint 
... 
class MySpider(BaseSpider): 
... 
    def parse_json(self, response): 

     js = json.loads(response.body) 
     pprint.pprint(js) 

Bu çıktılayacaktır gibi bir şey:

{u'flagicon': u'https://www.mcdonalds.com.sg/wp-content/themes/mcd/images/storeflag.png', 
u'stores': {u'listing': [{u'address': u'678A Woodlands Avenue 6<br/>#01-05<br/>Singapore 731678', 
          u'city': u'Singapore', 
          u'id': 78, 
          u'lat': u'1.440409', 
          u'lon': u'103.801489', 
          u'name': u"McDonald's Admiralty", 
          u'op_hours': u'24 hours<br>\r\nDessert Kiosk: 0900-0100', 
          u'phone': u'68940513', 
          u'region': u'north', 
          u'type': [u'24hrs', u'dessert_kiosk'], 
          u'zip': u'731678'}, 
          {u'address': u'383 Bukit Timah Road<br/>#01-09B<br/>Alocassia Apartments<br/>Singapore 259727', 
          u'city': u'Singapore', 
          u'id': 97, 
          u'lat': u'1.319752', 
          u'lon': u'103.827398', 
          u'name': u"McDonald's Alocassia", 
          u'op_hours': u'Daily: 0630-0100', 
          u'phone': u'68874961', 
          u'region': u'central', 
          u'type': [u'24hrs_weekend', 
            u'drive_thru', 
            u'mccafe'], 
          u'zip': u'259727'}, 

         ... 
          {u'address': u'60 Yishuan Avenue 4 <br/>#01-11<br/><br/>Singapore 769027', 
          u'city': u'Singapore', 
          u'id': 1036, 
          u'lat': u'1.423924', 
          u'lon': u'103.840628', 
          u'name': u"McDonald's Yishun Safra", 
          u'op_hours': u'24 hours', 
          u'phone': u'67585632', 
          u'region': u'north', 
          u'type': [u'24hrs', 
            u'drive_thru', 
            u'live_screening', 
            u'mccafe', 
            u'bday_party'], 
          u'zip': u'769027'}], 
      u'region': u'all'}} 

İstediğiniz alanları ayıklamak için sizi bırakacağım. "X-Talep-Birlikte: XMLHttpRequest" FormRequest() Eğer scrapy ile göndermek muhtemelen eklemem gerekiyor ise

başlık (tarayıcınızın gönderdiği incelemek aracında istek başlıklarına bakacak olursak)

+0

hızlı cevap! thx paul, 2. kez bana yardımcı oldu: DDD – HeadAboutToExplode

+0

Bir şey değil. Bu, SO'nun her şeyle ilgili olduğu şey: Paylaşmak ve yardım etmek. –

+0

Yumru, düzenlenmiş. biraz daha tavsiye alabilir miyim? – HeadAboutToExplode