pychan es un cliente de Python para interactuar con 4chan. 4Chan no tiene una API oficial, y los intentos de implementar uno por terceros han tendido a languidecer, por lo que, en cambio, esta biblioteca proporciona abstracciones sobre interactuar con (raspado) 4chan directamente. pychan está orientado a objetos y su implementación es perezosa cuando sea razonable (usando generadores de Python) para optimizar el rendimiento y minimizar las operaciones de E/S de bloqueo superfluo.
Si tiene Python> = 3.10 y <4.0 instalado, pychan se puede instalar desde Pypi usando algo como
pip install pychan Todas las interacciones 4chan se estremecen internamente al dormir el hilo ejecutivo. Si ejecuta pychan de manera multiproceso, no obtendrá los beneficios de este estrangulamiento. pychan no se hace responsable de las consecuencias de las solicitudes HTTP excesivas en tales casos.
from pychan import FourChan , LogLevel , PychanLogger
# With all defaults (logging disabled, all exceptions raised)
fourchan = FourChan ()
# Tell pychan to gracefully ignore HTTP exceptions, if any, within its internal logic
fourchan = FourChan ( raise_http_exceptions = False )
# Tell pychan to gracefully ignore parsing exceptions, if any, within its internal logic
fourchan = FourChan ( raise_parsing_exceptions = False )
# Configure logging explicitly
logger = PychanLogger ( LogLevel . INFO )
fourchan = FourChan ( logger = logger )
# Use all of the above settings at once
logger = PychanLogger ( LogLevel . INFO )
fourchan = FourChan ( logger = logger , raise_http_exceptions = True , raise_parsing_exceptions = True ) El resto de los ejemplos en este README suponen que ya ha creado una instancia de la clase FourChan como se muestra arriba.
Esta función obtiene dinámicamente tablas de 4chan en el momento de la llamada.
Nota: Los tableros que no son compatibles con
pychanno se devuelven en esta lista.
boards = fourchan . get_boards ()
# Sample return value:
# ['a', 'b', 'c', 'd', 'e', 'g', 'gif', 'h', 'hr', 'k', 'm', 'o', 'p', 'r', 's', 't', 'u', 'v', 'vg', 'vm', 'vmg', 'vr', 'vrpg', 'vst', 'w', 'wg', 'i', 'ic', 'r9k', 's4s', 'vip', 'qa', 'cm', 'hm', 'lgbt', 'y', '3', 'aco', 'adv', 'an', 'bant', 'biz', 'cgl', 'ck', 'co', 'diy', 'fa', 'fit', 'gd', 'hc', 'his', 'int', 'jp', 'lit', 'mlp', 'mu', 'n', 'news', 'out', 'po', 'pol', 'pw', 'qst', 'sci', 'soc', 'sp', 'tg', 'toy', 'trv', 'tv', 'vp', 'vt', 'wsg', 'wsr', 'x', 'xs'] # Iterate over all threads in /b/
for thread in fourchan . get_threads ( "b" ):
# Do stuff with the thread
print ( thread . title )
# You can also iterate over all the posts in the thread
for post in fourchan . get_posts ( thread ):
# Do stuff with the post - refer to the model documentation in pychan's README for details
print ( post . text )NOTA: Algunas tablas no tienen un archivo (por ejemplo, p
/b/). Dichos tableros devolverán una lista vacía o aumentarán una excepción dependiendo de cómo haya configurado su instanciaFourChan.
Los hilos devueltos por esta función siempre tendrán un campo title que contiene el texto que se muestra en la interfaz de 4Chan bajo el encabezado de la columna "Extract". Este texto puede ser el título real del hilo o una vista previa del texto de la publicación original. Pasar cualquiera de los subprocesos devueltos por este método al método get_posts() corregirá automáticamente el campo title (si es necesario) en el hilo que se adjunta a las publicaciones devueltas. Vea las publicaciones de Fetch para un hilo específico para más detalles.
Técnicamente,
pychanpodría abordar el comportamientotitledescrito anteriormente emitiendo una solicitud HTTP adicional para que cada hilo obtenga su título real, pero en el espíritu de hacer que el menor número de solicitudes HTTP sea posible,pychanusa directamente el extracto.
for thread in fourchan . get_archived_threads ( "pol" ):
# Do stuff with the thread
print ( thread . title )
# You can also iterate over all the posts in the thread
for post in fourchan . get_posts ( thread ):
# Do stuff with the post - refer to the model documentation in pychan's README for details
print ( post . text )Realizar búsquedas contra 4chan es mucho más engorroso que acceder al resto de los datos de 4chan. Esto se debe a que 4Chan tiene un firewall de Cloudflare frente a su API REST, por lo que la única forma de recuperar los datos de las búsquedas es proporcionar la información de solicitud HTTP necesaria para evitar las verificaciones anti-bots de Cloudflare. En última instancia, esto equivale a pasar ciertos encabezados junto con la solicitud HTTP, pero el desafío proviene de adquirir tales encabezados.
Actualmente está más allá del alcance de pychan generar estos encabezados para usted, por lo que si desea automatizar la elección de las protecciones de Cloudflare, es posible que desee buscar un proyecto como uno de los siguientes (esta lista está alfabizada y no exhaustiva):
Una forma manual de adquirir estos valores es realizar una búsqueda de 4chan utilizando un navegador web y aprovechar las herramientas de desarrollador del navegador para rastrear las solicitudes de red que se realizaron durante la búsqueda. La solicitud que contenga los valores de CloudFlare se habrá realizado a https://find.4chan.org/api con algunos parámetros de consulta. Una vez que haya encontrado esta solicitud, copie los valores User-Agent y Cookie que se enviaron a su solicitud, luego paselos al método search() de pychan . Tenga en cuenta que las cookies (s) de Cloudflare tienen un vencimiento en ellas, por lo que esta solución manual solo devolverá los resultados hasta que Cloudflare invalida sus cookies. Después de eso, deberá adquirir nuevos valores.
Nota: Los hilos cerrados/pegajosos/archivados nunca se devuelven en los resultados de búsqueda.
# This "threads" variable will contain a Python Generator (not a list) in order to facilitate laziness
threads = fourchan . search (
board = "b" ,
text = "ylyl" ,
user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36" ,
cloudflare_cookies = {
"cf_clearance" : "bm2RICpcDeR4cXoC2nfI_cnZcbAkN4UYpN6c1zzeb8g-1440859602-0-160"
}
)
for thread in threads :
# The thread object is the same class as the one returned by get_threads()
for post in fourchan . get_posts ( thread ):
# Do stuff with the post - refer to the model documentation in pychan's README for details
print ( post . text ) from pychan . models import Thread
# Instantiate a Thread instance with which to query for posts
thread = Thread ( "int" , 168484869 )
# Note: the thread contained within the returned posts will have all applicable metadata (such as
# title and sticky status), regardless of whether you provided such data above - pychan will
# "auto-discover" all metadata and include it in the post models' copy of the thread
posts = fourchan . get_posts ( thread )Las siguientes tablas resumen todos los tipos de datos disponibles en los diversos modelos utilizados por esta biblioteca.
También tenga en cuenta que todas las clases de modelos en pychan implementan los siguientes métodos:
__repr____str____hash____eq____iter__ : esto se implementa para que los modelos se pasen a la función tuple() de Python ()__copy____deepcopy__ La tabla a continuación corresponde a la clase pychan.models.Thread .
| Campo | Tipo | Valor (s) de ejemplo (s) |
|---|---|---|
thread.board | str | "b" , "int" |
thread.number | int | 882774935 , 168484869 |
thread.title | Optional[str] | None , "YLYL thread" |
thread.is_stickied | bool | True , False |
thread.is_closed | bool | True , False |
thread.is_archived | bool | True , False |
thread.url | str | "https://boards.4chan.org/a/thread/251097344" |
La tabla a continuación corresponde a la clase pychan.models.Post .
| Campo | Tipo | Valor (s) de ejemplo (s) |
|---|---|---|
post.thread | Thread | pychan.models.Thread |
post.number | int | 882774935 , 882774974 |
post.timestamp | DateTime.datetime | DateTime.datetime |
post.poster | Poster | pychan.models.Poster |
post.text | str | ">be men>be boredn>write pychann>somehow it works" |
post.is_original_post | bool | True , False |
post.file | Optional[File] | None , pychan.models.File |
post.replies | list[Post] | [] , [pychan.models.Post, pychan.models.Post] |
post.url | str | "https://boards.4chan.org/a/thread/251097344#p251097419" |
El campo replies que se muestra arriba es puramente una función de conveniencia que pychan proporciona para acceder a todas las publicaciones dentro de un hilo que usó el operador >> para "responder" a la publicación actual. Sin embargo, no es necesario usar el campo replies para acceder a todas las publicaciones disponibles en un hilo; Cuando llame al método get_posts() , aún recibirá todas las publicaciones (en el orden en que fueron publicadas) como una lista única y plana.
La siguiente tabla corresponde a la clase pychan.models.Poster .
| Campo | Tipo | Valor (s) de ejemplo (s) |
|---|---|---|
poster.name | str | "Anonymous" |
poster.is_moderator | bool | True , False |
poster.id | Optional[str] | None , "BYagKQXI" |
poster.flag | Optional[str] | None , "United States" , "Canada" |
La siguiente tabla corresponde a la clase pychan.models.File .
| Campo | Tipo | Valor (s) de ejemplo (s) |
|---|---|---|
file.url | str | "https://i.4cdn.org/pol/1658892700380132.jpg" |
file.name | str | "wojak.jpg" , "i feel alone.jpg" |
file.size | str | "601 KB" |
file.dimensions | tuple[int, int] | (1920, 1080) , (800, 600) |
file.is_spoiler | bool | True , False |
Consulte Contriping.MD para información orientada al desarrollador.