Recientemente he estado aprendiendo Python y estoy metiendo mi mano en la construcción de un raspador de web. No es nada lujoso en absoluto; su único propósito es sacar los datos de un sitio web de apuestas y tener estos datos en Excel.
La mayoría de los problemas se pueden resolver y estoy teniendo un buen lío. Sin embargo, estoy llegando a un obstáculo masivo sobre un problema. Si un sitio carga una tabla de caballos y enumera los precios actuales de las apuestas, esta información no se encuentra en ningún archivo fuente. La pista es que estos datos están en vivo a veces, y los números se actualizan obviamente desde algún servidor remoto. El HTML en mi PC simplemente tiene un agujero donde sus servidores están empujando a través de todos los datos interesantes que necesito.
Ahora mi experiencia con el contenido web dinámico es baja, por lo que esto es algo que estoy teniendo problemas para entender.
Creo que Java o Javascript es una clave, esto aparece a menudo.
El rascador es simplemente un motor de comparación de probabilidades. Algunos sitios tienen API, pero necesito esto para aquellos que no. Estoy usando la biblioteca scrapy con Python 2.7
Me disculpo si esta pregunta es demasiado abierta. En resumen, mi pregunta es: ¿cómo se puede usar scrapy para raspar estos datos dinámicos para que pueda usarlos? ¿Para poder raspar estos datos de probabilidades de apuestas en tiempo real?
fuente
Firefox
extensiones comohttpFox
oliveHttpHeaders
y cargue una página que esté usando la solicitud ajax. Scrapy no identifica automáticamente las solicitudes de ajax, debe buscar manualmente la URL de ajax adecuada y luego solicitarla con eso.Respuestas:
Los navegadores basados en Webkit (como Google Chrome o Safari) tienen herramientas de desarrollador integradas. En Chrome puedes abrirlo
Menu->Tools->Developer Tools
. LaNetwork
pestaña le permite ver toda la información sobre cada solicitud y respuesta:En la parte inferior de la imagen, puede ver que he filtrado la solicitud a
XHR
: estas son solicitudes realizadas por código javascript.Consejo: el registro se borra cada vez que carga una página, en la parte inferior de la imagen, el botón de punto negro conservará el registro.
Después de analizar las solicitudes y respuestas, puede simular estas solicitudes desde su rastreador web y extraer datos valiosos. En muchos casos, será más fácil obtener sus datos que analizar HTML, ya que esos datos no contienen lógica de presentación y están formateados para acceder a ellos mediante un código JavaScript.
Firefox tiene una extensión similar, se llama firebug . Algunos argumentarán que Firebug es aún más poderoso, pero me gusta la simplicidad del webkit.
fuente
Aquí hay un ejemplo simple de
scrapy
con una solicitud AJAX. Deje ver el sitio rubin-kazan.ru .Todos los mensajes se cargan con una solicitud AJAX. Mi objetivo es obtener estos mensajes con todos sus atributos (autor, fecha, ...):
Cuando analizo el código fuente de la página, no puedo ver todos estos mensajes porque la página web utiliza tecnología AJAX. Pero puedo con Firebug de Mozilla Firefox (o una herramienta equivalente en otros navegadores) para analizar la solicitud HTTP que genera los mensajes en la página web:
No recarga toda la página, sino solo las partes de la página que contienen mensajes. Para este propósito, hago clic en un número arbitrario de página en la parte inferior:
Y observo la solicitud HTTP que es responsable del cuerpo del mensaje:
Después de terminar, analizo los encabezados de la solicitud (debo citar que esta URL extraeré de la página de origen de la sección var, vea el código a continuación):
Y el contenido de los datos del formulario de la solicitud (el método HTTP es "Publicar"):
Y el contenido de la respuesta, que es un archivo JSON:
Que presenta toda la información que estoy buscando.
A partir de ahora, debo implementar todo este conocimiento en scrapy. Definamos la araña para este propósito:
En
parse
función tengo la respuesta para la primera solicitud. EnRubiGuessItem
Tengo el archivo JSON con toda la información.fuente
re
módulo (expresiones regulares), busca la cadena'url_list_gb_messages="(.*)"'
y aísla el contenido de paréntesis en la variable del mismo nombre. Esta es una buena introducción: guru99.com/python-regular-expressions-complete-tutorial.htmlMuchas veces al rastrear nos encontramos con problemas en los que el contenido que se representa en la página se genera con Javascript y, por lo tanto, scrapy no puede rastrearlo (por ejemplo, solicitudes ajax, locura jQuery).
Sin embargo, si usa Scrapy junto con el marco de prueba web Selenium, entonces podemos rastrear todo lo que se muestra en un navegador web normal.
Algunas cosas a tener en cuenta:
Debe tener instalada la versión Python de Selenium RC para que esto funcione, y debe haber configurado Selenium correctamente. Además, este es solo un rastreador de plantillas. Podrías ponerte más loco y más avanzado con las cosas, pero solo quería mostrar la idea básica. Tal como está el código ahora, hará dos solicitudes para cualquier URL dada. Scrapy realiza una solicitud y Selenium realiza la otra. Estoy seguro de que hay formas de evitar esto para que puedas hacer que Selenium haga la única solicitud, pero no me molesté en implementar eso y al hacer dos solicitudes, también puedes rastrear la página con Scrapy.
Esto es bastante poderoso porque ahora tiene todo el DOM renderizado disponible para que pueda rastrear y aún puede usar todas las características de rastreo agradables en Scrapy. Por supuesto, esto hará que el rastreo sea más lento, pero dependiendo de cuánto necesite el DOM renderizado, la espera podría valer la pena.
Referencia: http://snipplr.com/view/66998/
fuente
selenium=3.3.1
ypython=2.7.10
, error al importar selenio desde seleniofrom selenium import webdriver
ochromedriver
o lo que sea que se esté utilizando. Docs EDIT: ¡agregue referencias de documentación y cambie mi gramática horrible!Otra solución sería implementar un controlador de descarga o middleware del controlador de descarga. (consulte documentos de Scrapy para obtener más información sobre el middleware del descargador) La siguiente es una clase de ejemplo que utiliza selenio con webdriver phantomjs sin cabeza:
1) Definir clase dentro del
middlewares.py
script.2) Agregar
JsDownload()
clase a variableDOWNLOADER_MIDDLEWARE
dentro desettings.py
:3) Integrar el
HTMLResponse
interioryour_spider.py
. Decodificar el cuerpo de respuesta le dará la salida deseada.Complemento opcional:
quería la capacidad de decirle a las diferentes arañas qué middleware usar, así que implementé este contenedor:
Para que la envoltura funcione, todas las arañas deben tener como mínimo:
para incluir un middleware:
Ventaja:
La principal ventaja de implementarlo de esta manera en lugar de hacerlo en la araña es que solo terminas haciendo una solicitud. En la solución de AT, por ejemplo: el controlador de descarga procesa la solicitud y luego entrega la respuesta a la araña. La araña hace una nueva solicitud en su función parse_page: son dos solicitudes para el mismo contenido.
fuente
process_requests
,if spider.name in ['spider1', 'spider2']
en lugar del decoradorEstaba usando un middleware de descarga personalizado, pero no estaba muy contento con él, ya que no pude hacer que el caché funcionara con él.
Un mejor enfoque fue implementar un controlador de descarga personalizado.
Hay un ejemplo de trabajo aquí . Se parece a esto:
Supongamos que su raspador se llama "raspador". Si coloca el código mencionado dentro de un archivo llamado handlers.py en la raíz de la carpeta "scraper", entonces podría agregar a su settings.py:
Y voilà, el DOM analizado JS, con caché fragmentado, reintentos, etc.
fuente
Me pregunto por qué nadie ha publicado la solución usando solo Scrapy.
Echa un vistazo a la publicación del blog del equipo Scrapy SCRAPING INFINITE SCROLLING PAGES . El ejemplo desecha http://spidyquotes.herokuapp.com/scroll sitio web que utiliza desplazamiento infinito.
La idea es utilizar las Herramientas de desarrollo de su navegador y notar las solicitudes de AJAX, luego, basándose en esa información, cree las solicitudes de Scrapy .
fuente
Sí, Scrapy puede eliminar sitios web dinámicos, sitios web que se representan a través de JavaScript.
Hay dos enfoques para eliminar este tipo de sitios web.
Primero,
puede usar
splash
para representar el código Javascript y luego analizar el HTML representado. puedes encontrar el documento y proyectar aquí Scrapy splash, gitSegundo,
Como todos dicen, al monitorear
network calls
, sí, puede encontrar la llamada a la API que obtiene los datos y se burla de esa llamada en su araña temblorosa que podría ayudarlo a obtener los datos deseados.fuente
Manejo la solicitud ajax usando Selenium y el controlador web Firefox. No es tan rápido si necesita el rastreador como demonio, pero es mucho mejor que cualquier solución manual. Escribí un breve tutorial aquí para referencia
fuente