Esta es una API no oficial que le permite acceder a algunos de los datos de AO3 (ArchiveOfourown.org) a través de Python.
Use el Pip Pip Pip para instalar AO3 API.
pip install ao3_api
https://github.com/armindoflores/ao3_api
Este paquete se divide en 9 módulos centrales: obras, capítulos, usuarios, series, búsqueda, sesión, comentarios, extra y utilizados.
Una de las cosas más básicas que quiera hacer con este paquete es cargar un trabajo y verificar sus estadísticas e información. Para hacer eso, necesitará la clase AO3.Work
.
Comenzamos por encontrar el trabajo del trabajo que queremos cargar. Hacemos eso utilizando AO3.utils.workid_from_url(url)
o simplemente mirando la URL nosotros mismos. Echemos un vistazo:
import AO3
url = "https://archiveofourown.org/works/14392692/chapters/33236241"
workid = AO3 . utils . workid_from_url ( url )
print ( f"Work ID: { workid } " )
work = AO3 . Work ( workid )
print ( f"Chapters: { work . nchapters } " )
Después de ejecutar este fragmento, obtenemos la salida:
Work ID: 14392692
Chapters: 46
Es importante tener en cuenta que algunas obras pueden no ser accesibles para los usuarios invitados, y en este caso obtendrá 0 capítulos como salida, y el error AO3.utils.AuthError: This work is only available to registered users of the Archive
si usted Intenta cargarlo. Sin embargo, todavía podemos hacer mucho más con este objeto de trabajo: intentemos obtener las primeras 20 palabras del segundo capítulo.
import AO3
work = AO3 . Work ( 14392692 )
print ( work . chapters [ 1 ]. title ) # Second chapter name
text = work . chapters [ 1 ]. text # Second chapter text
print ( ' ' . join ( text . split ( " " )[: 20 ]))
What Branches Grow Meaning
December 27, 2018
Christmas sucked this year, and Shouto’s got the black eye to prove it.
Things had started out well enough,
Los objetos en el trabajo. Los capítulos son de tipo AO3.Chapter
. Tienen muchas de las mismas propiedades que un objeto Work
.
Otra cosa que puede hacer con el objeto de trabajo es descargar todo el trabajo como PDF o libro electrónico. En este momento puede descargar obras como archivos AZW3, EPUB, HTML, MOBI y PDF.
import AO3
work = AO3 . Work ( 14392692 )
with open ( f" { work . title } .pdf" , "wb" ) as file :
file . write ( work . download ( "PDF" ))
Funcionalidad avanzada
Por lo general, cuando llama al constructor para la clase Work
, toda la información sobre ella se carga en la función __init__()
. Sin embargo, este proceso lleva bastante tiempo (~ 1-1.5 segundos) y si desea cargar una lista de obras de una serie, por ejemplo, es posible que esté esperando más de 30 segundos. Para evitar este problema, la función Work.reload()
, llamada Inicialización, es una función "enhebrible", lo que significa que si lo llama con el argumento threaded=True
, devolverá un objeto Thread
y funcionará en paralelo, lo que es decir Puede cargar múltiples trabajos al mismo tiempo. Echemos un vistazo a una implementación:
import AO3
import time
series = AO3 . Series ( 1295090 )
works = []
threads = []
start = time . time ()
for work in series . work_list :
works . append ( work )
threads . append ( work . reload ( threaded = True ))
for thread in threads :
thread . join ()
print ( f"Loaded { len ( works ) } works in { round ( time . time () - start , 1 ) } seconds." )
Loaded 29 works in 2.2 seconds.
load=False
dentro del constructor Work
se asegura de que no cargamos el trabajo tan pronto como creamos una instancia de la clase. Al final, iteramos sobre cada hilo y esperamos el último para terminar de usar .join()
. Comparemos este método con la forma estándar de cargar AO3 Works:
import AO3
import time
series = AO3 . Series ( 1295090 )
works = []
start = time . time ()
for work in series . work_list :
work . reload ()
works . append ( work )
print ( f"Loaded { len ( works ) } works in { round ( time . time () - start , 1 ) } seconds." )
Loaded 29 works in 21.6 seconds.
Como podemos ver, hay un aumento significativo de rendimiento. Hay otras funciones en este paquete que tienen esta funcionalidad. Para ver si una función es "enhebrable", use hasattr(function, "_threadable")
o verifique su cadena __doc__
.
Para ahorrar aún más tiempo, si solo está interesado en los metadatos, puede cargar un trabajo con la opción load_chapters
establecida en False. Además, tenga en cuenta que algunas funciones (como Series.work_list
o Search.results
) podrían devolver objetos Work
semi-cargados. Esto significa que no se han realizado solicitudes para cargar este trabajo (por lo que no tiene acceso a texto del capítulo, notas, etc.), pero casi todos sus metadatos ya habrán sido almacenados en caché, y es posible que no necesite llamar Work.reload()
en absoluto.
La última información importante sobre la clase Work
es que la mayoría de sus propiedades (como el número de marcadores, felicitaciones, nombres de los autores, etc.) son propiedades en caché. Eso significa que una vez que los verifica una vez, el valor se almacena y nunca cambiará, incluso si esos valores cambian. Para actualizar estos valores, deberá llamar Work.reload()
. Vea el ejemplo a continuación:
import AO3
sess = AO3 . GuestSession ()
work = AO3 . Work ( 16721367 , sess )
print ( work . kudos )
work . leave_kudos ()
work . reload ()
print ( work . kudos )
392
393
Otra cosa útil que quizás desee hacer es obtener información sobre quién escribió qué funciona / comentarios. Para eso, usamos la clase AO3.User
.
import AO3
user = AO3 . User ( "bothersomepotato" )
print ( user . url )
print ( user . bio )
print ( user . works ) # Number of works published
https://archiveofourown.org/users/bothersomepotato
University student, opening documents to write essays but writing this stuff instead. No regrets though. My Tumblr, come chat with -or yell at- me if you feel like it! :)
2
Para buscar obras, puede usar la función AO3.search()
y analizar el objeto BeautifulSoup devuelto usted mismo, o usar la clase AO3.Search
para hacerlo automáticamente por usted.
import AO3
search = AO3 . Search ( any_field = "Clarke Lexa" , word_count = AO3 . utils . Constraint ( 5000 , 15000 ))
search . update ()
print ( search . total_results )
for result in search . results :
print ( result )
3074
<Work [five times lexa falls for clarke]>
<Work [an incomplete list of reasons (why Clarke loves Lexa)]>
<Work [five times clarke and lexa aren’t sure if they're a couple or not]>
<Work [Chemistry]>
<Work [The New Commander (Lexa Joining Camp Jaha)]>
<Work [Ode to Clarke]>
<Work [it's always been (right in front of me)]>
<Work [The Girlfriend Tag]>
<Work [The After-Heda Chronicles]>
<Work [The Counter]>
<Work [May We Meet Again]>
<Work [No Filter]>
<Work [The Games We Play]>
<Work [A l'épreuve des balles]>
<Work [Celebration]>
<Work [Another level of fucked up]>
<Work [(Don't Ever Want to Tame) This Wild Heart]>
<Work [Self Control]>
<Work [Winter]>
<Work [My only wish]>
Luego puede usar el WorkId para cargar uno de los trabajos que buscó. Para obtener más de los primeros 20 trabajos, cambie el número de página usando
search . page = 2
Muchas acciones que puede tomar puede requerir una cuenta AO3. Si ya tiene uno, puede acceder a esas acciones usando un objeto AO3.Session. Comience iniciando sesión utilizando su nombre de usuario y contraseña, y luego puede usar ese objeto para acceder al contenido restringido.
import AO3
session = AO3 . Session ( "username" , "password" )
print ( f"Bookmarks: { session . bookmarks } " )
session . refresh_auth_token ()
print ( session . kudos ( AO3 . Work ( 18001499 , load = False ))
Bookmarks: 67
True
Dejamos con éxito los felicitaciones en un trabajo y revisamos nuestros marcadores. La session.refresh_auth_token()
es necesaria para algunas actividades, como dejar felicitaciones y comentarios. Si está caducado o se olvida de llamar a esta función, el error AO3.utils.AuthError: Invalid authentication token. Try calling session.refresh_auth_token()
se planteará.
También puede comentar / dejar kudos en un trabajo llamando Work.leave_kudos()
/ Work.comment()
y siempre que haya instanciado ese objeto con una sesión ya ( AO3.Work(xxxxxx, session=sess)
o usando Work.set_session()
). Esta es probablemente la mejor manera de hacerlo porque se encontrará con menos problemas de autenticación (como se utilizará el token de autenticidad del trabajo).
Si prefiere dejar un comentario o felicitaciones de forma anónima, puede usar un AO3.GuestSession
de la misma manera que usaría una sesión normal, excepto que no podrá consultar sus marcadores, suscripciones, etc. porque usted '' En realidad no inició sesión.
Para recuperar y procesar los hilos de comentarios, es posible que desee mirar el método Work.get_comments()
. Devuelve todos los comentarios en un capítulo específico y sus respectivos hilos. Luego puedes procesarlos como quieras. Echemos un vistazo:
from time import time
import AO3
work = AO3 . Work ( 24560008 )
work . load_chapters ()
start = time ()
comments = work . get_comments ( 5 )
print ( f"Loaded { len ( comments ) } comment threads in { round ( time () - start , 1 ) } seconds n " )
for comment in comments :
print ( f"Comment ID: { comment . id } n Replies: { len ( comment . get_thread ()) } " )
Loaded 5 comment threads in 1.8 seconds
Comment ID: 312237184
Replies: 1
Comment ID: 312245032
Replies: 1
Comment ID: 312257098
Replies: 1
Comment ID: 312257860
Replies: 1
Comment ID: 312285673
Replies: 2
Cargar comentarios lleva mucho tiempo, por lo que debe intentar usarlo lo menos posible. También hace que se envíen muchas solicitudes a los servidores AO3, lo que podría resultar en obtener el error utils.HTTPError: We are being rate-limited. Try again in a while or reduce the number of requests
. Si eso sucede, debe intentar espaciar sus solicitudes o reducir su número. También existe la opción de habilitar la limitación de la solicitud con AO3.utils.limit_requests()
, que lo hace para que no pueda hacer más de X solicitudes en una ventana de tiempo determinada. También puede responder a los comentarios usando la función Comment.reply()
o eliminar una (si es suya) usando Comment.delete()
.
AO3.Extra contiene el código para descargar algunos recursos adicionales que no son centrales para la funcionalidad de este paquete y no cambian muy a menudo. Un ejemplo sería la lista de fandoms reconocidos por AO3. Para descargar un recurso, simplemente use AO3.extra.download(resource_name)
. Para descargar cada recurso, puede usar AO3.extra.download_all()
. Para ver la lista de recursos disponibles, use AO3.extra.get_resources()
.
Para obtener información o informes de errores, comuníquese con [email protected].
MIT