Как получить значение переменной JavaScript с помощью xpath? = - PullRequest
0 голосов
/ 11 декабря 2018

Я пытаюсь извлечь цены и другие атрибуты из этого JS-кода:

  <script type="application/ld+json">
{
  "@context": "http://schema.org/",
  "@type": "Product",
  "name": "Rolex Cellini Time 50505",
  "image": [
        "https://chronexttime.imgix.net/S/1/S1006/S1006_58774a90efd04.jpg?w=1024&amp;auto=format&amp;fm=jpg&amp;q=75&amp;usm=30&amp;usmrad=1&amp;h=1024&amp;fit=clamp"      ],
  "description": "Werk: automatic; Herrenuhr; Gehäusegröße: 39; Gehäuse: rose-gold; Armband: leather; Glas: sapphire; Jahr: 2018; Lieferumfang: Originale Box, Originale Papiere, Herstellergarantie",
  "mpn": "S1006",
  "brand":{
    "@type": "Thing",
    "name": "Rolex"
  },
  "offers":{
    "@type": "Offer",
    "priceCurrency": "EUR",
    "price": "11500",
    "itemCondition": "http://schema.org/NewCondition",
    "availability": "http://schema.org/InStock",

    "seller":{
      "@type": "Organization",
      "name": "CHRONEXT Service Germany GmbH"
    }
  }
}
</script>

В качестве альтернативы этот код может также сделать это:

  <script type="text/javascript">
window.articleInfo = {
    'id': 'S1006',
    'model': 'Cellini Time',
    'brand': 'Rolex',
    'reference': '50505',
    'priceLocal': '11500',
    'currencyCode': 'EUR'
};

Существует еще много другихJS код на той же странице, поэтому я не уверен, как адресовать этот конкретный скрипт с помощью xpath.

Я пробовал это:

response.xpath('//script[contains(.,"price")]/text()').extract_first()

, но ответ содержит кучу значений, в то время как я ищу только цену 11500. Позже я также попытался бы получить, например, имяи состояние.

Ответы [ 2 ]

0 голосов
/ 13 декабря 2018

Для первого сценария, да, нет лучшего варианта, чем декодировать его напрямую с помощью json.

Для второго сценария, конечно, вы всегда можете использовать регулярные выражения, но более чистое и лучшее решение Iрекомендовал бы использовать js2xml, который преобразует JavaScript в формат запроса xpath:

$ pip install js2xml

скажем, один скрипт имеет следующую структуру:

<script type="text/javascript">
window.articleInfo = {
    'id': 'S1006',
    'model': 'Cellini Time',
    'brand': 'Rolex',
    'reference': '50505',
    'priceLocal': '11500',
    'currencyCode': 'EUR'
};
</script>

форматирование будет выглядеть так:

import js2xml

...

parsed = js2xml.parse(response.xpath('//script/text()').extract_first())

Вы можете увидеть структуру parsed с:

>> print(js2xml.pretty_print(parsed))
>> <program>
  <assign operator="=">
    <left>
      <dotaccessor>
        <object>
          <identifier name="window"/>
        </object>
        <property>
          <identifier name="articleInfo"/>
        </property>
      </dotaccessor>
    </left>
    <right>
      <object>
        <property name="id">
          <string>S1006</string>
        </property>
        <property name="model">
          <string>Cellini Time</string>
        </property>
        <property name="brand">
          <string>Rolex</string>
        </property>
        <property name="reference">
          <string>50505</string>
        </property>
        <property name="priceLocal">
          <string>11500</string>
        </property>
        <property name="currencyCode">
          <string>EUR</string>
        </property>
      </object>
    </right>
  </assign>
</program>

Что означает, что теперь вы можете получить информациювам нужно вот так:

parsed.xpath('//property[@name="id"]/string/text()')[0]
parsed.xpath('//property[@name="model"]/string/text()')[0]
parsed.xpath('//property[@name="brand"]/string/text()')[0]
...

Я надеюсь, что смогу вам помочь с этим.

0 голосов
/ 11 декабря 2018

У вас есть два варианта,

1) Использование Json, но это будет работать только для первого случая

json_data = json.loads(response.xpath('//script[@type="application/ld+json"]/text()').extract_first())
price = json_data['price']

2) Использование регулярного выражения:

response.xpath('//script/text()').re_first('price(?:local)?["\']\s*:\s*["\'](.*)'["\'])

Регулярное выражение price(?:local)?["\']\s*:\s*["\'](.*)'["\'] означает:

  • Начните с цены с необязательным local суффиксом
  • Затем одинарные или двойные кавычки
  • Затем :между нулем и более пробелов
  • Затем одинарные или двойные кавычки
  • Затем любое значение (здесь будет цена)
  • Затем снова одинарные или двойные кавычки
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...