Скрипт Python для веб-скрепинга замедляется с несколькими потоками, в то время как он работает быстро на многопроцессорной или однопоточной - PullRequest
0 голосов
/ 17 мая 2019

Я пытаюсь создать скрипт для мониторинга твитов с помощью API внешнего интерфейса Twitter.Я в основном использую библиотеку Twitter Scraper, которую я слегка модифицировал, чтобы отфильтровать ретвиты.

У меня есть файл json, где я храню твиттер-идентификаторы и их последние твиты.Каждый раз, когда публикуется новый твит, скрипт печатает содержание нового твита.Вот как выглядит файл json:

{
   "facebook": {
        "lastTweet": "1144174307321311987"
    },
    "youtube": {
        "lastTweet": "1121174307114311682"
    }
}

Теперь перейдем к моей проблеме.Если я запускаю скрипт с 1 профилем, загруженным в файл json, я могу ловить твиты в режиме реального времени, так как скрипт выполняется без каких-либо задержек.Если я начну запускать больше профилей (например, 10 или 15), все потоки замедляются, а твиты задерживаются на 5 - 10 секунд позже.Использование многопроцессорной обработки исправляет это, но использование процессора сумасшедшее по сравнению с многопоточностью.Вот мой код:

from libs import get_tweets
import requests
import threading
import json
import time
import threading

def update_database():

    global database

    with open("database.json", "w") as f:
        json.dump(database, f, indent=4)
        f.close()

def load_database():

    f = open("database.json","r")
    return json.loads(f.read())

def monitor(username):


    global database

    while True:
        #time.sleep(0.1)
        try:
            for tweet in get_tweets(username, pages = 1):


                last_tweet = tweet
                break

            if last_tweet["tweetId"] != database[username]["lastTweet"]:
                database[username]["lastTweet"] = last_tweet["tweetId"]
                print("NEW TWEET")
                update_database()
                print(last_tweet["text"])
            else:
                print(username,"did not change!")

        except Exception as e:
            if "last_tweet" in str(e):
                print("retweets only for", username)
            else:
                print(e)

if __name__ == "__main__":

    database = load_database()

    for profile in database.keys():
        print("Starting monitor for",profile)
        t = threading.Thread(target = monitor, args = (profile,))
        t.start()
...