pychan é um cliente Python para interagir com o 4chan. O 4Chan não possui uma API oficial e as tentativas de implementar uma por terceiros tendem a definhar; portanto, essa biblioteca fornece abstrações sobre a interação com (raspando) o 4chan diretamente. pychan é orientada a objetos e sua implementação é preguiçosa quando razoável (usando geradores de Python), a fim de otimizar o desempenho e minimizar as operações de E/S de bloqueio supérfluas.
Se você possui python> = 3.10 e <4,0 instalado, pychan pode ser instalado a partir de Pypi usando algo como
pip install pychan Todas as interações 4chan são reduzidas internamente, dormindo o tópico de execução. Se você executar pychan de uma maneira multithread, não obterá os benefícios dessa limitação. pychan não se responsabiliza pelas conseqüências de solicitações HTTP excessivas nesses 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 ) O restante dos exemplos neste README assume que você já criou uma instância da classe FourChan , como mostrado acima.
Esta função busca dinamicamente as placas de 4chan no horário da chamada.
Nota: as placas que não são compatíveis com
pychannão são devolvidas nesta 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: Algumas placas não têm um arquivo (por exemplo
/b/). Essas placas retornarão uma lista vazia ou aumentarão uma exceção, dependendo de como você configurou sua instânciaFourChan.
Os threads retornados por esta função sempre terão um campo title que contém o texto mostrado na interface do 4chan no cabeçalho da coluna "trecho". Este texto pode ser o título real do thread ou uma prévia do texto da postagem original. A passagem de qualquer um dos threads retornados por este método para o método get_posts() corrigirá automaticamente o campo title (se necessário) no thread que é conectado às postagens retornadas. Consulte Postagens buscam um tópico específico para obter mais detalhes.
Tecnicamente,
pychanpoderia abordar o comportamentotitledescrito acima, emitindo uma solicitação HTTP adicional para cada thread para obter seu título real, mas no espírito de tornar possível o menor número de solicitações HTTP,pychanusa diretamente o trecho.
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 )A execução de pesquisas contra o 4Chan é muito mais pesada do que acessar o restante dos dados do 4chan. Isso ocorre porque o 4chan possui um firewall do Cloudflare na frente de sua API de REST; portanto, a única maneira de obter os dados de volta das pesquisas é fornecer as informações de solicitação HTTP necessárias para ignorar as verificações anti-BOT da CloudFlare. Por fim, isso equivale a passar certos cabeçalhos junto com a solicitação HTTP, mas o desafio vem da aquisição desses cabeçalhos.
Atualmente, está além do escopo de pychan gerar esses cabeçalhos para você; portanto, se você deseja automatizar a contornar as proteções do Cloudflare, convém querer usar um projeto como um dos seguintes (esta lista é alfabetizada e não exaustiva):
Uma maneira manual de adquirir esses valores é executar uma pesquisa 4chan usando um navegador da web e aproveitar as ferramentas de desenvolvedor do navegador para rastrear as solicitações de rede que foram feitas durante a pesquisa. A solicitação que contém os valores do CloudFlare será feita para https://find.4chan.org/api com alguns parâmetros de consulta. Depois de encontrar essa solicitação, copie os valores User-Agent e Cookie que foram enviados em sua solicitação e depois passe-os para o método search() de pychan . Esteja ciente de que os cookies do CloudFlare têm uma expiração sobre eles; portanto, essa solução alternativa manual retornará apenas os resultados até que o CloudFlare invalide seus cookies. Depois disso, você precisará adquirir novos valores.
NOTA: Os threads fechados/grudados/arquivados nunca são retornados nos resultados da pesquisa.
# 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 )As tabelas a seguir resumem todos os tipos de dados disponíveis nos vários modelos usados por esta biblioteca.
Observe também que todas as classes de modelo em pychan implementam os seguintes métodos:
__repr____str____hash____eq____iter__ - Isso é implementado para que os modelos possam ser passados para a função tuple() de Python__copy____deepcopy__ A tabela abaixo corresponde à classe pychan.models.Thread .
| Campo | Tipo | Exemplo de valor (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" |
A tabela abaixo corresponde à classe pychan.models.Post .
| Campo | Tipo | Exemplo de valor (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" |
O campo replies mostrado acima é puramente um recurso de conveniência que pychan fornece para acessar todas as postagens em um thread que usou o operador >> para "responder" à postagem atual. No entanto, não é necessário usar o campo replies para acessar todas as postagens disponíveis em um thread; Quando você chama o método get_posts() , você ainda receberá todas as postagens (na ordem em que foram publicadas) como uma única lista plana.
A tabela abaixo corresponde à classe pychan.models.Poster .
| Campo | Tipo | Exemplo de valor (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" |
A tabela abaixo corresponde à classe pychan.models.File .
| Campo | Tipo | Exemplo de valor (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 Contribuindo.md para obter informações orientadas para o desenvolvedor.