Анализ переменных данных из тега javascript с использованием python

Я очищаю некоторые сайты, используя BeautifulSoup и Requests. Есть одна страница, которую я изучаю, которая имеет свои данные внутри тега <script language="JavaScript" type="text/javascript">. Это выглядит так:

<script language="JavaScript" type="text/javascript">
var page_data = {
   "default_sku" : "SKU12345",
   "get_together" : {
      "imageLargeURL" : "http://null.null/pictures/large.jpg",
      "URL" : "http://null.null/index.tmpl",
      "name" : "Paints",
      "description" : "Here is a description and it works pretty well",
      "canFavorite" : 1,
      "id" : 1234,
      "type" : 2,
      "category" : "faded",
      "imageThumbnailURL" : "http://null.null/small9.jpg"
       ......

Есть ли способ создать словарь python или json-объект из переменной page_data в этом теге script? Это было бы намного лучше, чем пытаться получить значения с помощью BeautifulSoup.

Ответ 1

Если вы используете BeautifulSoup для получения содержимого тега <script>, json модуль может сделать все остальное с помощью немного магии строк:

 jsonValue = '{%s}' % (textValue.split('{', 1)[1].rsplit('}', 1)[0],)
 value = json.loads(jsonValue)

Комбинация .split() и .rsplit() выше разбивает текст на первый { и на последний } в текстовом блоке JavaScript, который должен быть вашим определением объекта. Добавив фигурные скобки к тексту, мы можем отправить его json.loads() и получить из него структуру python.

Демонстрация:

>>> import json
>>> textValue = '''
... var page_data = {
...    "default_sku" : "SKU12345",
...    "get_together" : {
...       "imageLargeURL" : "http://null.null/pictures/large.jpg",
...       "URL" : "http://null.null/index.tmpl",
...       "name" : "Paints",
...       "description" : "Here is a description and it works pretty well",
...       "canFavorite" : 1,
...       "id" : 1234,
...       "type" : 2,
...       "category" : "faded",
...       "imageThumbnailURL" : "http://null.null/small9.jpg"
...    }
... };
... '''
>>> jsonValue = '{%s}' % (textValue.split('{', 1)[1].rsplit('}', 1)[0],)
>>> value = json.loads(jsonValue)
>>> value
{u'default_sku': u'SKU12345', u'get_together': {u'category': u'faded', u'canFavorite': 1, u'name': u'Paints', u'URL': u'http://null.null/index.tmpl', u'imageThumbnailURL': u'http://null.null/small9.jpg', u'imageLargeURL': u'http://null.null/pictures/large.jpg', u'type': 2, u'id': 1234, u'description': u'Here is a description and it works pretty well'}}
>>> import pprint
>>> pprint.pprint(value)
{u'default_sku': u'SKU12345',
 u'get_together': {u'URL': u'http://null.null/index.tmpl',
                   u'canFavorite': 1,
                   u'category': u'faded',
                   u'description': u'Here is a description and it works pretty well',
                   u'id': 1234,
                   u'imageLargeURL': u'http://null.null/pictures/large.jpg',
                   u'imageThumbnailURL': u'http://null.null/small9.jpg',
                   u'name': u'Paints',
                   u'type': 2}}