zoukankan      html  css  js  c++  java
  • python实现并行爬虫

    问题背景:指定爬虫depth、线程数, python实现并行爬虫
       思路:    单线程 实现爬虫类Fetcher
                     多线程 threading.Thread去调Fetcher
      
    方法:Fetcher 中,用urllib.urlopen打开指定url,读取信息:

    response = urllib.urlopen(self.url)
    content = response.read()

    但是这样有问题, 比如对于www.sina.com来说,读出来的content是乱码的:

    [cpp] view plain copy
     
    1. >>> content[0:100]  
    2. 'x1fx8bx08x00x00x00x00x00x00x03xecxbdkx93x1cxd7u xf8x99x8cxd0x7fHx14Wxe8*t=2xebxd5xd5]H`x014@4x88x97x00xf0%x10xeaxc8xaaxcaxeeNxa0xbaxb2Xx99x85x06Xxa8x1fCjx1cxb6ly-x92x06xf5 %xca"Exf1!Rx94xa8x87C3x9exf1xd8#x87xbd;x8exd8x99x8dxb1x1dxf2'  



    于是用了python第三方工具chardet,通过

    chardet.detect(content)

    进行content中字符集的检测:

    [html] view plain copy
     
    1. >>> chardet.detect(content)  
    2. {'confidence': 0.99, 'encoding': 'GB2312'}  


    好,问题解决了:

    [html] view plain copy
     
    1. >>> import urllib  
    2. >>url = 'http://www.sina.com'  
    3. >>response = urllib.urlopen(url)  
    4. >>content = response.read()  
    5. >>> chardet.detect(content)  
    6. {'confidence': 0.99, 'encoding': 'GB2312'}  



    但是我们想高效爬虫的时候需要设置urlopen的timeout时间,这在urllib中没有实现,而在urllib2中有实现:

    response = urllib2.urlopen(self.url, timeout = self.timeout)

    但是这时候再用chardet出现的字符集结果与上次不同:

    [html] view plain copy
     
    1. >>> import urllib  
    2. >>url = 'http://www.sina.com'  
    3. >>response = urllib2.urlopen(url, timeout=1)  
    4. >>content = response.read()  
    5. >>> chardet.detect(content)  
    6. {'confidence': 0.0, 'encoding': None}  

    这是怎么回事? 原来是这个页面的编码问题, 该页面返回的是gzip编码,参考<python urllib2 returns garbage - Stack Overflow>

    实际上每次应该判断页面信息的'Content-Encoding'是否为'gzip'。 

    urllib支持gzip页面自动解压而urllib2不支持。 所以对于这种页面, 先解压再read:

    try:
        response = urllib2.urlopen(self.url, timeout = self.timeout)
        if response.info().get('Content-Encoding', "") == 'gzip':  #e.g www.sina.com.cn
            buf = StringIO.StringIO(response.read())
            f = gzip.GzipFile(fileobj=buf)
            content = f.read()
        else:
            content = response.read()
        content = self.enc_dec(content)
        return content
    except socket.timeout:
        log.warn("Timeout in fetching %s" % self.url)

    到这里,大家是不是都以为我只是个标题党。。。?

    *******************************************************************************

    那么,就把调通的整个spider文件share一下吧,

    程序支持多线程爬虫,主文件为spider.py, testSpider.py为单测(不保证覆盖率)。

    程序地址:http://download.csdn.net/detail/abcjennifer/9086751

    from: http://blog.csdn.net/abcjennifer/article/details/48270479

  • 相关阅读:
    Python之字典
    Python之模块
    Python之字符串格式化
    结束循环
    循环
    C语言static和局部变量
    C static extern和全局变量
    extern static和函数
    C语言typedef
    C语言之文件包含
  • 原文地址:https://www.cnblogs.com/GarfieldEr007/p/5354570.html
Copyright © 2011-2022 走看看