英文:
chromedp - How to retrieve FCP and such from console
问题
我正在使用chromedp包构建一个个人爬虫。我想获取我的FCP(First Contentful Paint)和其他统计数据。不幸的是,我无法找到一种方法来实现这一点,然后我想到了从开发者控制台中提取它的方法。
不幸的是,在研究了两天后,我在互联网上找不到任何教程。
请问有人可以告诉我如何使用chromedp测量FCP和其他指标吗?
我尝试了以下代码,但返回一个错误:遇到了一个未定义的值。
但是,当我在浏览器的控制台中输入它时,它确实可以工作。
chromedp.EvaluateAsDevTools("const paintTimings = performance.getEntriesByType('paint');", nil),
chromedp.EvaluateAsDevTools("const fmp = paintTimings.find(({ name }) => name === \"first-contentful-paint\");", nil),
chromedp.EvaluateAsDevTools("console.log('First contentful paint at foo');", &jscript))
我发现我遇到的问题是,当执行console.log时,devtools也会返回一个未定义的值,这与Go所期望的不符。
有人知道如何解决这个问题吗?
英文:
I am building a personal scraper using the chromedp package. I would like to get my FCP(First Contentful Paint) and other stats. Unfortunately I am unable to find a way to do this, then I got the idea of extracting it from the developer console.
Unfortunately I am unable to find any tutorials on the internet after two days of fiddling around with it.
Can anyone tell me please how I can measure the FCP and other metrics with chromedp?
I tried this but it returns an error: encountered an undefined value.
But when I type it into my browser's console it actually does work.
chromedp.EvaluateAsDevTools("const paintTimings = performance.getEntriesByType('paint');", nil),
chromedp.EvaluateAsDevTools("const fmp = paintTimings.find(({ name }) => name === \"first-contentful-paint\");", nil),
chromedp.EvaluateAsDevTools("console.log('First contentful paint at foo');", &jscript))
I figured out that the problem I have is, that when a console.log is executed devtools also returns a undefined which collides with what Go expects.
Does anyone know how to fix this?
答案1
得分: 1
我不理解FCP是如何测量的。我将在下面提供一个从chromedp的角度工作的演示。
最好使用cdp Performance domain和/或cdp PerformanceTimeline domain,但正如我之前所说,我不了解FCP,也不知道如何使用它们。
package main
import (
"context"
"encoding/json"
"log"
"github.com/chromedp/chromedp"
)
type performancePaintTiming struct {
EntryType string `json:"entryType"`
Name string `json:"name"`
Duration int `json:"duration"`
StartTime float64 `json:"startTime"`
}
func main() {
ctx, cancel := chromedp.NewContext(context.Background(),
// 启用调试模式以查看CDP消息。
// 这有助于理解CDP的工作原理。
// 但请不要在生产环境中启用它。
chromedp.WithDebugf(log.Printf))
defer cancel()
// 我不知道为什么,但似乎Runtime.evaluate不再返回JSON对象,所以我必须将其字符串化为字符串。
js := `
const paintTimings = performance.getEntriesByType('paint');
const fcp = paintTimings.find(({ name }) => name === "first-contentful-paint");
JSON.stringify(fcp);`
var res string
if err := chromedp.Run(ctx,
chromedp.Navigate("https://www.bing.com/"),
chromedp.EvaluateAsDevTools(js, &res),
); err != nil {
panic(err)
}
var fcp performancePaintTiming
if err := json.Unmarshal([]byte(res), &fcp); err != nil {
panic(err)
}
log.Printf("%#v", fcp)
}
参考资料:
- 查看如何解析
runtime.RemoteObject
对象:https://github.com/chromedp/chromedp/blob/19b37c1b76b6a16d165e69e18756475ddc8f6432/eval.go#L66-L96 - 查看关于
encountered an undefined value
的讨论:https://github.com/chromedp/chromedp/issues/526
英文:
I don't understand how FCP is measured. I will provide a demo that works from the perspective of chromedp below.
It would be better to use the cdp Performance domain and/or the cdp PerformanceTimeline domain, but as what I said before, I don't know FCP and I don't know how to use them.
package main
import (
"context"
"encoding/json"
"log"
"github.com/chromedp/chromedp"
)
type performancePaintTiming struct {
EntryType string `json:"entryType"`
Name string `json:"name"`
Duration int `json:"duration"`
StartTime float64 `json:"startTime"`
}
func main() {
ctx, cancel := chromedp.NewContext(context.Background(),
// Enable the debug mode to see the CDP messages.
// It's helpful to understand how CDP works.
// But please don't enable it in Production Environment.
chromedp.WithDebugf(log.Printf))
defer cancel()
// I don't know why but it seems that Runtime.evaluate does not return
// JSON object any more, so I have to stringified it into a string.
js := `
const paintTimings = performance.getEntriesByType('paint');
const fcp = paintTimings.find(({ name }) => name === "first-contentful-paint");
JSON.stringify(fcp);`
var res string
if err := chromedp.Run(ctx,
chromedp.Navigate("https://www.bing.com/"),
chromedp.EvaluateAsDevTools(js, &res),
); err != nil {
panic(err)
}
var fcp performancePaintTiming
if err := json.Unmarshal([]byte(res), &fcp); err != nil {
panic(err)
}
log.Printf("%#v", fcp)
}
References:
- See how the
runtime.RemoteObject
object is parsed: https://github.com/chromedp/chromedp/blob/19b37c1b76b6a16d165e69e18756475ddc8f6432/eval.go#L66-L96 - See discussion about
encountered an undefined value
: https://github.com/chromedp/chromedp/issues/526
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论