在使用 Python 编写脚本时,我遇到一个奇怪的问题。我的脚本需要将搜索结果记录到日志文件中。但问题是,每次搜索到的结果都会被记录一次,而第一个结果会被记录多次,第二个结果会被记录两次,以此类推。例如,以下代码将搜索结果记录到日志文件中:
#!/usr/bin/python
import urllib
import simplejson
import logging
from logging.handlers import SysLogHandler
query = urllib.urlencode({'q' : 'test'})
url = 'http://ajax.googleapis.com/ajax/services/search/web?v=1.0&%s' \
http://www.jshk.com.cn/mb/reg.asp?kefu=xiaoding;//爬虫IP免费获取;
% (query)
search_results = urllib.urlopen(url)
json = simplejson.loads(search_results.read())
results = json['responseData']['results']
# 在循环中添加日志记录器和文件句柄
for i in results:
logger = logging.getLogger()
logger.addHandler(SysLogHandler(address=('192.168.0.2', 514)))
logger.addHandler(logging.FileHandler("hits.log"))
logging.warn(i['url'])
print i['url']
这样,每个搜索结果都会被记录一次,而第一个结果会被记录多次。
2、解决方案
解决方案1:
一个可能的解决方案是将日志记录器和文件句柄移出循环,仅在循环中记录日志。这样,每个搜索结果只会被记录一次。
#!/usr/bin/python
import urllib
import simplejson
import logging
from logging.handlers import SysLogHandler
query = urllib.urlencode({'q' : 'test'})
url = 'http://ajax.googleapis.com/ajax/services/search/web?v=1.0&%s' \
% (query)
# 将日志记录器和文件句柄移出循环
logger = logging.getLogger('')
logger.addHandler(logging.FileHandler("hits.log"))
logger.addHandler(SysLogHandler(address=('192.168.0.2', 514)))
search_results = urllib.urlopen(url)
json = simplejson.loads(search_results.read())
results = json['responseData']['results']
# 在循环中记录日志
for i in results:
logging.warn(i['url'])
print i['url']
解决方案2:
另一个可能的解决方案是每次在循环中添加日志记录器和文件句柄时,在循环结束时将它们移除。这样,每个搜索结果只会被记录一次。
#!/usr/bin/python
import urllib
import simplejson
import logging
from logging.handlers import SysLogHandler
query = urllib.urlencode({'q' : 'test'})
url = 'http://ajax.googleapis.com/ajax/services/search/web?v=1.0&%s' \
% (query)
# 创建一个日志记录器
logger = logging.getLogger('')
search_results = urllib.urlopen(url)
json = simplejson.loads(search_results.read())
results = json['responseData']['results']
# 在循环中添加和移除日志记录器和文件句柄
for i in results:
# 添加日志记录器和文件句柄
logger.addHandler(SysLogHandler(address=('192.168.0.2', 514)))
logger.addHandler(logging.FileHandler("hits.log"))
# 记录日志
logging.warn(i['url'])
print i['url']
# 移除日志记录器和文件句柄
logger.removeHandler(SysLogHandler(address=('192.168.0.2', 514)))
logger.removeHandler(logging.FileHandler("hits.log"))
通过使用这两种解决方案中的一种,就可以消除日志文件中重复行的现象。