scraping - scrapy python español
Ejemplo muy básico de Scrapy (2)
Hola, tengo instalado Python Scrapy en mi mac e intento seguir el primer ejemplo en su web.
Estaban tratando de ejecutar el comando:
scrapy crawl mininova.org -o scraped_data.json -t json
No entiendo muy bien qué significa esto? parece que el tratamiento con medicamentos es un programa separado. Y no creo que tengan un comando llamado rastreo. En el ejemplo, tienen un párrafo de código, que es la definición de la clase MininovaSpider y TorrentItem. No sé a dónde deberían ir estas dos clases, vaya al mismo archivo y ¿cuál es el nombre de este archivo python?
Es posible que tenga más suerte mirando primero el tutorial , en contraposición a la página web "Scrapy at the glance".
El tutorial implica que Scrapy es, de hecho, un programa separado.
Al ejecutar el comando scrapy startproject tutorial
se creará una carpeta llamada tutorial
varios archivos ya configurados para usted.
Por ejemplo, en mi caso, los módulos / paquetes items
, pipelines
, settings
y spiders
se han agregado al tutorial
paquete raíz.
tutorial/
scrapy.cfg
tutorial/
__init__.py
items.py
pipelines.py
settings.py
spiders/
__init__.py
...
La clase TorrentItem
se colocaría dentro de items.py
, y la clase MininovaSpider
iría dentro de la carpeta spiders
.
Una vez que el proyecto está configurado, los parámetros de línea de comando para Scrapy parecen ser bastante sencillos. Ellos toman la forma:
scrapy crawl <website-name> -o <output-file> -t <output-type>
Alternativamente, si desea ejecutar scrapy sin la sobrecarga de crear un directorio de proyecto, puede usar el comando runspider :
scrapy runspider my_spider.py
TL; DR: vea el script de ejemplo mínimo autónomo para ejecutar scrapy .
En primer lugar, tener un proyecto de Scrapy normal con un archivo .cfg
, settings.py
, pipelines.py
, items.py
, spiders
, etc. separados es una forma recomendada de mantener y manejar su lógica de raspado web. Proporciona una modularidad, separación de preocupaciones que mantiene las cosas organizadas, claras y comprobables.
Si está siguiendo el tutorial oficial de Scrapy para crear un proyecto, está ejecutando el scrapy
web a través de una scrapy
especial de scrapy
comandos de scrapy
:
scrapy crawl myspider
Pero, Scrapy
también proporciona una API para ejecutar el rastreo de un script .
Hay varios conceptos clave que deben mencionarse:
- Clase de
Settings
: básicamente un "contenedor" de clave-valor que se inicializa con los valores predeterminados incorporados - Clase de
Crawler
- la clase principal que actúa como un pegamento para todos los diferentes componentes implicados en el raspado web con Scrapy - Torcido
reactor
- ya que Scrapy está integrado en la parte superior de la biblioteca de red asíncronatwisted
- para iniciar un rastreador, tenemos que ponerlo dentro de Twisted Reactor , que es en palabras simples, un ciclo de eventos:
El reactor es el núcleo del bucle de eventos dentro de Twisted, el bucle que impulsa aplicaciones que usan Twisted. El bucle de eventos es una construcción de programación que espera y envía eventos o mensajes en un programa. Funciona llamando a un "proveedor de eventos" interno o externo, que generalmente bloquea hasta que llega un evento, y luego llama al controlador de eventos relevante ("despacha el evento"). El reactor proporciona interfaces básicas para una serie de servicios, incluidas las comunicaciones de red, el enhebrado y el envío de eventos.
Aquí hay un proceso básico y simplificado para ejecutar Scrapy desde el script:
crea una instancia de
Settings
(o usaget_project_settings()
para usar la configuración existente):settings = Settings() # or settings = get_project_settings()
instanciar
Crawler
con la instancia desettings
pasada:crawler = Crawler(settings)
instanciar una araña (de esto se trata finalmente, ¿no?):
spider = MySpider()
configurar señales. Este es un paso importante si desea tener una lógica de procesamiento posterior, recopilar estadísticas o, al menos, terminar de rastrear ya que el
reactor
trenzado debe detenerse manualmente. Los documentos de Scrapy sugieren detener elreactor
en elspider_closed
señalspider_closed
:
Tenga en cuenta que también tendrá que apagar el reactor Twisted usted mismo después de que la araña haya terminado. Esto se puede lograr conectando un controlador a la señal signal.spider_closed.
def callback(spider, reason):
stats = spider.crawler.stats.get_stats()
# stats here is a dictionary of crawling stats that you usually see on the console
# here we need to stop the reactor
reactor.stop()
crawler.signals.connect(callback, signal=signals.spider_closed)
configurar e iniciar la instancia de rastreador con una spider pasada:
crawler.configure() crawler.crawl(spider) crawler.start()
opcionalmente iniciar el logging :
log.start()
iniciar el reactor: esto bloquearía la ejecución del script:
reactor.run()
Aquí hay un ejemplo de script autocontenido que utiliza la araña DmozSpider
e involucra cargadores de elementos con procesadores de entrada y salida y tuberías de artículos :
import json
from scrapy.crawler import Crawler
from scrapy.contrib.loader import ItemLoader
from scrapy.contrib.loader.processor import Join, MapCompose, TakeFirst
from scrapy import log, signals, Spider, Item, Field
from scrapy.settings import Settings
from twisted.internet import reactor
# define an item class
class DmozItem(Item):
title = Field()
link = Field()
desc = Field()
# define an item loader with input and output processors
class DmozItemLoader(ItemLoader):
default_input_processor = MapCompose(unicode.strip)
default_output_processor = TakeFirst()
desc_out = Join()
# define a pipeline
class JsonWriterPipeline(object):
def __init__(self):
self.file = open(''items.jl'', ''wb'')
def process_item(self, item, spider):
line = json.dumps(dict(item)) + "/n"
self.file.write(line)
return item
# define a spider
class DmozSpider(Spider):
name = "dmoz"
allowed_domains = ["dmoz.org"]
start_urls = [
"http://www.dmoz.org/Computers/Programming/Languages/Python/Books/",
"http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/"
]
def parse(self, response):
for sel in response.xpath(''//ul/li''):
loader = DmozItemLoader(DmozItem(), selector=sel, response=response)
loader.add_xpath(''title'', ''a/text()'')
loader.add_xpath(''link'', ''a/@href'')
loader.add_xpath(''desc'', ''text()'')
yield loader.load_item()
# callback fired when the spider is closed
def callback(spider, reason):
stats = spider.crawler.stats.get_stats() # collect/log stats?
# stop the reactor
reactor.stop()
# instantiate settings and provide a custom configuration
settings = Settings()
settings.set(''ITEM_PIPELINES'', {
''__main__.JsonWriterPipeline'': 100
})
# instantiate a crawler passing in settings
crawler = Crawler(settings)
# instantiate a spider
spider = DmozSpider()
# configure signals
crawler.signals.connect(callback, signal=signals.spider_closed)
# configure and start the crawler
crawler.configure()
crawler.crawl(spider)
crawler.start()
# start logging
log.start()
# start the reactor (blocks execution)
reactor.run()
Ejecútelo de la manera habitual:
python runner.py
y observe los artículos exportados a items.jl
con la ayuda de la tubería:
{"desc": "", "link": "/", "title": "Top"}
{"link": "/Computers/", "title": "Computers"}
{"link": "/Computers/Programming/", "title": "Programming"}
{"link": "/Computers/Programming/Languages/", "title": "Languages"}
{"link": "/Computers/Programming/Languages/Python/", "title": "Python"}
...
Gist está disponible aquí (no dudes en mejorar):
Notas:
Si define la settings
al crear una instancia de un objeto de Settings()
, obtendrá todos los ajustes predeterminados de Scrapy. Pero, si quiere, por ejemplo, configurar una canalización existente, o configurar un DEPTH_LIMIT
o modificar cualquier otra configuración, debe establecerlo en la secuencia de comandos mediante settings.set()
(como se demostró en el ejemplo):
pipelines = {
''mypackage.pipelines.FilterPipeline'': 100,
''mypackage.pipelines.MySQLPipeline'': 200
}
settings.set(''ITEM_PIPELINES'', pipelines, priority=''cmdline'')
o use una settings.py
existente con todas las configuraciones personalizadas preconfiguradas:
from scrapy.utils.project import get_project_settings
settings = get_project_settings()
Otros enlaces útiles sobre el tema: