⚠️ Автонаповнюваний блог із майже нескінченним контентом на коментарях з Reddit (Мануал)

Мої 14-річні фантазії про автоблог почали матеріалізовуватися лише нещодавно, але це може стати вашою реальністю вже сьогодні! Ні, вам не потрібно “знати” python, щоб запустити цей скрипт. Усе, що вам потрібно, це IDE на вашій локальній машині, зрозуміти, як встановити кілька бібліотек, і скрипт готовий до запуску.

Цей скрипт можна масштабувати до багатопотокового монстра, який може обробляти 100 паралельно і робити 10 000 000 постів із коментарями щодня, тому я б рекомендував встановити локальний сервер на virutalbox і експортувати базу даних пізніше.

Що робить скрипт:

Витягує найкращі пости з reddit разом із 75-125 коментарями верхнього рівня кожного поста і постить їх у wordpress, пости і коментарі – від оригінальних імен авторів з оригінальною часовою міткою. Функція багатопоточності з поточними налаштуваннями може зробити 200 постів із середньою кількістю 75 коментарів на пост приблизно за 16 секунд.

Обмеження:

  • 1. тільки 100 запитів на секунду на акаунт, але я рекомендую використовувати кількість запитів не більше ніж у 2 рази більшу, ніж кількість ядер у вас є. Скрипт засинає після кожних 100 запитів на 61 секунду.
  • Якщо ви розміщуєте свій wordpress локально або на vps чи виділеному сервері, то все гаразд, але якщо ви на віртуальному хостингу, то у вашого хостера можуть бути проблеми з численними запитами. Можливо, вам доведеться налаштувати ssh-тунель, або створити сайт локально, заповнити базу даних і перенести її на сервер, або знайти спосіб синхронізувати її в реальному часі.
  • Якщо ви запустите скрипт і відійдете від нього, і якщо відбудеться втрата зв’язку через одне з цих обмежень, скрипт перестане працювати.
  • Вам знадобиться обліковий запис адміністратора.
  • У скрипт не включений рерайтер, тому контент не є унікальним.

Порядок роботи:

  1. Якщо у вас немає середовища python або IDE, встановіть їх.
  2. Скопіюйте код і збережіть його у файл із розширенням .py
  3. Введіть ім’я користувача reddit, пароль, client-id і client-secret. Дізнайтеся, як їх зробити тут geeksforgeeks.org/how-to-get-client_id-and-client_secret-for-python-reddit-api-registration.
  4. Введіть ваше ім’я користувача wordpress і пароль додатка. Звичайний пароль не спрацює. Керівництво з цього питання знаходиться тут paidmembershipspro.com/create-application-password-wordpress.
  5. Якщо вам потрібна багатопотоковість, встановіть прапорець у True, але спочатку я б рекомендував залишити його в False.
  6. Ви можете вводити по одному сабреддіту за раз або скласти їхній список по одному рядку у файлі sr.txt у тій самій папці, що й файл коду.
  7. Запустіть скрипт.

Ось сам код:

тиць
import praw, os, requests, time, random, base64, json, secrets, string
from concurrent.futures import ProcessPoolExecutor
from datetime import datetime
redditUsername = “”
redditPassword = “”
redditClientId = “”
redditClientSecret = “”
redditPullLimit = 200
redditUserAgent= “postConsolidator_1.0″
wpDomain = ” ##DO NOT INCLUDE HTTPS OR WWW OR ANY TRAILING SLASHES. ONLY ENTER domainname.tld unless wordpress is located in a subfolder, in which case do not use a trailing slash
wpUsername = ‘admin’
wpApplicationPassword = ”
wpHasHTTPS = True
wpPostStatus = ‘publish’
wpCommentStatus = ‘approve’
multiProcessFlag = False
multiProcessMaxWorkers = 16
reddit = praw.Reddit(username=redditUsername,
password=redditPassword,
client_id=redditClientId,
client_secret=redditClientSecret,
user_agent=redditUserAgent
)
wpCredentials = f'{wpUsername}:{wpApplicationPassword}’
wpCredentialsToken = base64.b64encode(wpCredentials.encode())
wpHeader = {‘Authorization’: ‘Basic ‘ + wpCredentialsToken.decode(‘utf-8′)}
if wpHasHTTPS:
wpPostAPIURL = f’https://{wpDomain}/wp-json/wp/v2/posts/’
wpCommentsAPIURL = f’https://{wpDomain}/wp-json/wp/v2/comments/’
wpUsersAPIURL = f’https://{wpDomain}/wp-json/wp/v2/users/’
else:
wpPostAPIURL = f’http://{wpDomain}/wp-json/wp/v2/posts/’
wpCommentsAPIURL = f’http://{wpDomain}/wp-json/wp/v2/comments/’
wpUsersAPIURL = f’http://{wpDomain}/wp-json/wp/v2/users/’
main_menu = ”’
Howdy!
Hit
1: Input name of Subreddit manually
2: Import from a list of subreddits
3. Exit
Wachawannado? : ”’
def post2wp(submission, i):
if str(submission.selftext) == ”:
print(‘nothing to post’)
return
wpUserDate = {
‘username’:str(submission.author).lower().replace(‘_’,””).replace(‘-‘,”),
’email’:str(submission.author).lower().replace(‘_’,””).replace(‘-‘,”) + ‘@’ + wpDomain,
‘password’:”.join(secrets.choice(string.ascii_letters + string.digits + ‘!@#$%^&*()_+=-`~;:”|?><,./’) for i in range(16)), ‘roles’:[‘subscriber’], } wpUserResponse = requests.post(url=wpUsersAPIURL, headers=wpHeader, json=wpUserDate) try: wpPostAuthorID = int(json.loads(wpUserResponse.text)[‘id’]) except KeyError: print(f'{submission.author}, not created’) print(wpUserResponse.text) wpPostAuthorID = 2 print(‘Author ID’, wpPostAuthorID) wpPostData = { ‘title’ : submission.title, ‘status’: wpPostStatus, ‘content’: submission.selftext, ‘date_gmt’:datetime.utcfromtimestamp(submission.created).strftime(‘%Y-%m-%dT%H:%M:%S’), ‘author’:wpPostAuthorID, } wpPostResponse = requests.post(url=wpPostAPIURL, headers=wpHeader, json=wpPostData) print(‘wppostresponse’, wpPostResponse) try: wpPostID = json.loads(wpPostResponse.text)[‘id’] except KeyError: j=0 print(‘Bad Response, skipping post’) return submission.comments.replace_more(limit=None) for j, topLevelComment in enumerate(submission.comments): if topLevelComment is not None: wpCommentData = { ‘post’: wpPostID, ‘author_name’: topLevelComment.author, ‘author_email’: str(topLevelComment.author) + ‘@’ + wpDomain, ‘content’: topLevelComment.body, ‘status’:wpCommentStatus, ‘author_ip’:str(random.randint(0,255))+’.’+str(random.randint(0,255))+’.’+str(random.randint(0,255))+’.’+str(random.randint(0,255)), ‘date_gmt’:datetime.utcfromtimestamp(topLevelComment.created).strftime(‘%Y-%m-%dT%H:%M:%S’), } wp_comment_response = requests.post(url=wpCommentsAPIURL, headers=wpHeader, data=wpCommentData) print(i+1, j+1, wp_comment_response) if j > random.randint(75,125):
break
print(f’Item no. {i + 1} posted, with {j+1} comments and title{submission.title} and post content \n\n {submission.selftext} \n\n {wpPostResponse}’)
if __name__ == ‘__main__’:
startTime = time.perf_counter()
try:
wachawannado = int(input(main_menu))
except ValueError:
print(‘\nPlease enter a number’)
if wachawannado == 1:
subreddit = reddit.subreddit(input(“Ok, lets crawl reddit.\nWhats the name of the subreddit? : “))
with ProcessPoolExecutor(max_workers=multiProcessMaxWorkers) as executor:
for i, submission in enumerate(subreddit.top(limit=redditPullLimit)):
if multiProcessFlag:
executor.submit(post2wp, submission=submission, i=i)
else:
post2wp(submission=submission, i=i)
elif wachawannado == 2:
if os.path.exists(‘sr.txt’):
if not os.stat(“sr.txt”).st_size == 0:
with open(‘sr.txt’,’r’) as sr:
with ProcessPoolExecutor(max_workers=multiProcessMaxWorkers) as executor:
for i, line in enumerate(sr):
subreddit = reddit.subreddit(line)
for j, submission in enumerate(subreddit.top(limit=redditPullLimit)):
if multiProcessFlag:
executor.submit(post2wp, submission=submission, i=j)
if j % 99 == 0:
print(‘yawn’)
time.sleep(61)
print(‘Sorry, dozed off’)
else:
post2wp(submission=submission, i=j)
print(f'{i}:{line} done, pulled {j} submissions from {line}’)
else:
print(‘sr.txt is empty’)
else:
print(‘Cant find sr.txt with the list of SubReddits’)
elif wachawannado == 3:
print(‘Bye!’)
else:
print(‘\nHit a valid number\n’)
print(‘Total time for this loop is ‘, time.perf_counter()-startTime)
Додати коментар