Pregunta

Tengo un programa que recupera la información de otras páginas y analiza ellos utilizando BeautifulSoup y getPage de trenzado. Más tarde en el programa puedo imprimir información de que el proceso crea diferido. Actualmente mi programa intenta imprimirlo antes de que vuelva diferían de la información. ¿Cómo puedo hacer que esperar?

def twisAmaz(contents): #This parses the page (amazon api xml file)
    stonesoup = BeautifulStoneSoup(contents)
    if stonesoup.find("mediumimage") == None:
       imageurl.append("/images/notfound.png")
    else:
      imageurl.append(stonesoup.find("mediumimage").url.contents[0])

    usedPdata = stonesoup.find("lowestusedprice")
    newPdata = stonesoup.find("lowestnewprice")
    titledata = stonesoup.find("title")
    reviewdata = stonesoup.find("editorialreview")

    if stonesoup.find("asin") != None:
        asin.append(stonesoup.find("asin").contents[0])
    else:
        asin.append("None")
    reactor.stop()


deferred = dict()
for tmpISBN in isbn:  #Go through ISBN numbers and get Amazon API information for each
    deferred[(tmpISBN)] = getPage(fetchInfo(tmpISBN))
    deferred[(tmpISBN)].addCallback(twisAmaz)
    reactor.run()

.....print info on each ISBN
¿Fue útil?

Solución

Lo que parece es que estamos tratando de hacer correr / múltiples reactores. Todo se une a la mismo reactor. Aquí es cómo utilizar un DeferredList que esperar a que todos sus devoluciones de llamada a fin.

Tenga en cuenta también que twisAmaz devuelve un valor. Ese valor se pasa a través de la callbacks DeferredList y sale como value. Desde un DeferredList mantiene el orden de las cosas que se ponen en ella, puede hacer una referencia cruzada el índice de los resultados con el índice de sus números ISBN.

from twisted.internet import defer

def twisAmaz(contents):
    stonesoup = BeautifulStoneSoup(contents)
    ret = {}
    if stonesoup.find("mediumimage") is None:
        ret['imageurl'] = "/images/notfound.png"
    else:
        ret['imageurl'] = stonesoup.find("mediumimage").url.contents[0]
    ret['usedPdata'] = stonesoup.find("lowestusedprice")
    ret['newPdata'] = stonesoup.find("lowestnewprice")
    ret['titledata'] = stonesoup.find("title")
    ret['reviewdata'] = stonesoup.find("editorialreview")
    if stonesoup.find("asin") is not None:
        ret['asin'] = stonesoup.find("asin").contents[0]
    else:
        ret['asin'] = 'None'
    return ret

callbacks = []
for tmpISBN in isbn:  #Go through ISBN numbers and get Amazon API information for each
    callbacks.append(getPage(fetchInfo(tmpISBN)).addCallback(twisAmazon))

def printResult(result):
    for e, (success, value) in enumerate(result):
        print ('[%r]:' % isbn[e]),
        if success:
            print 'Success:', value
        else:
            print 'Failure:', value.getErrorMessage()

callbacks = defer.DeferredList(callbacks)
callbacks.addCallback(printResult)

reactor.run()

Otros consejos

Otra manera fresca de hacerlo es con @ defer.inlineCallbacks. Se le permite escribir código asíncrono como una función secuencial normal: http : //twistedmatrix.com/documents/8.1.0/api/twisted.internet.defer.html#inlineCallbacks

En primer lugar, no debe poner un reactor.stop () en el método diferido, ya que mata todo.

Ahora, en Twisted, no está permitido "en espera". Para imprimir los resultados de devolución de llamada, sólo tiene que añadir otra llamada de retorno después de la primera.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top