2013-09-26 2 views
20

scrapy을 사용하여 웹 사이트의 스크랩 데이터를 스크리닝합니다. 그러나 원하는 데이터는 HTML 자체가 아니라 자바 스크립트에서 가져온 것입니다. 그래서, 제 질문은 :자바 스크립트 내에서 데이터 스크랩하기

그런 경우의 값 (텍스트 값)을 얻는 방법은 무엇입니까? 내가 얻으려고 https://www.mcdonalds.com.sg/locate-us/

속성 : 주소, 연락처, 운영 시간

이것은 내가 화면 스크랩에 노력하고있어 사이트입니다.

크롬 브라우저에서 "마우스 오른쪽 버튼으로 클릭", "소스보기"를 수행하면 HTML에서 이러한 값을 사용할 수 없다는 것을 알 수 있습니다.


편집

SRY 폴, 난 당신이 정말 지금 붙어있어,에 나에게 말했다 admin-ajax.php를 발견하고 몸을 보았다하지만했다.

json 개체에서 값을 검색하고이를 내 자신의 변수 필드에 저장하려면 어떻게해야합니까? 대중을 위해 하나의 속성을 수행하는 방법과 치료를 시작한 사람들에게도 공유하는 방법을 공유하면 좋을 것입니다. 여기에 내 코드가 짧은, 그래서 내가 어떻게 저장합니까, 긴 편집을 위해 지금까지

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의

내 속성에 json 값? 예를 들어 대한

*** 항목 [ '주소'] = * 검색하는 방법 ****

PS, 확실하지 않은이 있지만, 도움이된다면, 내가 사용하는 cmd를 라인에서 이러한 스크립트를 실행

scream crawl mcdonalds -o McDonalds.json -t json (모든 데이터를 json 파일에 저장)

나는 얼마나 고맙다고 느끼는지 충분히 강조 할 수 없다. 나는 그것이 당신에게 이것을위한 시간이 없더라도 u의 이것에게 질문하는 것이 무리하다라고 완전히 알고있을 것이다라는 것을 알고있다.

답변

18

(나는 scrapy-users 메일 링리스트에이 문제를 게시하지만이 shell 명령의 상호 작용에 대한 답을 보완 바울의 제안에 의해 내가 여기를 게시하도록하겠습니다.) 일반적으로

, 타사 서비스를 사용하는 웹 사이트는 일부 데이터 시각화를 렌더링 (지도, 테이블 등)는 어떻게 든 데이터를 전송해야하며 대부분의 경우이 데이터는 브라우저에서 액세스 할 수 있습니다. 이 경우를 들어

, 검사 (즉, 브라우저에 의해 요청을 탐구) 기본적으로 당신이 좋은에서 원하는 모든 데이터가 있고, 데이터가 https://www.mcdonalds.com.sg/wp-admin/admin-ajax.php 그래서

에 POST 요청에서로드되는 것을 보여줍니다 json 형식을 사용할 준비가되었습니다. 한마디로

$ 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는 거미를 작성하기 전에 웹 사이트와 사상가 매우 편리한 shell 명령을 제공합니다 거미에 당신이 다음 콜백의로드 위의 FormRequest(...)을 반환해야 json 개체가 response.body이고 마지막으로 각 저장소의 데이터가 목록에 있습니다. data['stores']['listing'] 원하는 값으로 항목을 만듭니다. 이 같은

뭔가 :

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

도움을 준 Tho 정보 Rho는 유익하고 효과적입니다! * 저와 같은 문제를 겪고있는 분들을 위해이 게시물을 확인하십시오 * – HeadAboutToExplode

7

선택한 브라우저에서 https://www.mcdonalds.com.sg/locate-us/을 열면 "inspect"도구 (Chrome 또는 Firefox 등)가 열리 며 "네트워크"탭을 찾으십시오.

당신은 더 "XHR"(XMLHttpRequest의) 이벤트를 필터링 할 수 있습니다, 당신이 몸

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

그 POST 요청에 대한 응답으로 https://www.mcdonalds.com.sg/wp-admin/admin-ajax.phpPOST 요청을 볼 수

모두와 JSON 객체입니다 정보를 당신이 원하는

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

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

이 것 출력 뭔가 같은 :

{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'}} 

원하는 필드를 추출해 드리겠습니다. "X-요청-으로 : XMLHttpRequest를"이 FormRequest()는 Scrapy와 함께 보낼 당신이 아마를 추가 할 필요가에서

헤더 (브라우저에서 보내는 당신은 검사 도구의 요청 헤더를 보면)

+0

빠른 답변! thx 폴, 두 번째 시간이 나를 도왔 : DDD – HeadAboutToExplode

+0

당신은 오신 것을 환영합니다. 그것이 바로 SO의 전부입니다. 공유하고 돕는 것입니다. –

+0

범프 수정. 좀 더 조언을 해줄 수 있을까요? – HeadAboutToExplode

관련 문제