Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

198
Views
Al usar request (), la página devuelta aún no contiene los datos necesarios; en su lugar, se devuelve una página incompleta. ¿Cómo puedo 'esperar'?

Estoy tratando de extraer el año, la marca, el modelo, el color y el número de placa de carjam.co.nz. Un ejemplo de una URL de la que estoy raspando es https://www.carjam.co.nz/car/?plate=JKY242 .

Si la placa ha sido solicitada recientemente, la respuesta será un documento HTML con los detalles del vehículo.

Resultado donde los detalles de la placa han sido solicitados recientemente. Resultado donde los detalles de la placa han sido solicitados recientemente.

Si los detalles de la placa no se han solicitado recientemente (como es el caso con la mayoría de las placas), la respuesta es un documento HTML con "Intentando obtener algunos datos del vehículo". Supongo que esta página se muestra mientras se obtiene la información de la base de datos, luego la página se vuelve a cargar para mostrar los detalles del vehículo. Esto parece ser del lado del servidor, no puedo ver ninguna solicitud de AJAX.

La URL es la misma para cada resultado.

Resultado donde los detalles de la placa no han sido solicitados recientemente. Resultado donde el vehículo no ha sido solicitado recientemente.

¿Cómo 'espero' la información correcta?

Estoy usando request (en desuso, lo sé, pero es lo que me siento más cómodo usando) en un servidor Node.js con Express.

Mi código (muy reducido):

 app.get("/:numberPlate", (req, res) => { request("https://www.carjam.co.nz/car/?plate=" + req.params.numberPlate, function(error, response, body) { const $ = cheerio.load(body); res.status(200).send(JSON.stringify({ year: $("[data-key=year_of_manufacture]").next().html(), make: toTitleCase($("[data-key=make]").next().html()), model: toTitleCase($("[data-key=model]").next().html()), colour: toTitleCase($("[data-key=main_colour]").next().html()), })); } }

He considerado:

  • Hacer una solicitud y descartarla, dormir durante 2 o 3 segundos y luego hacer una segunda solicitud. La ventaja de este enfoque es que todas las solicitudes funcionarían. La desventaja es que cada solicitud tarda de 2 a 3 segundos (demasiado lento).
  • Realización de una solicitud y verificación para ver si el cuerpo contiene "Intentando obtener algunos datos del vehículo". Si es así, duerma unos segundos, haga otra solicitud y tome medidas sobre el resultado de esa segunda solicitud (¿pero cómo?).

Estoy seguro de que este es un problema común con una respuesta fácil, pero no tengo suficiente experiencia para resolverlo yo mismo, ¡o para saber exactamente qué buscar en Google!


Para probar: Nueva Zelanda tiene lugares numéricos en el formato "ABC123": tres letras, tres números. Estos se lanzan en orden alfabético, actualmente no tenemos nada más allá de NLU999 (excluyendo placas de matrícula personalizadas, placas de matrícula emitidas fuera de secuencia, etc.).

Para reproducir el "Intento de obtener algunos datos del vehículo", debe encontrar una nueva placa de matrícula cada vez; la mayoría de las placas de matrícula anteriores en la secuencia que NLU999 deberían funcionar.

Este fragmento de código debería generar una placa de matrícula válida.

 console.log(Math.random().toString(36).replace(/[^an]+/g, '').substr(0, 1).toUpperCase() + Math.random().toString(36).replace(/[^az]+/g, '').substr(0, 2).toUpperCase() + Math.floor(Math.random() * 10).toString() + Math.floor(Math.random() * 10).toString() + Math.floor(Math.random() * 10).toString());


05 de mayo de 2021 actualización

Después de pensarlo más, este pseudocódigo podría ser lo que busco, pero no estoy seguro de cómo implementarlo en la práctica.

 request(url) { if (url body contains "Trying to get some vehicle data") { wait(2 seconds) request(url again) { return second_result } } else { return first_result } } then process(first_result or second_result)

Mi dificultad aquí: estoy acostumbrado al formato request().then() , actuando directamente desde la solicitud.

Suponiendo que este enfoque sea correcto, ¿cómo llevaría a cabo lo siguiente?

  1. Envíe la solicitud, luego
  2. Evalúa la respuesta, luego
  3. Pase esta respuesta o envíe otra solicitud y luego pase esa respuesta a
  4. Respuesta del proceso
over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

A partir de este archivo javascript , el sitio web carga la página cada X segundos si no se encuentran los datos con un reintento máximo establecido en 10. Además, el valor de actualización en segundos se recupera del valor del encabezado Refresh http.

Puede reproducir este flujo, de modo que tenga exactamente el mismo comportamiento que el código de interfaz.

En el siguiente ejemplo estoy usando axios

 const axios = require("axios"); const cheerio = require("cheerio"); const rootUrl = "https://www.carjam.co.nz/car/"; const plate = "NLU975"; const maxRetry = 10; const waitingString = "Waiting for a few more things"; async function getResult() { return axios.get(rootUrl, { params: { plate: plate, }, }); } async function processRetry(result) { const refreshSeconds = parseInt(result.headers["refresh"]); var retryCount = 0; while (retryCount < maxRetry) { console.log( `retry: ${retryCount} time, waiting for ${refreshSeconds} second(s)` ); retryCount++; await timeout(refreshSeconds * 1000); result = await getResult(); if (!result.data.includes(waitingString)) { break; } } return result; } (async () => { var result = await getResult(); if (result.data.includes(waitingString)) { result = await processRetry(result); } const $ = cheerio.load(result.data); console.log({ year: $("[data-key=year_of_manufacture]").next().html(), make: $("[data-key=make]").next().html(), model: $("[data-key=model]").next().html(), colour: $("[data-key=main_colour]").next().html(), }); })(); function timeout(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); }

enlace repl.it: https://replit.com/@bertrandmartel/ScrapeCarJam

Salida de muestra:

 retry: 0 time, waiting for 1 second(s) retry: 1 time, waiting for 1 second(s) retry: 2 time, waiting for 1 second(s) { year: 'XXXX', make: 'XXXXXX', model: 'XX', colour: 'XXXX' }

Utiliza async/await en lugar de promesa.

Tenga en cuenta que la solicitud está en desuso

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!