无法从 Facebook 广告的元标记中抓取图像 url - Axios Cheerio

问题描述 投票:0回答:1

感谢您的光临。

我正在尝试使用 Axios 和 Cheerio 从 Facebook 广告 URL 中抓取

og:image
元标记的值。我有一个函数可以在已部署的 api (aws) 的上下文中调用该函数

在本地测试执行此工作的函数没有问题,使用 postman 和在本地部署 api 都可以正常工作,或者仅通过使用

node
调用该函数。

在部署的 api 上使用 postman 进行测试时出现问题。 axios

responseUrl
是一个编码的“登录类型”网址,但包含我正在寻找的广告的网址:

示例:

https://www.facebook.com/login/?next=...
,其中
...
包含编码后的广告网址。

有 2 个陷阱:

  1. 向该函数提供的 url 会被缩短,并且使用 axios 的 GET 请求会重定向到不同的 URL(包含实际广告的 URL)。 Axios
    responseUrl
    与提供的网址不匹配。 (这已经处理好了,所以没问题)
  2. 当使用 Postman 测试部署的 api 中的函数时,axios
    responseUrl
    始终响应一个编码的 url,要求登录并包含实际的广告 url(decodeURIComponent url 并拆分字符串以获取实际的广告 url 句柄)这个很好

在任何情况下我都可以获得实际的广告网址,但是当使用 axios 向正确的、解码的广告网址发出 GET 请求,然后使用 Cheerio 解析它时,我得到与第 2 项中所述相同的网址。

提前感谢您提供有关 axios 或 facebook 废弃的任何建议或建议

这是我的代码(留下调试日志)

const cheerio = require('cheerio')
const axios = require('axios')

const timeout = 3000
const axiosInstance = axios.create({
  timeout: timeout
})

async function getImageURL(url) {

  //eslint-disable-next-line no-console
  console.log('getImageUrl fn invoked for arg url:', url)

  if (!url) {
    return null
  } else {
    try {

      // Gets url html content

      let axiosResponse = await axiosInstance.get(url)

      //eslint-disable-next-line no-console
      console.log(
        'axiosResponse.request.res.responseUrl: >>',
        axiosResponse.request.res.responseUrl
      )

      // Check for redirects: perform a new get to redirected url

      while (url !== axiosResponse.request.res.responseUrl) {

        //eslint-disable-next-line no-console
        console.log('>>>>> inside while loop <<<<<')

        //eslint-disable-next-line no-console
        console.log(
          'url equals responseUrl ?',
          url === axiosResponse.request.res.responseUrl
        )

        axiosResponse = await axiosInstance.get(
          axiosResponse.request.res.responseUrl
        )

        url = axiosResponse.request.res.responseUrl
      }

      //eslint-disable-next-line no-console
      console.log('\n =========== outside while loop ======= \n')

      //eslint-disable-next-line no-console
      console.log(
        'url equals responseUrl ?',
        url === axiosResponse.request.res.responseUrl
      )

      //eslint-disable-next-line no-console
      console.log(
        'axiosResponse.request.res.responseUrl: >>',
        axiosResponse.request.res.responseUrl
      )

      // Check for encoded url with requiring to login

      if (url.includes('login')) {
        //eslint-disable-next-line no-console
        console.log(`\nContains 'login'. Last GET performed to: ${url}\n`)

        const decodedURL = decodeURIComponent(url).split('next=')[1]
        //eslint-disable-next-line no-console
        console.log('decodedURL', decodedURL)

        axiosResponse = await axiosInstance.get(decodedURL)
      }

      const data = axiosResponse.data

      // Loads HTML to then parse image url

      const $ = cheerio.load(data)
      const metaTags = []

      $('meta').each(function (i) {
        metaTags[i] = $(this).attr()
      })

      //eslint-disable-next-line no-console
      console.log('meta tags elements with their attributes >>', metaTags)

      const imageURL = $("meta[property='og:image']").attr('content')

      //eslint-disable-next-line no-console
      console.log('obtained imageURL: ', imageURL)

      return imageURL ? imageURL : 'Url could not be parsed'

    } catch (error) {
      //eslint-disable-next-line no-console
      console.error('Error getImageURL: ', error.message)
      return null
    }
  }
}

module.exports = getImageURL

// this last part only when testing the function with node

async function main() {
  await getImageURL('insert your facebook ad url here')

main()
facebook axios cheerio scrape
1个回答
0
投票

不再需要答案,我很久以前就辞去了那份工作,是别人的问题。

© www.soinside.com 2019 - 2024. All rights reserved.