pychan является клиентом Python для взаимодействия с 4chan. 4chan не имеет официального API, и попытки реализовать один за счет третьих лиц, как правило, томиться, поэтому вместо этого эта библиотека обеспечивает абстракции в связи с взаимодействием с (соскоба) 4chan напрямую. pychan ориентирован на объект, и его реализация ленива, если разумная (использование генераторов Python) для оптимизации производительности и минимизации лишних операций ввода-вывода блокировки.
Если у вас установлен Python> = 3.10 и <4.0, pychan может быть установлен из PYPI, используя что -то вроде
pip install pychan Все 4chan взаимодействия запускаются внутренне, спит выполняющую ветку. Если вы выполняете pychan многопоточным образом, вы не получите преимущества этого дросселирования. pychan не несет ответственности за последствия чрезмерных HTTP -запросов в таких случаях.
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 ) Остальные примеры в этом README предполагают, что вы уже создали экземпляр класса FourChan , как показано выше.
Эта функция динамически приносит доски из 4chan во время вызова.
Примечание. Доски, которые не совместимы с
pychanне возвращаются в этом списке.
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 )Примечание: некоторые доски не имеют архива (например
/b/). Такие платы либо вернет пустой список, либо поднимут исключение в зависимости от того, как вы настроили экземплярFourChan.
Поток, возвращаемые этой функцией, всегда будет иметь поле title , содержащее текст, показанный в интерфейсе 4chan под заголовком столбца «Выдержка». Этот текст может быть либо реальным названием потока, либо предварительным просмотром текста оригинального поста. Передача любого из потоков, возвращаемых этим методом, методу get_posts() автоматически исправляет поле title (при необходимости) на потоке, который прикрепляется к возвращенным сообщениям. Смотрите посты для конкретного потока для получения более подробной информации.
Технически,
pychanможет обратиться кtitleповедению, описанному выше, выпустив дополнительный HTTP -запрос для каждого потока, чтобы получить его реальное название, но в духе создания наименьшего количества HTTP -запросовpychanнапрямую использует выдержку вместо этого.
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 )Выполнение поиска против 4chan гораздо более громоздко, чем доступ к остальным данным 4chan. Это связано с тем, что 4chan имеет брандмауэр CloudFlare перед API REST, поэтому единственный способ вернуть данные из поиска-это предоставить информацию HTTP-запрос, необходимую для обойти анти-ботские проверки CloudFlare. В конечном счете, это означает передачу определенных заголовков наряду с HTTP -запросом, но задача возникает в результате приобретения таких заголовков.
В настоящее время это выходит за рамки pychan , чтобы генерировать эти заголовки для вас, поэтому, если вы хотите автоматизировать обход защиты CloudFlare, вы можете захотеть использовать проект, подобный следующему (этот список алфавит и не исчерпывающий):
Ручной способ приобрести эти значения - выполнить 4chan поиск с использованием веб -браузера и использовать инструменты разработчика браузера, чтобы отслеживать сетевые запросы, которые были сделаны во время поиска. Запрос, содержащий значения CloudFlare, будет сделан на https://find.4chan.org/api с некоторыми параметрами запроса. После того, как вы нашли этот запрос, скопируйте значения User-Agent и Cookie , которые были отправлены в вашем запросе, затем передайте их методу search() pychan . Имейте в виду, что в CloudFlare Cookie (ы) есть истечение срока действия, поэтому этот ручный обходной путь вернет только результаты, пока CloudFlare не лишает недействительного вашего cookie (ы). После этого вам нужно будет приобрести новые ценности.
ПРИМЕЧАНИЕ. Закрытые/липкие/архивные потоки никогда не возвращаются в результатах поиска.
# 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 )В следующих таблицах обобщены все виды данных, которые доступны на различных моделях, используемых этой библиотекой.
Также обратите внимание, что все классы моделей в pychan реализуют следующие методы:
__repr____str____hash____eq____iter__ - это реализовано так, чтобы модели могли быть переданы в функцию Python's tuple()__copy____deepcopy__ Таблица ниже соответствует классу pychan.models.Thread .
| Поле | Тип | Пример значения (ы) |
|---|---|---|
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" |
Таблица ниже соответствует классу pychan.models.Post .
| Поле | Тип | Пример значения (ы) |
|---|---|---|
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" |
Поле replies показанное выше, является исключительно удобной функцией pychan для доступа к всем сообщениям в потоке, в котором использовался оператор >> для «ответа» на текущий пост. Тем не менее, нет необходимости использовать поле replies для доступа ко всем доступным сообщениям в потоке; Когда вы позвоните в метод get_posts() , вы все равно будете получать все сообщения (в заказе, которые они были опубликованы) в виде единого, плоского списка.
Таблица ниже соответствует классу pychan.models.Poster .
| Поле | Тип | Пример значения (ы) |
|---|---|---|
poster.name | str | "Anonymous" |
poster.is_moderator | bool | True , False |
poster.id | Optional[str] | None "BYagKQXI" |
poster.flag | Optional[str] | None , "United States" , "Canada" |
Таблица ниже соответствует классу pychan.models.File .
| Поле | Тип | Пример значения (ы) |
|---|---|---|
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 |
См. Appling.md для информации, ориентированной на разработчика.