pychan est un client Python pour interagir avec 4chan. 4Chan n'a pas d'API officielle et les tentatives d'implémenter une par tiers ont eu tendance à languir, donc à la place, cette bibliothèque fournit des abstractions sur l'interaction avec (grattant) 4Chan directement. pychan est orienté objet et son implémentation est paresseuse lorsqu'il est raisonnable (en utilisant des générateurs Python) afin d'optimiser les performances et de minimiser les opérations d'E / S de blocage superflues.
Si vous avez installé Python> = 3.10 et <4.0, pychan peut être installé à partir de PYPI en utilisant quelque chose comme
pip install pychan Toutes les interactions 4Chan sont étranglées en interne en dormant le fil d'exécution. Si vous exécutez pychan de manière multithread, vous n'obtiendrez pas les avantages de cette étranglement. pychan ne prend pas la responsabilité des conséquences des demandes HTTP excessives dans de tels cas.
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 ) Le reste des exemples de cette README supposent que vous avez déjà créé une instance de la classe FourChan comme indiqué ci-dessus.
Cette fonction récupère dynamiquement les cartes de 4Chan au moment de l'appel.
Remarque: Les planches qui ne sont pas compatibles avec
pychanne sont pas renvoyées dans cette liste.
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 )Remarque: Certaines planches n'ont pas d'archive (par exemple
/b/). Ces cartes renverront une liste vide ou augmenteront une exception en fonction de la façon dont vous avez configuré votre instanceFourChan.
Les threads renvoyés par cette fonction auront toujours un champ title contenant le texte indiqué dans l'interface de 4Chan sous l'en-tête de colonne "Extratpt". Ce texte peut être soit le titre réel du fil, soit un aperçu du texte du post d'origine. Le passage de l'un des threads renvoyés par cette méthode à la méthode get_posts() corrigera automatiquement le champ title (si nécessaire) sur le thread qui est attaché aux messages retournés. Voir Fetch Posts pour un fil spécifique pour plus de détails.
Techniquement,
pychanpourrait aborder le comportementtitledécrit ci-dessus en émettant une demande HTTP supplémentaire pour chaque fil pour obtenir son titre réel, mais dans l'esprit de faire possible le plus petit nombre de demandes HTTP,pychanutilise directement l'extrait à la place.
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 )Effectuer des recherches contre 4chan est beaucoup plus lourd que l'accès au reste des données de 4chan. En effet, 4Chan a un pare-feu CloudFlare devant son API REST, donc la seule façon de récupérer les données des recherches est de fournir les informations de demande HTTP nécessaires pour contourner les contrôles anti-BOT de CloudFlare. En fin de compte, cela revient à passer certains en-têtes avec la demande HTTP, mais le défi vient de l'acquisition de ces en-têtes.
Il est actuellement au-delà de la portée de pychan de générer ces en-têtes pour vous, donc si vous souhaitez automatiser le contournement des protections de CloudFlare, vous voudrez peut-être chercher à utiliser un projet comme l'un des éléments suivants (cette liste est alphabétisée et non exhaustive)::
Une façon manuelle d'acquérir ces valeurs consiste à effectuer une recherche 4Chan à l'aide d'un navigateur Web et à tirer parti des outils de développeur du navigateur pour tracer les demandes de réseau qui ont été faites pendant la recherche. La demande qui contient les valeurs CloudFlare aura été faite à https://find.4chan.org/api avec certains paramètres de requête. Une fois que vous avez trouvé cette demande, copiez les valeurs User-Agent et Cookie qui ont été envoyées dans votre demande, puis passez-les à la méthode search() de pychan . Sachez que les cookies CloudFlare ont une expiration sur eux, donc cette solution de contournement manuelle ne renverra les résultats que jusqu'à ce que CloudFlare invalide vos cookies. Après cela, vous devrez acquérir de nouvelles valeurs.
Remarque: les fils fermés / collés / archivés ne sont jamais renvoyés dans les résultats de la recherche.
# 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 )Les tableaux suivants résument tous les types de données disponibles sur les différents modèles utilisés par cette bibliothèque.
Notez également que toutes les classes de modèles de pychan mettent en œuvre les méthodes suivantes:
__repr____str____hash____eq____iter__ - Ceci est mis en œuvre afin que les modèles puissent être transmis à la fonction tuple() de Python__copy____deepcopy__ Le tableau ci-dessous correspond à la classe pychan.models.Thread .
| Champ | Taper | Exemple de valeur (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" |
Le tableau ci-dessous correspond à la classe pychan.models.Post .
| Champ | Taper | Exemple de valeur (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" |
Le champ replies indiqué ci-dessus est purement une fonctionnalité de commodité que pychan fournit pour accéder à tous les messages dans un thread qui a utilisé l'opérateur >> pour "répondre" à la publication actuelle. Cependant, il n'est pas nécessaire d'utiliser le champ replies pour accéder à tous les messages disponibles dans un fil; Lorsque vous appelez la méthode get_posts() , vous recevrez toujours tous les messages (dans l'ordre où ils ont été publiés) comme une seule liste plate.
Le tableau ci-dessous correspond à la classe pychan.models.Poster .
| Champ | Taper | Exemple de valeur (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" |
Le tableau ci-dessous correspond à la classe pychan.models.File .
| Champ | Taper | Exemple de valeur (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 |
Voir contribution.md pour les informations axées sur les développeurs.