You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Javascript、Cheerio和Axios爬取Transfermarkt时出现选择器未终止错误

解决Transfermarkt爬取时的Cheerio选择器报错

问题场景

使用Javascript、Cheerio和Axios爬取Transfermarkt英超2022赛季射手榜数据时,出现如下报错:

throw new Error("Attribute selector didn't terminate");
Error: Attribute selector didn't terminate

原代码如下:

const fetchData = async(url) => {
    const result = await axios.get(url)
    return result.data
}

const main = async () => {
    const content = await fetchData("https://www.transfermarkt.com.br/premier-league/torschuetzenliste/wettbewerb/GB1/saison_id/2022")
    const $ = cheerio.load(content)
    let artilheiros = []

    $('table.items tbody tr').each((i, e) => {
        const AllElements = $(e).find('td')
        const nomeArtilheiro = $(`${AllElements[1]} > table > tbody > tr.hauptlink > a`).text();
        // const clubeArtilheiro
        // const jogos 
        // const gols 
        const data = {nomeArtilheiro}
        artilheiros.push(data)
    })

    console.log(artilheiros)
}

main()

报错原因

代码中错误地将Cheerio DOM对象AllElements[1]直接转成字符串拼接到选择器模板中,导致生成的选择器语法完全不符合规范,Cheerio无法解析这种混乱的选择器,因此抛出“属性选择器未终止”的错误。

修复方案

方案1:基于已有DOM对象链式调用find方法

不需要拼接选择器,直接在AllElements[1]对应的元素上调用find方法查找子元素:

$('table.items tbody tr').each((i, e) => {
    const AllElements = $(e).find('td')
    // 直接在AllElements[1]的元素上执行find
    const nomeArtilheiro = $(AllElements[1]).find('table > tbody > tr.hauptlink > a').text();
    const data = {nomeArtilheiro}
    artilheiros.push(data)
})

方案2:直接使用精准的CSS选择器

跳过AllElements的中间变量,直接在遍历的行元素中通过nth-child定位目标列,再查找子元素:

$('table.items tbody tr').each((i, e) => {
    const nomeArtilheiro = $(e).find('td:nth-child(2) table tbody tr.hauptlink a').text();
    // 补充其他字段的爬取逻辑示例:
    const clubeArtilheiro = $(e).find('td:nth-child(3) a').text();
    const jogos = $(e).find('td:nth-child(4)').text().trim();
    const gols = $(e).find('td:nth-child(5)').text().trim();
    const data = {nomeArtilheiro, clubeArtilheiro, jogos, gols}
    artilheiros.push(data)
})

额外提示

爬取Transfermarkt时建议添加请求头模拟浏览器访问,避免被反爬拦截,示例:

const fetchData = async(url) => {
    const result = await axios.get(url, {
        headers: {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36'
        }
    })
    return result.data
}

内容的提问来源于stack exchange,提问作者G4rutti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 00:05:35