Trong bài viết này Thanh sẽ chia sẻ với các bạn cách trích xuất dữ liệu từ báo cáo Power BI đã xuất bản lên web mà không có dữ liệu nguồn. Đây là một bài chia sẻ kiến thức nâng cao. Để có thể hiểu và triển khai được đoạn code trong bài này, bạn cần kiến thức ít nhất từ khóa học:
Lập trình tương tác Python Excel chìa khóa tối ưu công việc
Mời các bạn theo dõi video phân tích và giải thích code sử dụng ở đây:
Đoạn code Python sử dụng trong video là:
import re
import json
import base64
import requests
from bs4 import BeautifulSoup
from urllib.parse import unquote
url = 'https://app.powerbi.com/view?r=eyJrIjoiYjQzZDE1ZDgtNTI0NS00N2U5LThlM2QtMTljZTcwMTgyY2E4IiwidCI6IjQ0YmQ2NjgzLWI0MTQtNGFjNC1iY2VjLTY4NDFiZDNmMzlkMyIsImMiOjEwfQ%3D%3D'
token = url.split('=')[-1]
unquoted_token = unquote(token)
token_string = base64.b64decode(unquoted_token).decode('utf-8')
d = json.loads(token_string)
tenantId = d['t']
resourceKey = d['k']
html_data = requests.get(url).text
resolvedClusterUri = re.search(r"var resolvedClusterUri = '(.*?)'", html_data)[1].replace('-redirect', '-api')
requestId = re.search(r"var requestId = '(.*?)'", html_data)[1]
activityId = re.search(r"var telemetrySessionId = '(.*?)'", html_data)[1]
url = resolvedClusterUri + "/public/reports/" + resourceKey + "/modelsAndExploration?preferReadOnlySession=true"
query_url = resolvedClusterUri + "/public/reports/querydata?synchronous=true"
headers={'ActivityId': activityId, 'RequestId': requestId, 'X-PowerBI-ResourceKey': resourceKey}
data = requests.get(url, headers=headers).json()
for s in data['exploration']['sections']:
if 'query' in s['visualContainers'][0]:
payload = {
"version": "1.0.0",
"queries": [
{
"Query": json.loads(s['visualContainers'][0]['query']),
"CacheKey": '',
"QueryId": "",
"ApplicationContext": {
"DatasetId": data['models'][0]['dbName'],
"Sources": [
{
"ReportId": data['exploration']['report']['objectId']
}
]
}
}
],
"cancelQueries": [],
"modelId": data['models'][0]['id']
}
section_data = requests.post(query_url, json=payload, headers=headers).json()
print(section_data['results'][0]['result']['data']['dsr']['DS'][0]['ValueDicts']['D0'])
print('-' * 80)
print(section_data['results'][0]['result']['data']['dsr']['DS'][0]['PH'][0]['DM0'])