简体   繁体   English

如何从 selenium 的 console.log 中提取数组?

[英]How can I extract an array from the console.log in selenium?

When I try to get the console.log with当我尝试获取 console.log 时

driver.execute_script('values = [];Highcharts.charts[0].series[0].data.forEach(function(d){ values.push(d.y) });console.log(values);')
time.sleep(4)
for entry in driver.get_log('browser'):
print(entry)

I just get the console output but not the actual contents of the array which should look like this screenhot of array我只是得到控制台 output 但不是数组的实际内容,它应该看起来像这个数组的屏幕截图

Instead I get:相反,我得到:

{'level': 'INFO', 'message': 'console-api 2:121 Array(261)', 'source': 'console-api', 'timestamp': 1647448899327}

I´ve found a couple of suggestion on how to fix this but none of them worked for me unfortunately.我找到了一些关于如何解决这个问题的建议,但不幸的是,没有一个对我有用。 Does anyone have a solution?有没有人有办法解决吗? Thanks a lot!非常感谢!

EDIT: I found this script ( https://bgrins.github.io/devtools-snippets/#console-save ) which saves the console output to a file when i execute this script manually in the browser but when I try to implement it in selenium like编辑:我发现这个脚本( https://bgrins.github.io/devtools-snippets/#console-save )当我在浏览器中手动执行这个脚本但是当我尝试实现它时,它将控制台 output 保存到一个文件在 selenium 喜欢

driver.execute_script('(function(console){console.save=function(data,filename){if(!data){console.error("Console.save: No data")return}if(!filename)filename="console.json"if(typeof data==="object"){data=JSON.stringify(data,undefined,4)}var blob=new Blob([data],{type:"text/json"}),e=document.createEvent("MouseEvents"),a=document.createElement("a")a.download=filename a.href=window.URL.createObjectURL(blob)a.dataset.downloadurl=["text/json",a.download,a.href].join(":")e.initMouseEvent("click",true,false,window,0,0,0,0,0,false,false,false,false,0,null)a.dispatchEvent(e)}})(console)')

driver.execute_script('values = [];Highcharts.charts[0].series[0].data.forEach(function(d){ values.push(d.y) });console.save(values, add);')

I get this response:我得到这样的回应:

[19980:18944:0316/183240.115:ERROR:database.cc(1777)] OptOutBlacklist SQLite error: code 13 errno 112: database or disk is full sql: CREATE TABLE IF NOT EXISTS previews_v1 (host_name VARCHAR NOT NULL, time INTEGER NOT NULL, opt_out INTEGER NOT 
NULL, type INTEGER NOT NULL, PRIMARY KEY(host_name, time DESC, opt_out, type))
[19980:18944:0316/183240.121:ERROR:database.cc(1777)] OptOutBlacklist SQLite error: code 1 errno 112: no such table: enabled_previews_v1 sql: SELECT type, version FROM enabled_previews_v1
[19980:18944:0316/183240.132:ERROR:database.cc(1777)] OptOutBlacklist SQLite error: code 1 errno 112: no such table: enabled_previews_v1 sql: INSERT INTO enabled_previews_v1 (type, version) VALUES  (?, ?)
[19980:18944:0316/183240.180:ERROR:database.cc(1777)] OptOutBlacklist SQLite error: code 1 errno 112: no such table: previews_v1 sql: SELECT host_name, time, opt_out, type FROM previews_v1 ORDER BY host_name, time DESC
[15816:23948:0316/183240.237:ERROR:entry_impl.cc(999)] Failed to save user data
[15816:23948:0316/183240.259:ERROR:entry_impl.cc(999)] Failed to save user data
[15816:23948:0316/183240.340:ERROR:entry_impl.cc(999)] Failed to save user data
[15816:23948:0316/183240.359:ERROR:entry_impl.cc(999)] Failed to save user data
[19980:18944:0316/183240.607:ERROR:database.cc(1777)] Shortcuts SQLite error: code 13 errno 112: database or disk is full sql: COMMIT
[15816:23948:0316/183240.677:ERROR:entry_impl.cc(999)] Failed to save user data
[15816:23948:0316/183240.755:ERROR:entry_impl.cc(999)] Failed to save user data
[15816:23948:0316/183240.765:ERROR:entry_impl.cc(999)] Failed to save user data
[19980:18944:0316/183240.825:ERROR:database.cc(1777)] Shortcuts SQLite error: code 1 errno 112: no such table: omni_box_shortcuts sql: SELECT id, text, fill_into_edit, url, document_type, contents, contents_class, description, description_class, transition, type, keyword, last_access_time, number_of_hits FROM omni_box_shortcuts
[19980:19372:0316/183241.460:ERROR:database.cc(1777)] TopSites SQLite error: code 13 errno 0: database or disk is full sql: INSERT OR REPLACE INTO top_sites (url, url_rank, title) VALUES (?, ?, ?)
[19980:19372:0316/183241.468:ERROR:database.cc(1777)] TopSites SQLite error: code 13 errno 0: database or disk is full sql: INSERT OR REPLACE INTO top_sites (url, url_rank, title) VALUES (?, ?, ?)
[19980:19372:0316/183241.479:ERROR:database.cc(1777)] TopSites SQLite error: code 13 errno 0: database or disk is full sql: UPDATE top_sites SET url_rank = ? WHERE url == ?
[19980:19372:0316/183241.479:ERROR:database.cc(1777)] TopSites SQLite error: code 1 errno 0: cannot commit - no transaction is active sql: COMMIT
[19980:18944:0316/183241.550:ERROR:database.cc(1777)] Predictor SQLite error: code 13 errno 112: database or disk is full sql: COMMIT

I think it is XYProblem .我认为这是XYProblem

You ask how to get output from console.log() but it seems real problem is how to get data from Highcharts and use in Python - and this doesn't need console.log() .你问如何从console.log()获取 output 但似乎真正的问题是如何从Highcharts获取数据并在 Python 中使用 - 这不需要console.log()

You can use return values in JavaScript to get it in Python.可以使用JavaScript中的return values在Python中获取。

It doesn't even need JSON.stringify() in JavaScript and json.loads() in Python.它甚至不需要JSON.stringify()和 Python 中的json.loads()

data = driver.execute_script('''
values = [];
Highcharts.charts[0].series[0].data.forEach((d) => values.push(d.y));
return values;
''')

print(data)

EDIT:编辑:

Using .map() instead of forEarch() you can reduce JavaScript to one line:使用.map()而不是forEarch()可以将 JavaScript 减少到一行:

return Highcharts.charts[0].series[0].data.map(d => d.y);

Minimal working example for https://www.highcharts.com/demo/line-basic https 的最小工作示例://www.highcharts.com/demo/line-basic

from selenium import webdriver
#from webdriver_manager.chrome import ChromeDriverManager
from webdriver_manager.firefox import GeckoDriverManager
import time

url = 'https://www.highcharts.com/demo/line-basic'

#driver = webdriver.Chrome(executable_path=ChromeDriverManager().install())
driver = webdriver.Firefox(executable_path=GeckoDriverManager().install())

driver.get(url)

time.sleep(5)

data = driver.execute_script('''
values = [];
Highcharts.charts[0].series[0].data.forEach((d) => values.push(d.y));
return values;
''')

print(type(data), data)

# or shorter

data = driver.execute_script('return Highcharts.charts[0].series[0].data.map(d => d.y);')

print(type(data), data)

Result:结果:

<class 'list'> [43934, 52503, 57177, 69658, 97031, 119931, 137133, 154175]

EDIT:编辑:

For example it can be used to convert x with timestamps (in milliseconds) to date like MM/DD/YY or YYYY-MM-DD例如,它可用于将带有时间戳(以毫秒为单位)的x转换为日期,如MM/DD/YYYYYY-MM-DD

import datetime

data = [1647212400000, 1647298800000, 1647385200000, 1647471600000]

new_data = []

for x in data:
    dt = datetime.datetime.fromtimestamp(x//1000)
    new_data.append(d.strftime('%D'))
    print(d.strftime('%D'), '|', d.strftime('%Y-%m-%d'))
        
print('new_data:', new_data)        

Result:结果:

03/17/22 | 2022-03-17
03/17/22 | 2022-03-17
03/17/22 | 2022-03-17
03/17/22 | 2022-03-17
new_data: ['03/17/22', '03/17/22', '03/17/22', '03/17/22']

And if you keep data in pandas.DataFrame then you can use pd.to_datetime() and .dt.strftime('%D') but for calculations it can be better keep it as datetime如果您将数据保存在pandas.DataFrame中,那么您可以使用pd.to_datetime().dt.strftime('%D')但对于计算,最好将其保存为datetime时间

import pandas as pd

data = [1647212400000, 1647298800000, 1647385200000, 1647471600000]

df = pd.DataFrame({'date': data})
print(df)

df['date'] = pd.to_datetime(df['date'], unit='ms')
df['date'] = df['date'].dt.strftime('%D')
print(df)

Result:结果:

            date
0  1647212400000
1  1647298800000
2  1647385200000
3  1647471600000
       date
0  03/13/22
1  03/14/22
2  03/15/22
3  03/16/22

I basically fixed it with an additional js我基本上用额外的 js 修复了它

driver.execute_script("""(function(console){

    console.save = function(data, filename){

        if(!data) {
            console.error('Console.save: No data')
            return;
        }

        if(!filename) filename = 'console.json'

        if(typeof data === "object"){
            data = JSON.stringify(data, undefined, 4)
        }

        var blob = new Blob([data], {type: 'text/json'}),
            e    = document.createEvent('MouseEvents'),
            a    = document.createElement('a')

        a.download = filename
        a.href = window.URL.createObjectURL(blob)
        a.dataset.downloadurl =  ['text/json', a.download, a.href].join(':')
        e.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null)
        a.dispatchEvent(e)
    }
})(console)""")
driver.execute_script('values = [];Highcharts.charts[0].series[0].data.forEach(function(d){ values.push(d.y) });')
driver.execute_script('console.save(values, add);')

This will save the array to a json这会将数组保存到 json

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM