Python Scrapy项目,如何使用相同的蜘蛛废弃1000页?

时间:2012-08-23 03:12:09

标签: python mysql scrapy web-crawler

我必须废弃1000条结构相似的链接,但内容不同。

我设计了这个蜘蛛,但是我不想把每个url放在start_urls中,运行它并重复1000次,我把它们都放在一个文件中,所以我怎样才能以发送start_url的方式重复这个过程作为参数并用a做1000次......

1 个答案:

答案 0 :(得分:1)

创建一个覆盖BaseSpider的 init 方法的蜘蛛。在其中,解析文件并将它们附加到start_urls列表。

代码看起来像这样:

def __init__(self, *args, **kwargs):
     #load the file here
     super(DmozSpider, self).__init__()         
     for url in some_file:
         self.start_urls.append[url]

显然,循环文件的方式取决于文件的类型。

此外,您可能会考虑使用items管道并在解析数据后使用mysqldb管道来保存数据。

修改

我会为你重写你的蜘蛛。从技术上讲,最好使用管道来处理你正在做的事情,但是,为了时间的推移,我会让你当前的蜘蛛工作。一会儿。

试一下

    # -*- coding: utf-8 -*-
#Por: Daniel Ortiz Costa, Ivo Andres Astudillo, Ruben Quezada
#Proyecto de Academias Web - Extraer publicaciones de Scopus

from scrapy.spider import BaseSpider
from scrapy.selector import HtmlXPathSelector
import datetime
import MySQLdb

class DmozSpider(BaseSpider):
    name = "scrapyscopus"

    start_urls = ["http://www.scopus.com/inward/record.url?partnerID=HzOxMe3b&scp=84858710280",]

    #id de la url actual
    id_paper_web = ""

    #Variables de la base de datos
    abstracto = ""
    keywords = ""
    anio_publicacion = ""
    tipo_documento = ""
    tipo_publicacion = ""    
    descripcion = ""
    volume_info = ""
    idioma = ""
    fecha_consulta = ""
    nombres = {}
    instituciones = {}

    #La probabilidad de que el articulo sea de alguien que buscamos
    probabilidad = 0

    def __init__(self, *args, **kwargs):
        super(DmozSpider, self).__init__()

        #load file here
        for url in some_file:
            self.start_urls.append[url]


    def parse(self, response):

        #Recibe el codigo de la pagina en la response
        hxs = HtmlXPathSelector(response)

        self.obtenerId(response.url)

        #La probabilidad de exito consta de 3 factores
        #1 - Probabilidad del 25% por pertenecer al pais
        #2 - Probabilidad del 25% por tener la misma inicial y apellido
        #3 - Probabilidad del 35% porque el articulo tenga a alguien de la universidad
        #4 - Probabilidad del 15% si es que todos los del articulo son de la universidad

        #Las dos primeras condiciones ya se cumplieron, por lo que se suma 50%
        #la otra se determinará leyendo las instituciones dentro del código 
        self.probabilidad = self.probabilidad+50;

        #ABSTRACTO
        #Se extrae el abstracto que es el parrafo que contiene un valor align=justify
        lista =  hxs.select('//p[contains(@align, "justify")]/text()')  

        #Se saca el texto
        self.abstracto = lista[0].extract()

        #KEYWORDS
        #Se encuentran en el ultimo resultado de la lista de parrafos con clase marginB3
        lista =  hxs.select('//p[@class="marginB3"]/text()')          

        #Se saca el texto del ultimo resultado
        self.keywords = lista[len(lista)-1].extract()

        #TIPO DE PUB, TIPO DE DOC E IDIOMA
        #Se encuentran todos con la clase paddingR15
        lista =  hxs.select('//span[@class="paddingR15"]')

        #Se analiza cada uno de los span recibidos en busca del correcto
        for i in lista:

            #Se analiza el strong que retiene la descripcion de lo que vemos
            #Para sacar el lenguaje por ejemplo, debemos buscar la linea "Original Language"
            #Luego de ello proceder a extraer el texto del span padre

            if (str(i.select('.//strong/text()').extract()[0]) == "Source Type: "):
                self.tipo_publicacion=i.select('text()').extract()[0]; 

            if (str(i.select('.//strong/text()').extract()[0]) == "Original language: "):
                self.idioma=i.select('text()').extract()[1];

            if (str(i.select('.//strong/text()').extract()[0]) == "Document Type: "):
                self.tipo_documento=i.select('text()').extract()[0]; 

        #FECHA DE CONSULTA
        #Para la fecha de consulta se obtiene la fecha actual
        self.fecha_consulta = datetime.datetime.now().strftime("%Y-%m-%d")


        #DESCRIPCION
        #La descripcion se encuentra formada por la zona del encabezado
        #Se extrae primeramente el titulo, que es un h2 de clase sourceTitle
        lista =  hxs.select('//h2[@class="sourceTitle"]/text()') 

        #Luego se la agrega a la cadena de descripcion
        self.descripcion=self.descripcion+str(lista[0].extract())+"\n";

        #Se obtiene la informacion del volumen que tambien pertenece a la descripcion
        lista =  hxs.select('//div[@class="volumeInfo"]/text()')             

        #Se la extrae
        self.volume_info=str(lista[0].extract())

        #Se la agrega a la cadena de la descripcion
        self.descripcion=self.descripcion+self.volume_info

        #Se debe extraer el anio de publicacion desde la informacion de volumeen
        #Para ello se llama al metodo respectivo que se encarga de la extraccion
        self.obtenerAnioPublicacion()


        #AUTORES
        #Se determina el parrafo donde se encuentran los nombres de los autores
        lista =  hxs.select('//p[@class="smallLink authorlink svDoNotLink paddingB5"]')

        #Se seleccionan  los span directos de ese parrafo
        lista = lista.select('span')

        for elemento in lista:

            lista2 = elemento.select('.//sup')

            for i in lista2:
                self.nombres[elemento.select('.//span[@class="previewTxt"]/text()').extract()[0]]=i.select('text()').extract()[0]
                break;


        #DIRECCIONES
        #Se determina el parrafo donde se encuentran los nombres de los autores
        lista =  hxs.select('//p[@class="affilTxt"]')

        #Se determina una nueva lista con los sup y su texto
        lista2 = lista.select('.//sup/text()')

        #Se la lista siguiente mostrará los datos procesados
        letras=[]

        #Obtendrá la letra de cada publicación
        for i in lista2:
            letra = str(i.extract()[0])
            letras.append(letra)

        #Se determina el parrafo donde se encuentran los nombres de los autores
        lista3 = lista.select('text()')

        institucion=[]

        contador=0;

        for i in lista3:

            if(i.extract()!="\n"):
                if "Loja" in i.extract():
                    contador=contador+1

                institucion.append(i.extract())

        if contador>=1:
            if contador==1:
                self.probabilidad=self.probabilidad+35
            else:
                if contador==len(institucion):
                    self.probabilidad=self.probabilidad+15

        self.instituciones=dict(zip(letras, institucion))

        self.guardarDatos()

    """
    Metodo responsable de obtener el 
    anio de publicacion del articulo.
    """
    def obtenerAnioPublicacion(self):

        #Divide el volumen de acuerdo a la , que posee
        componentes=self.volume_info.split(', ')      

        #Dependiendo del tipo de publicacion, la posicion del anio variara
        if(self.tipo_publicacion == "Journal"):            
            self.anio_publicacion=componentes[2]

        else:
            self.anio_publicacion=componentes[0]



    """
    Metodo de obtener el id de la url actual
    """
    def obtenerId(self, url):   

        db = MySQLdb.connect("localhost","root","","proyectoacademias" )

        cursor = db.cursor()

        sql = "SELECT id FROM test WHERE url like \'"
        sql = sql + url
        sql = sql + "\'"

        cursor.execute(sql)

        data = cursor.fetchone()

        for row in data:
            print str(row)
            self.id_paper_web=str(row)

        db.close()



    """
    Metodo de guardar los datos

    """
    def guardarDatos(self):
        db = MySQLdb.connect("localhost","root","","proyectoacademias" )

        cursor = db.cursor()

        sql = "UPDATE test SET abstract=\'"+str(self.abstracto)+"\', fecha_consulta=\'"+str(self.fecha_consulta)+"\', anio_publicacion=\'"+str(self.anio_publicacion)+"\', probabilidad="+str(self.probabilidad)+" WHERE id = "+str(self.id_paper_web)

        print "\n\n\n"+sql+"\n\n\n"
        cursor.execute(sql)      
        db.commit()

        for i in range (len(self.nombres)):
            sql = "INSERT INTO test_autores VALUES (\'"+self.nombres.keys()[i]+"\', "+str(self.id_paper_web)+", \'"+self.instituciones[self.nombres[self.nombres.keys()[i]]]+"\', "+str((i+1))+")"
            print "\n\n\n"+sql+"\n\n\n"
            cursor.execute(sql)
            db.commit()

        db.close()

除了修改 init 和obtenerId方法之外,我没有做任何改变。