python3 request 爬虫 httplib.IncompleteRead() 问题的简单解决方法

起因

在一个循环爬取得爬虫中,随机出现一个 httplib.IncompleteRead() 错误。

分析

查询了许多资料之后了解到,这个是由于 chunked 编码不完整导致,那么如何解决这个问题?由于这时候其实数据我们已经拿到了,但是 http_client 认为没有结束,所以有这么一个错误。具体分析过程可以看看这篇博文很详细。博文传送门

处理

这里由于项目中充斥着 Request,不方便换,而且文件不大,所以我通过最简单的处理方式来处理这个问题(处理方式来源),这种方式可能会带来数据丢失(在大文件的情况下)
自己抓取到这个错误
通过 错误.partial.decode(‘utf-8’) 来获取到文件内容
实例代码:

def __init__(self, e, uri, format, uriparts):
        self.e = e
        self.uri = uri
        self.format = format
        self.uriparts = uriparts
        try:
            data = self.e.fp.read()
        except http_client.IncompleteRead as e:
            data = e.partial
        if self.e.headers.get('Content-Encoding') == 'gzip':
            buf = BytesIO(data)
            f = gzip.GzipFile(fileobj=buf)
            data = f.read()
        if len(data) == 0:
            data = {}
        else:
            data = data.decode('utf-8')
            if self.format == 'json':
                try:
                    data = json.loads(data)
                except ValueError:
                    pass
        self.response_data = data
        super(FanfouHTTPError, self).__init__(str(self))

本文对应代码

    def get_cartoon_json(self,categories):
        for category in categories:
            hasMore = True
            index = 1
            while hasMore:
                try:
                    link = self.__baseUrl + '/' + category['name']+'/'+str(index)
                    # 转换中文 url 编码
                    link = urllib.request.quote(link)
                    print(link)
                    # 把多余的转换 : ==> %3A ,还原
                    link = link.replace('%3A', ':')
                    # 打开链接
                    conn = req.urlopen(link)
                    # 以 utf-8 编码获取网页内容
                    content = conn.read().decode('utf-8')

                except http_client.IncompleteRead as e:
                    # 处理 chunked 读取错误,由于这里都是 json 所以就不再作 gzip 验证
                    content = e.partial
                    content = content.decode('utf-8')
                    if len(content) == 0:
                        content = '{}'

                print(content)
                jsonUtils = BaiDuCartoonUtils(self.__filePath)
                jsonUtils.write_json_to_jsonFile(content, self.__filePath + category['name'] + '/list/',
                                                 'data' + str(index) + '.json')

                jsonStr = json.loads(content)
                if jsonStr['data']['hasMore'] != 1:
                    hasMore = False
                index = index + 1
                # jsonUtils.write_cartoon_to_json('/api/query/'+self.__categoryName, content)

如有问题,欢迎指正

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值