2012-11-08 61 views
10

Tôi đang cạo một số trang web bằng cách sử dụng BeautifulSoup và Yêu cầu. Có một trang mà tôi đang kiểm tra có dữ liệu bên trong thẻ <script language="JavaScript" type="text/javascript">. Nó trông giống như thế này:Phân tích cú pháp dữ liệu biến ra khỏi thẻ javascript bằng cách sử dụng python

<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" 
     ...... 

Có cách nào mà tôi có thể tạo ra một từ điển python hoặc đối tượng json ra của biến page_data trong thẻ script này? Điều đó sẽ đẹp hơn nhiều sau đó cố gắng để có được giá trị với BeautifulSoup.

Trả lời

22

Nếu bạn sử dụng BeautifulSoup để có được nội dung của thẻ <script>, các json module có thể làm phần còn lại với một chút chuỗi ma thuật:

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

Các .split().rsplit() kết hợp trên chia các văn bản trên { đầu tiên và trên } cuối cùng trong khối văn bản JavaScript, phải là định nghĩa đối tượng của bạn. Bằng cách thêm dấu ngoặc ôm vào văn bản, chúng ta có thể đưa nó vào json.loads() và lấy cấu trúc python từ nó.

diễn:

>>> 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}} 
+0

Đây là thực sự tuyệt vời và ý nghĩa. Cảm ơn bạn đã giúp. – ajt

+0

Tôi rất muốn biết cách tôi có thể sử dụng lại điều này cho một tuyên bố đối tượng không sử dụng dấu ngoặc kép để biểu thị các khóa của đối tượng, ví dụ: 'default_sku:" SKU12345 ", ...'. Nó có lẽ chỉ cần có một regex ... – 2rs2ts

+0

@ 2rs2ts: Xem [Vấn đề với thẻ html trong khi cạo dữ liệu bằng cách sử dụng súp đẹp] (http://stackoverflow.com/a/14122300) cho một câu trả lời trước đó cho biết thêm trong dấu ngoặc kép để làm cho một cái gì đó hợp lệ JSON. –

Các vấn đề liên quan