await page.on("response", async (response) => {
const request = await response.request();
if (
request.url().includes("https://www.jobs.abbott/us/en/search-results")
) {
const text = await response.text();
const root = await parse(text);
root.querySelectorAll("script").map(async function (n) {
if (n.rawText.includes("eagerLoadRefineSearch")) {
const text = await n.rawText.match(
/"eagerLoadRefineSearch":({.*}),/,
);
const refinedtext = await text[0].match(/[{.*}]/);
//console.log(refinedtext);
console.log(JSON.parse(refinedtext[0]));
}
});
}
});
在这个片段中,我发布了一个文本格式的数据,我想用regex
将eagerLoadRefineSearch : { (and its content too)}
提取为文本,并对提取的文本执行json.parse
,这样我最终得到一个"eagerLoadRefineSearch" : {}
的json对象。
我使用puppetter
拦截响应。我只想要一个正确的regex
,它可以得到"eagerLoadRefineSearch" : {}
的整个对象文本(及其内容(。
我正在此链接中共享来自服务器的响应文本https://codeshare.io/bvjzJA。
我想从中的文本格式的数据中提取"eagerLoadRefineSearch" : {}
https://codeshare.io/bvjzJA
上下文
愚蠢的错误
您正在解析的文本在eagerLoadRefineSearch
周围没有两侧的"
。现在要匹配的对象跨越几行,因此需要m
标志。此外,.
与新线不匹配,因此备选方案是使用[sS]
。请参阅如何在多行中使用javascript正则表达式。
另外,不要在字符串方法match
上使用await
。
匹配右大括号
快速搜索这个话题会让我找到这个链接,正如我所怀疑的,这很复杂。为了缓解这个问题,我假设文本是正确缩进的。我们可以在缩进级别上进行匹配,以找到具有此模式的右大括号。
/(?<indent>[s]+){[sS]+k<indent>}/gm
如果左大括号和右大括号都处于相同的缩进级别,则此操作有效。它们不在我们的情况下,因为eagerLoadRefineSearch:
位于缩进和左大括号之间,但我们可以解释这一点。
const reMatchObject = /(?<indent>[s]+)eagerLoadRefineSearch: {[sS]+?k<indent>}/gm
有效的JSON
如前所述,密钥缺少两侧双引号,因此让我们用"key"
s替换所有key
s。
const reMatchKeys = /(w+):/gm
const impure = 'hello: { name: "nammu", age: 18, subjects: { first: "english", second: "mythology"}}'
const pure = impure.replace(reMatchKeys, '"$1":')
console.log(pure)
然后我们去掉后面的逗号。下面是适用于这个示例的正则表达式。
const reMatchTrailingCommas = /,(?=s+[]}])/gm
一旦我们通过管道传输这些replace
函数,JSON.parse
就可以很好地使用这些数据。
代码
await page.on('response', async (response) => {
const request = await response.request();
if (
request
.url()
.includes('https://www.jobs.abbott/us/en/search-results')
) {
const text = await response.text();
const root = await parse(text);
root.querySelectorAll('script').map(async function (n) {
const data = n.rawText;
if (data.includes('eagerLoadRefineSearch')) {
const reMatchObject = /(?<indent>[s]+)eagerLoadRefineSearch: {[sS]+?k<indent>}/gm;
const reMatchKeys = /(w+):s/g;
const reMatchTrailingCommas = /,(?=s+[]}])/gm;
const parsedStringArray = data.toString().match(reMatchObject);
for (const parsed of parsedStringArray) {
const noTrailingCommas = parsed.replace(reMatchTrailingCommas, '');
const validJSONString = '{' + noTrailingCommas.replace(reMatchKeys, '"$1":') + '}';
console.log(JSON.parse(validJSONString));
}
}
});
}
});