抓取Javascrip中的数据

2024-06-30 16:30:42 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用^{}筛选从网站上刮取的数据。然而,我想要的数据不在html本身,而是来自javascript。所以,我的问题是:

如何获取此类情况的值(文本值)?

这是我要筛选的网站: https://www.mcdonalds.com.sg/locate-us/

我试图获得的属性: 地址,联系方式,营业时间。

如果在chrome浏览器中执行“右键单击”和“查看源代码”,您将看到这些值本身在HTML中不可用。


编辑

Sry paul,我照你说的做了,找到了尸体,看到了尸体,但是,我现在真的被卡住了。

如何从json对象中检索值并将其存储到自己的变量字段中?如果你能分享一下如何为公众以及那些刚刚开始发霉的人做一件事,那就太好了。

这是我的密码

项目.py

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

麦当劳.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值存储到我的属性中?对于eg

***item['address']=*如何检索****

p.S,不确定这是否有用,但是,我在命令行上运行这些脚本

scrapy craw mcdonalds-o mcdonalds.json-t json(将我的所有数据保存到一个json文件中)

我不能过分强调我的感激之情。我知道问你这个有点不合理,即使你没有时间也会没事的。


Tags: 数据fromhttpsimportcomjsonfield属性
2条回答

(我将此发布到了scrapy-users邮件列表,但根据Paul的建议,我将其发布在这里,因为它通过shell命令交互补充了答案。)

通常,使用第三方服务呈现某些数据可视化(地图、表格等)的网站必须以某种方式发送数据,并且在大多数情况下,可以从浏览器访问这些数据。

对于这种情况,检查(即浏览浏览器发出的请求)显示数据是从POST请求加载到https://www.mcdonalds.com.sg/wp-admin/admin-ajax.php

所以,基本上你已经准备好了所有你想要的数据,用一个很好的json格式。

Scrapy提供了shell命令,在编写spider之前,thinker非常方便地使用该网站:

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

简而言之:在spider中,您必须返回上面的FormRequest(...),然后在回调中从response.body加载json对象,最后为列表中每个存储的数据创建一个具有所需值的项。

像这样的:

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'])

在您选择的浏览器中打开https://www.mcdonalds.com.sg/locate-us/时,打开“检查”工具(希望它有一个,例如Chrome或Firefox),并查找“网络”选项卡。

您可以进一步筛选“XHR”(XMLHttpRequest)事件,您将看到一个使用此主体的POST请求https://www.mcdonalds.com.sg/wp-admin/admin-ajax.php

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

对POST请求的响应是一个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'}}

我让你去提取你想要的田地。

在用Scrapy发送的FormRequest()中,您可能需要添加一个“X-Requested-with:XMLHttpRequest”头(如果您在inspect工具中查看请求头,浏览器将发送该头)

相关问题 更多 >