所以,我正试图用剧作家的几个搜索短语来抓取几个搜索引擎。使用一个查询运行脚本是有效的。
工作:
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch({ headless: false, slowMo: 250 });
const context = await browser.newContext()
const page = await context.newPage();
const keyWord = ('Arsenal');
await page.goto('https://duckduckgo.com/');
await page.fill('//input[@name="q"]',keyWord);
await page.keyboard.press('Enter');
const getOne = (' (//h2[@class="result__title"])[9] ');
await page.waitForSelector(getOne)
const pushOne = await page.$(getOne);
const One = await pushOne.evaluate(element => element.innerText);
console.log(One);
await page.goto('https://yandex.com/');
await page.fill('//input[@aria-label="Request"]', keyWord);
await page.keyboard.press('Enter');
const getTwo = (' //li[@data-first-snippet] //div[@class="organic__url-text"] ');
await page.waitForSelector(getTwo)
const pushTwo = await page.$(getTwo);
const Two = await pushTwo.evaluate(element => element.innerText);
console.log(Two);
await browser.close()
})()
但是当我使用数组与短语(keyWordlist)我无法得到脚本运行。已经搜索了使用数组与"for"one_answers"Foreach"循环,但还没有能够修复它。我想通过不同的搜索引擎运行不同的关键字,并列出结果。在两个搜索引擎中搜索3个关键词,会得到6个结果。
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch({ headless: false, slowMo: 250 });
const context = await browser.newContext()
const page = await context.newPage();
let kewWordlist = ['Arsenal', 'Liverpool', 'Ajax']
for (var i=0; i<=kewWordlist.length; i++) {
// for (const i in kewWordlist){
async () => {
const keyWord = kewWordlist[i];
await page.goto('https://duckduckgo.com/');
await page.fill('//input[@name="q"]',keyWord);
// await page.fill('//input[@name="q"]',[i]);
// await page.fill('//input[@name="q"]',`${keyWord}`);
await page.keyboard.press('Enter');
const getOne = (' (//h2[@class="result__title"])[9] ');
await page.waitForSelector(getOne)
const pushOne = await page.$(getOne);
const One = await pushOne.evaluate(element => element.innerText);
console.log(One);
// await page.goto('https://yandex.com/');
// await page.fill('//input[@aria-label="Request"]', keyWord);
// await page.keyboard.press('Enter');
// const getTwo = (' //li[@data-first-snippet] //div[@class="organic__url-text"] ');
// await page.waitForSelector(getTwo)
// const pushTwo = await page.$(getTwo);
// const Two = await pushTwo.evaluate(element => element.innerText);
// console.log(Two);
}}
await browser.close()
})()
如果有人对如何解决这个问题有一些建议,我将不胜感激。
也许结果选择器需要一些调整,但我认为这是你正在寻找的:
test.only('search search engines', async({page, context}) => {
const search = [
{
name: 'yandex',
url: 'https://yandex.com/',
elementFill: '//input[@aria-label="Request"]',
elementResult: '//li[@data-first-snippet] //div[@class="organic__url-text"]'
},
{
name: 'google',
url: 'https://www.google.nl',
elementFill: '//input[@name="q"]',
elementResult: '(//h2[@class="result__title"])[9]'
},
{
name: '',
url: 'https://duckduckgo.com/',
elementFill: '//input[@name="q"]',
elementResult: '(//h2[@class="result__title"])[9]'
}
]
const kewWordlist = ['Arsenal', 'Liverpool', 'Ajax']
for (let i = 0; i < search.length; i++) {
const searchName = search[i].name
const searchResult = search[i].elementResult
const searchFill = search[i].elementFill
const searchPage = await context.newPage()
await searchPage.waitForLoadState()
await searchPage.goto(`${search[i].url}`)
for (let i = 0; i < kewWordlist.length; i++) {
await searchPage.fill(searchFill,kewWordlist[i])
await searchPage.keyboard.press('Enter')
await searchPage.waitForSelector(searchResult)
const result = await page.$(searchResult)
console.log(`${searchName}: ${result} `)
}
}
})
你的循环不工作的原因是你在它里面有一个你从未调用过的异步函数。有几种方法可以做到这一点:
你可以用你的第一个版本,让它接受一个词来搜索,然后在数组的每个元素上运行:
const searchOneKeyword = async (keyWord) => {
const browser = await chromium.launch({ headless: false, slowMo: 250 });
const context = await browser.newContext()
const page = await context.newPage();
// rest of code
}
const kewWordList = ['Arsenal', 'Liverpool', 'Ajax']
keyWordList.forEach((k) => {
searchOneKeyword(k)
})
或者,如果您想保持相同的浏览器实例,您可以在函数中的循环中完成:
const search = async (words) => {
const browser = await chromium.launch({ headless: false, slowMo: 250 });
const context = await browser.newContext()
const page = await context.newPage();
for (const keyWord of words) {
await page.goto('https://duckduckgo.com/');
await page.fill('//input[@name="q"]',keyWord);
await page.keyboard.press('Enter');
const getOne = (' (//h2[@class="result__title"])[9] ');
await page.waitForSelector(getOne)
const pushOne = await page.$(getOne);
const One = await pushOne.evaluate(element => element.innerText);
console.log(One);
// etc.
}
await browser.close()
}
search(keyWordList)
在这两种情况下,你记录,但从不返回任何东西,所以如果你需要的数据在另一个函数之后,你必须改变它。例子:
const search = async (words) => {
const browser = await chromium.launch({ headless: false, slowMo: 250 });
const context = await browser.newContext()
const page = await context.newPage();
const results = await Promise.all(words.map((keyWord) => {
await page.goto('https://duckduckgo.com/');
await page.fill('//input[@name="q"]',keyWord);
await page.keyboard.press('Enter');
// etc.
return [ One, Two ]
}))
await browser.close()
return results
}
search(keyWordList).then((results) => { console.log(results.flat()) })
我花了几个小时试图根据您的建议让脚本工作。不幸的是没有结果。我得到诸如"等待只在异步函数中有效"one_answers"检测到无法到达的代码"之类的错误。寻找其他的例子,寻找一些灵感,但没有找到。如果你或其他人有建议,请分享!这是我现在的代码:
const { chromium } = require('playwright');
let keyWordList = ['Arsenal', 'Liverpool', 'Ajax']
const search = async function words() {
const browser = await chromium.launch({ headless: false, slowMo: 250 });
const context = await browser.newContext()
const page = await context.newPage();
}
const results = await Promise.all(words.map(keyWord))
//DUCKDUCKGO
await page.goto('https://duckduckgo.com/');
await page.fill('//input[@name="q"]',keyWord);
await page.keyboard.press('Enter');
const getOne = (' (//h2[@class="result__title"])[9] ');
await page.waitForSelector(getOne)
const pushOne = await page.$(getOne);
const One = await pushOne.evaluate(element => element.innerText);
//YANDEX
await page.goto('https://yandex.com/');
await page.fill('//input[@aria-label="Request"]', keyWord);
await page.keyboard.press('Enter');
const getTwo = (' //li[@data-first-snippet] //div[@class="organic__url-text"] ');
await page.waitForSelector(getTwo)
const pushTwo = await page.$(getTwo);
const Two = await pushTwo.evaluate(element => element.innerText);
console.log(Two);
return [ One , Two ]
return results
search(keyWordList).then((results) => { console.log(results.flat())
await browser.close();
})