在推文中阅读缩短网址(https://t.co)的最快方式(数百)

时间:2017-08-22 11:41:54

标签: python-2.7 http tornado python-multiprocessing python-multithreading

我正在阅读数百条推文并检查这些推文中缩短的网址。

只是一个简单的代码流程:

主题:

def worker(tweets):
   for tweet in tweets:
         find shortened urls in tweet
         result= process these urls (read the response body)

主要流程:

Block till all threads are done
Collect these results

目前,我正在使用多线程,这在一定程度上缩短了时间。例如,对于包含缩短URL的100条推文,处理它们需要大约320秒。但是,如果我使用多线程,我可以用50个线程将这个时间带到24秒左右。在那之后,即使我转到我能理解的100个线程,速度也没有增加。

我的代码主要耗时的部分是读取缩短的URL,将其解析为实际的URL,然后使用Goose读取它们。

实际代码:

def worker(result_queue, input_tweet_queue):

queue_full = True
while queue_full:
    try:
        item = input_tweet_queue.get(False)
        urls = re.findall('http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+',
                          item['text'])
        for url in urls:
            try:
                res = urllib2.urlopen(url)
                actual_url = res.geturl()
                if 'twitter.com' not in actual_url:
                    g = Goose() # Its defined somewhere else in real
                    content_of_url = g.extract(actual_url)
                    result = process(content_of_url) 
                    result_queue.put(result)
            except:
                invalid_url = True
    except Queue.Empty:
        queue_full = False

主要流程:

result_queue = Queue.Queue()
input_tweet_queue = Queue.Queue()

# Place all tweets in a queue
for item in tweets:
    tweet_queue.put(item)

# Create threads and start them
thread_count = 50
for i in range(thread_count):
    t = threading.Thread(target=worker, args=(result_queue, input_tweet_queue))
    t.daemon = True
    t.start()

# Collect the results
final_result = []
index = 0
for tweet in tweets:
    result[index] = q.get()
    index = index + 1

当前表现:

Tweets  Threads Execution-Time(Seconds)
100       1      340
100       5      66
100      10      44
100      50      24
100      100     23

时间消耗的主要原因是解决这些缩短的网址并阅读它们。

有没有更好的方法来完成这项任务?我可以以某种方式嵌入任何非阻塞IO吗?或者我可以使用non-blocking IO方法而不是多线程吗?

1 个答案:

答案 0 :(得分:-1)

我会尝试grequests模块:https://github.com/kennethreitz/grequests

非常愉快地记录并且易于使用。