【问题标题】:multiple thread website crawling using python使用python进行多线程网站爬取
【发布时间】:2013-06-12 05:30:40
【问题描述】:

这是我的代码 (link):

import urllib, urllib2, re
import threading, Queue

somewebsite = 'xxx' 

urls5 = []
for i in range(50001, 60000):
    url = somewebsite + str(i)
    urls5.append(url)

class MultiUrl(threading.Thread):  
    def __init__(self, queue):  
        threading.Thread.__init__(self)  
        self.queue = queue
    def run(self):  
        while True:  
            url = self.queue.get()
            try:  
                Go(url)
            except:  
                continue  
            self.queue.task_done()


def main():
    queue = Queue.Queue()
    for i in range(16):  
        t = MultiUrl(queue)  
        t.setDaemon(True)   
        t.start() 

    for url in urls5:
        queue.put(url) 
    queue.join()

def Go(url):
    try:
        print "Now grabbing...", url
        getArticle(url)
        if (OriginalContentList != []):
            writeContent()
    except:
        pass

def getArticle(url):
    global content, Content
    i = re.findall('\d+', url)[0]
    ArticleID = str(i)
    try:
        content = urllib2.urlopen(url).read()
        Content = urllib.unquote(content)
    except:
        OriginalContentList = []
        pass

def writeContent():
    # Origin Content
    try:
        filename = ArticleID + '.txt'
        file_out = open(filename, 'w')
        file_out.write(Content)
        file_out.write('\n')
        file_out.close()
    except:
        pass

if __name__ == '__main__':
    main()

单线程抓取不能处理那么多文章(>=200000),所以我谷歌(d)并选择了线程和队列。

问题是:程序无法将内容写入对应的文件。例如,它可以将 No.55555 的内容写入 55666.txt 。

如果我的描述不准确,请发表评论。

【问题讨论】:

    标签: python python-2.7 queue web-crawler


    【解决方案1】:

    全局变量由多个线程共享。 一个线程可以覆盖一个变量,而另一个线程正在读取它。

    尽可能避免使用全局变量。

    【讨论】:

    • 好吧好吧..我将我的功能组合在一起并添加了一些“try”和“except”然后程序运行正常..谢谢!
    【解决方案2】:

    有一个简单的方法可以实现多线程,但是我忘了它是从哪里来的..

    from multiprocessing.dummy import Pool as ThreadPool
    pool = ThreadPool(5)
    results = pool.map(function_name, url_list)
    pool.close()
    pool.join()
    

    不足之处在于,它不能处理错误,所以你应该考虑如何正确编写该函数。 ipdb 是一个很棒的工具。

    还有更方便的访问网页内容的库:requests

    和内容存储:PyMongo

    【讨论】:

    • 如果你不使用results,你最好使用以下:for _ in pool.imap_unordered(function_name, url_list): pass
    • @falsetru,谢谢。请您解释一下您的建议好吗? :)
    • map 在所有任务完成之前不会返回。并且列表项的顺序应该是有序的。如果不需要,您可以改用imap_unordered;立即返回;迭代将以任何顺序产生任何已完成任务的返回值。
    • @falsetru 我尝试使用 print(taskurl),有时它会打印一个 url 两次.....
    • 您是否检查过原始列表 contians 重复项? len(url_list) == len(set(url_list))
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-12
    • 1970-01-01
    • 2011-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-04
    相关资源
    最近更新 更多