[踩坑]python实现并行爬虫


问题背景:指定爬虫depth、线程数, python实现并行爬虫
思路: 单线程 实现爬虫类Fetcher
多线程 threading.Thread去调Fetcher

方法:Fetcher 中,用urllib.urlopen打开指定url,读取信息:

 

response = urllib.urlopen(self.url)
content = response.read()
但是这样有问题, 比如对于www.sina.com来说,读出来的content是乱码的:

 

 

>>> content[0:100]
'?ì½k?×u ø??ÐHWè*t=2ëÕÕ]H`4@4??ð%êȪÊîN º²X??X¨Cj¶ly-?õ %ÊEñ!R?¨?C3?ñØ#?½;?Ø??±ò'


 

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

chardet.detect(content)
进行content中字符集的检测:

 

 

>>> chardet.detect(content)
{'confidence': 0.99, 'encoding': 'GB2312'}

好,问题解决了:

 

 

>>> import urllib
>>> url = 'http://www.sina.com'
>>> response = urllib.urlopen(url)
>>> content = response.read()
>>> chardet.detect(content)
{'confidence': 0.99, 'encoding': 'GB2312'}


 

 

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

 

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

 

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

 

>>> import urllib
>>> url = 'http://www.sina.com'
>>> response = urllib2.urlopen(url, timeout=1)
>>> content = response.read()
>>> chardet.detect(content)
{'confidence': 0.0, 'encoding': None}

 

这是怎么回事? 原来是这个页面的编码问题, 该页面返回的是gzip编码,参考

 

实际上每次应该判断页面信息的'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为单测(不保证覆盖率)。

 

评论关闭