Requests: ์••์ถ•๋˜์ง€ ์•Š์€ ์ฝ˜ํ…์ธ ๋ฅผ ํŒŒ์ผ๊ณผ ๊ฐ™์€ ๊ฐ์ฒด๋กœ ์ฝ์„ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์—†์Šต๋‹ˆ๋‹ค.

์— ๋งŒ๋“  2012๋…„ 02์›” 29์ผ  ยท  44์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: psf/requests

๋ฌธ์„œ์— ๋”ฐ๋ฅด๋ฉด ์‘๋‹ต ๋‚ด์šฉ์„ ์ฝ๋Š” ๋ฐฉ๋ฒ•์—๋Š” .text , .content ๋ฐ .raw ์žˆ์Šต๋‹ˆ๋‹ค. ์ฒ˜์Œ ๋‘ ๊ฐ€์ง€๋Š” ๋ฉ”๋ชจ๋ฆฌ ๋‚ด ๊ฒฐ๊ณผ๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ์ „์†ก ์ธ์ฝ”๋”ฉ์„ ๊ณ ๋ คํ•˜๊ณ  ์ŠคํŠธ๋ฆผ์„ ์ž๋™์œผ๋กœ ์••์ถ• ํ•ด์ œํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํŠนํžˆ ๊ฒฐ๊ณผ๊ฐ€ ํฐ ๊ฒฝ์šฐ, ์˜ˆ๋ฅผ ๋“ค์–ด XML ๋˜๋Š” Json ํŒŒ์„œ์— ์ง์ ‘ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์ด ํŒŒ์ผ๊ณผ ๊ฐ™์€ ๊ฐ์ฒด์˜ ํ˜•ํƒœ๋กœ ์••์ถ• ํ•ด์ œ๋œ ๊ฒฐ๊ณผ๋ฅผ ์–ป๋Š” ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์€ ํ˜„์žฌ ์—†์Šต๋‹ˆ๋‹ค.

HTTP ์š”์ฒญ์„ ์‚ฌ์šฉ์ž ์นœํ™”์ ์œผ๋กœ ๋งŒ๋“œ๋Š” ๊ฒƒ์„ ๋ชฉํ‘œ๋กœ ํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๊ด€์ ์—์„œ ์‚ฌ์šฉ์ž๊ฐ€ ์›น ์„œ๋ฒ„์™€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๊ฐ„์— ๋‚ด๋ถ€์ ์œผ๋กœ ํ˜‘์ƒ๋œ ์ŠคํŠธ๋ฆผ์˜ ์••์ถ• ์œ ํ˜•๊ณผ ๊ฐ™์€ ๋‚ฎ์€ ์ˆ˜์ค€์˜ ๊ฒƒ์— ๊ด€์‹ฌ์„ ๊ฐ€์ ธ์•ผ ํ•˜๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ๊ฒฐ๊ตญ, ๊ทธ๋Ÿฌํ•œ ์ŠคํŠธ๋ฆผ์„ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ˆ˜๋ฝํ•˜๋Š” ๊ฒƒ์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ "์˜ค๋ฅ˜"์ž…๋‹ˆ๋‹ค. ์ด๋Ÿฐ ์ ์—์„œ .raw ์ŠคํŠธ๋ฆผ์€ ๋‚ด ์ทจํ–ฅ์— ๋„ˆ๋ฌด ์ƒ์†Œํ•ฉ๋‹ˆ๋‹ค.

.stream ์™€ ๊ฐ™์€ ๋„ค ๋ฒˆ์งธ ์†์„ฑ์ด ๋” ๋‚˜์€ ์ถ”์ƒํ™” ์ˆ˜์ค€์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์„๊นŒ์š”?

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

์ด๊ฒƒ์ด ๊ธฐ๋Šฅ ์š”์ฒญ์ด ์•„๋‹Œ ๋””์ž์ธ ๋ฒ„๊ทธ์ธ ์ด์œ ๋Š” ์ด๋ฏธ ์„ค๋ช…ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ์กด API๋Š” ์ž˜๋ชป๋œ ์ถ”์ƒํ™”๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์—ฐ๊ฒฐ์˜ ํ˜‘์ƒ ์„ธ๋ถ€ ์ •๋ณด๋ฅผ ์›๊ฒฉ ์‚ฌ์ดํŠธ์— ๋”ฐ๋ผ ์‚ฌ์šฉ์ž ๊ณต๊ฐ„์œผ๋กœ ๋ˆ„์ถœํ•˜๋ฏ€๋กœ ์‚ฌ์šฉ์ž๊ฐ€ ์‹ ๊ฒฝ์จ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ํ˜„์žฌ ์›์‹œ ์ŠคํŠธ๋ฆผ ์ฝ๊ธฐ ์ง€์›์„ ์‚ฌ์šฉํ•˜๊ธฐ ์–ด๋ ต๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๋ณธ์งˆ์ ์œผ๋กœ ์ด๊ฒƒ์€ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ์š”์ฒญ์ด ์•„๋‹ˆ๋ผ ์†์ƒ๋œ ๊ธฐ๋Šฅ์„ ์ˆ˜์ •ํ•˜๊ธฐ ์œ„ํ•œ ์š”์ฒญ์ž…๋‹ˆ๋‹ค.

๋ชจ๋“  44 ๋Œ“๊ธ€

Response.iter_content

์Œ, ์•„๋‹ˆ์š”, ๊ทธ๊ฒƒ์€ ๋ฐ˜๋ณต์ž์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” ํŒŒ์ผ๊ณผ ๊ฐ™์€ ๊ฐ์ฒด, ์ฆ‰ ๋ฌธ์„œ ํ”„๋กœ์„ธ์„œ๊ฐ€ ์ง์ ‘ ์ฝ์„ ์ˆ˜ ์žˆ๋Š” ๊ฐ์ฒด๋ฅผ ์š”๊ตฌํ–ˆ์Šต๋‹ˆ๋‹ค.

iter_content ๋กœ ํŒŒ์ผ๊ณผ ๊ฐ™์€ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์€ ๋งค์šฐ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค.

๋น ๋ฅธ ๋‹ต๋ณ€ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค, BTW.

๋‚˜๋Š” ๋™์˜ํ•œ๋‹ค. ๊ทธ๋ž˜๋„ requests ์—์„œ ์ด ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์ด ํ›จ์”ฌ ๋” ์‰ฌ์šธ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‚ด ์š”์ ์€ .raw ๊ฐ€ ์ „์†ก ์ˆ˜์ค€ ์„ธ๋ถ€ ์ •๋ณด๋ฅผ ๋…ธ์ถœํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ŠคํŠธ๋ฆผ์—์„œ ์ฝ์œผ๋ ค๋Š” ๋Œ€๋ถ€๋ถ„์˜ ์‚ฌ์šฉ ์‚ฌ๋ก€์— ๋Œ€ํ•ด ์ž˜๋ชป๋œ ์ถ”์ƒํ™” ์ˆ˜์ค€์ด๋ผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ฐœ์ธ์ ์œผ๋กœ HTTP ์š”์ฒญ ๊ฒฐ๊ณผ์— ๋Œ€ํ•ด ์ค„ ๋‹จ์œ„๋กœ ๋ฐ˜๋ณตํ•˜๊ฑฐ๋‚˜ ์ฒญํฌ ๋‹จ์œ„๋กœ ๋ฐ˜๋ณตํ•˜๋Š” ์ฃผ์š” ์‚ฌ์šฉ ์‚ฌ๋ก€๋Š” ๋ณด์ง€ ๋ชปํ•˜์ง€๋งŒ ํŒŒ์ผ๊ณผ ๊ฐ™์€ ๊ฐ์ฒด, ํŠนํžˆ ์‘๋‹ต ํ˜•์‹์œผ๋กœ ๊ตฌ๋ฌธ ๋ถ„์„ํ•˜๋Š” ๋ช‡ ๊ฐ€์ง€ ์ฃผ์š” ์‚ฌ์šฉ ์‚ฌ๋ก€๋ฅผ ๋ด…๋‹ˆ๋‹ค. HTML, XML, Json ๋“ฑ๊ณผ ๊ฐ™์€ ๋ฌธ์„œ ํŒŒ์„œ๊ฐ€ ํ•„์š”ํ•œ

๋˜ํ•œ ํŒŒ์ผ๋ฅ˜ ๊ฐ์ฒด๋ฅผ ๋ž˜ํ•‘ํ•˜๋Š” ๋ฐ˜๋ณต์ž๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด ๋ฐ˜๋ณต์ž๋ฅผ ๋ž˜ํ•‘ํ•˜๋Š” ํŒŒ์ผ๋ฅ˜ ๊ฐ์ฒด๋ณด๋‹ค ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด ํ›จ์”ฌ ์‰ฝ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ ์ฝ”๋“œ๋ฅผ ์ƒ๊ฐํ•ด ๋ƒˆ์Šต๋‹ˆ๋‹ค. ํ•„์š”ํ•œ ๋ชจ๋“  ๊ฒฝ์šฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜์ง€๋งŒ ๋‹ค์†Œ ๋ณต์žกํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๋„์„œ๊ด€์˜ ์ผ๋ถ€๋กœ ์ด๋Ÿฐ ๊ฒƒ์„ ๊ฐ–๊ณ  ์‹ถ๋‹ค๊ณ  ๋งํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๋Š” ์ด๊ฒƒ์„ ์Šค์Šค๋กœ ์•Œ์•„๋‚ผ ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” requests' models.py ๋‚ด๋ถ€์˜ ์ฝ”๋“œ๊ฐ€ ์—ฌ๊ธฐ์„œ ์ž˜๋ชป๋œ ์ถ”์ƒํ™”๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜๋ณตํ•˜๋Š” ๋™์•ˆ์ด ์•„๋‹ˆ๋ผ ๋ฐ˜๋ณต ๊ธฐ๊ณ„๋กœ ์‹œ์ž‘ํ•˜๊ธฐ _์ „์—_ ์›์‹œ ์ŠคํŠธ๋ฆผ์˜ ์••์ถ•์„ ํ’€์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํŒŒ์ผ๋ฅ˜์—์„œ ๋ฐ˜๋ณต์ž๋กœ ๋Œ์•„๊ฐ€์„œ ํŒŒ์ผ๋ฅ˜๋กœ ๋Œ์•„๊ฐ€๋Š” ๊ฒƒ์€ ๊ทธ์ € ์–ด๋ฆฌ์„์€ ์ผ์ž…๋‹ˆ๋‹ค. ๋‹จ์ผ API ๋ณ€ํ™˜์œผ๋กœ ์ถฉ๋ถ„ํ•˜๋ฉฐ ๋Œ€๋ถ€๋ถ„์˜ ์‚ฌ์šฉ์ž๋Š” ์–ด์จŒ๋“  ์ฝ˜ํ…์ธ  ๋ฐ˜๋ณต๊ธฐ์— ๋Œ€ํ•ด ์‹ ๊ฒฝ ์“ฐ์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

class FileLikeDecompressor(object):
    """
    File-like object that wraps and decompresses an HTTP stream transparently.
    """
    def __init__(self, stream, mode='gzip'):
        self.stream = stream
        zlib_mode = 16 + zlib.MAX_WBITS if mode == 'gzip' else -zlib.MAX_WBITS  # magic
        self.dec = zlib.decompressobj(zlib_mode)
        self.data = ''

    def read(self, n=None):
        if self.dec is None:
            return '' # all done
        if n is None:
            data = self.data + self.dec.decompress(self.stream.read())
            self.data = self.dec = None
            return data
        while len(self.data) < n:
            new_data = self.stream.read(n)
            self.data += self.dec.decompress(new_data)
            if not new_data:
                self.dec = None
                break
        if self.data:
            data, self.data = self.data[:n], self.data[n:]
            return data
        return ''

def decompressed(response):
    """
    Return a file-like object that represents the uncompressed HTTP response data.
    For compressed HTTP responses, wraps the stream in a FileLikeDecompressor.
    """
    stream = response.raw
    mode = response.headers.get('content-encoding')
    if mode in ('gzip', 'deflate'):
        return FileLikeDecompressor(stream, mode)
    return stream

์ œ์•ˆ๋œ ๋Œ€๋กœ content_iter ์—์„œ ํŒŒ์ผ๊ณผ ๊ฐ™์€ ๊ฐœ์ฒด๋ฅผ ๋นŒ๋“œํ•˜์ง€ ์•Š๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ณด์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

class FileLikeFromIter(object):
    def __init__(self, content_iter):
        self.iter = content_iter
        self.data = ''

    def __iter__(self):
        return self.iter

    def read(self, n=None):
        if n is None:
            return self.data + '\n'.join(l for l in self.iter)
        else:
            while len(self.data) < n:
                try:
                    self.data = '\n'.join((self.data, self.iter.next()))
                except StopIteration:
                    break
            result, self.data = self.data[:n], self.data[n:]
            return result

๋‚ด ์˜๊ฒฌ, ํŠนํžˆ ๋‚ด๊ฐ€ ๊ฒŒ์‹œํ•œ ์ฝ”๋“œ ์•ž์˜ ๋‹จ๋ฝ์„ ๋‹ค์‹œ ์ฝ๊ณ  ์‹ถ์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ, ํ•˜์ง€๋งŒ ์ด ์†”๋ฃจ์…˜์€ ์ด๋ฏธ ์š”์ฒญ์— ๋‚ด์žฅ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋‘ ๋ฒˆ์งธ ์œ„์น˜์—์„œ ์••์ถ• ํ•ด์ œ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ์—ฌ์ „ํžˆ ๊นจ๋—ํ•˜๊ณ (IMO๊ฐ€ ๋” ์‰ฝ์Šต๋‹ˆ๋‹ค).

๊ทธ๋Ÿฌ๋‚˜ ์ผ๋ฐ˜์ ์œผ๋กœ r.file (๋˜๋Š” ์ด์™€ ์œ ์‚ฌํ•œ ๊ฒƒ)์—๋Š” r.raw ๋ณด๋‹ค ํ›จ์”ฌ ๋” ๋งŽ์€ ์‚ฌ์šฉ ์‚ฌ๋ก€๊ฐ€ ์žˆ๋‹ค๋Š” ๋ฐ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ด๊ฒƒ๋„ ๋ฆฌํ€˜์ŠคํŠธ์— ํฌํ•จ๋˜์—ˆ์œผ๋ฉด ํ•˜๋Š” ๋ฐ”๋žจ์ž…๋‹ˆ๋‹ค. @kennethreitz

"response.stream"์€ ๋‚˜์—๊ฒŒ ์ข‹์€ ์ด๋ฆ„์ฒ˜๋Ÿผ ๋“ค๋ฆฝ๋‹ˆ๋‹ค.

์ด๊ฒƒ์ด response.raw์˜ ์šฉ๋„์ž…๋‹ˆ๋‹ค :)

์ €๋„ ๋ณด๊ณ  ์ง๊ฐ์ ์œผ๋กœ ๊ทธ๋ ‡๊ฒŒ ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์‚ฌ์šฉ์ž๊ฐ€ ์‹ ๊ฒฝ ์“ฐ์ง€ ์•Š์•„๋„ ๋˜๋Š” ๊ธฐ๋ณธ ์ „์†ก ๊ณ„์ธต์˜ ๋‚ด๋ถ€ ์„ธ๋ถ€ ์ •๋ณด๋ฅผ ๋…ธ์ถœํ•˜๊ธฐ ๋•Œ๋ฌธ์— response.raw๊ฐ€ ์†์ƒ๋˜์—ˆ์Œ์„ ๊นจ๋‹ฌ์•˜์Šต๋‹ˆ๋‹ค.

๊ทธ๋“ค์ด ํ•„์š”๋กœ ํ•˜๋Š” ์œ ์ผํ•œ ๋ฐฉ๋ฒ•์€ raw.read ์ž…๋‹ˆ๊นŒ?

์˜ˆ. raw.read()๊ฐ€ ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ๊ฐ„์˜ ๋‚ด๋ถ€ ํ˜‘์ƒ์— ๋”ฐ๋ผ ๋‹ค๋ฅด๊ฒŒ ๋™์ž‘ํ•œ๋‹ค๋Š” ์ ์„ ์ œ์™ธํ•˜๋ฉด ๊ทธ๋ ‡์Šต๋‹ˆ๋‹ค. ๋•Œ๋กœ๋Š” ์˜ˆ์ƒ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  ๋•Œ๋กœ๋Š” ์••์ถ•๋˜์ง€ ์•Š์€ ๋ฐ”์ดํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

๊ธฐ๋ณธ์ ์œผ๋กœ response.raw ๋Š” ๋Œ€๋ถ€๋ถ„์˜ ์‚ฌ์šฉ์ž๊ฐ€ ๊ธฐ๊บผ์ด ๋ฌด์‹œํ•  ์ˆ˜ ์žˆ๊ณ  ์ผ๋ถ€ ๊ณ ๊ธ‰ ์‚ฌ์šฉ์ž๋Š” ์œ ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์œ ์šฉํ•œ ๊ธฐ๋Šฅ์ธ ๋ฐ˜๋ฉด ์••์ถ•์— ๋…๋ฆฝ์ ์ธ response.stream ๋Š” ๋Œ€๋ถ€๋ถ„์˜ ์ŠคํŠธ๋ฆฌ๋ฐ ์‚ฌ์šฉ์ž๊ฐ€ ์›ํ•˜๋‹ค.

+1

+1

์ด ๋””์ž์ธ ๋ฒ„๊ทธ๊ฐ€ ์ˆ˜์ •๋  ์˜ˆ์ •์ธ๊ฐ€์š”?

์ด ๋ฐฉ๋ฒ•์ด ์–ผ๋งˆ๋‚˜ ์ •ํ™•ํ•˜๊ฑฐ๋‚˜ ํšจ์œจ์ ์ธ์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์ง€๋งŒ ์ €์—๊ฒŒ๋Š” ๋‹ค์Œ์ด ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค .

>>> import lxml  # a parser that scorns encoding
>>> unicode_response_string = response.text
>>> lxml.etree.XML(bytes(bytearray(unicode_response_string, encoding='utf-8')))  # provided unicode() means utf-8
<Element html at 0x105364870>

@kernc : ๊ทธ๊ฒŒ ์ด์ƒํ•œ ์ผ์ž…๋‹ˆ๋‹ค. response.content ๋Š” ์ด๋ฏธ ๋ฐ”์ดํŠธ ์ŠคํŠธ๋ง์ด๋ฏ€๋กœ ์—ฌ๊ธฐ์„œ ํ•˜๋Š” ์ผ์€ ํŒŒ์ด์ฌ์ด ์„ ํƒํ•œ ์ง€์˜ฅ ์ฝ”๋ฑ์œผ๋กœ ๋‚ด์šฉ์„ ๋””์ฝ”๋”ฉํ•œ ๋‹ค์Œ utf-8๋กœ ๋‹ค์‹œ ์ธ์ฝ”๋”ฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ๋ฒ„๊ทธ๊ฐ€ _์•„๋‹™๋‹ˆ๋‹ค_, ๋‹น์‹ ์ด ์ œ์•ˆํ•œ ๋ฒ„๊ทธ๋Š” ํ™•์‹คํžˆ ์•„๋‹™๋‹ˆ๋‹ค. ํŒŒ์ผ๋ฅ˜ ๊ฐ์ฒด๊ฐ€ ์ •๋ง๋กœ ํ•„์š”ํ•˜๋‹ค๋ฉด StringIO์™€ BytesIO๋ฅผ ์ถ”์ฒœํ•ฉ๋‹ˆ๋‹ค.

@๋ฃจ์นด์‚ฌ ๋งž์Šต๋‹ˆ๋‹ค. content ๋Š” ํ•ญ์ƒ ๋ฐ”์ดํŠธ์—ด์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(Python 3์—์„œ๋Š” ๋ช…์‹œ์  ๋ฐ”์ดํŠธ์—ด์ด๊ณ  Python 2์—์„œ๋Š” str == bytes). ๋ฐ”์ดํŠธ์—ด์ด ์•„๋‹Œ ์œ ์ผํ•œ ํ•ญ๋ชฉ์€ text ์ž…๋‹ˆ๋‹ค.

@kennethreitz ์ด์— ๋Œ€ํ•œ ์†Œ์‹์ด ์žˆ์Šต๋‹ˆ๊นŒ? ์ด๊ฒƒ์€ ๋งค์šฐ ์‹ฌ๊ฐํ•œ ๋””์ž์ธ ๋ฒ„๊ทธ์ด๋ฉฐ ์กฐ๊ธฐ์— ํ•ด๊ฒฐํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์ข‹์Šต๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋” ๋งŽ์€ ์ฝ”๋“œ๊ฐ€ ์ž‘์„ฑ๋ ์ˆ˜๋ก ๋ชจ๋‘์—๊ฒŒ ๋” ๋งŽ์€ ๋น„์šฉ์ด ๋“ญ๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ๋””์ž์ธ ๋ฒ„๊ทธ๊ฐ€ ์•„๋‹ˆ๋ผ ๊ธฐ๋Šฅ ์š”์ฒญ์ผ ๋ฟ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์š”์ฒญ์— ๊ธฐ๋Šฅ ์ •์ง€ ๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์ด ๊ณง ์š”์ฒญ์— ํฌํ•จ๋˜์ง€ ์•Š์„ ๊ฒƒ์ด๋ผ๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค(๋งŒ์•ฝ ์žˆ๋‹ค๋ฉด)...

๋‚˜๋Š” ์˜ค๋ž˜ ์ง€์†๋˜๋Š” ๋””์ž์ธ ๋ฒ„๊ทธ๋ฅผ "๋ˆ„๋ฝ๋œ ๊ธฐ๋Šฅ"์œผ๋กœ ๋‹ค์‹œ ์„ ์–ธํ•˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.
๋„ˆ๋ฌด ์‰ฝ๊ฒŒ ์‚ฌ๋ผ์ง€๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์ž‘๊ฐ€๊ฐ€ ๊ณ ๋ฏผํ•˜๊ณ  ์žˆ๋‹ค๊ณ  ๋“ค์—ˆ๋‹ค.
"์š”์ฒญ"์„ Python stdlib์˜ ์ผ๋ถ€๋กœ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๊ทธ๊ฒŒ ์ข‹์„๊ฑฐ์•ผ
์ด๊ฒƒ์„ ๊ณ ์น  ๊ธฐํšŒ.

์ž‘๊ฐ€๊ฐ€ ๊ณ ๋ฏผํ•˜๊ณ  ์žˆ๋‹ค๊ณ  ๋“ค์—ˆ๋‹ค.
"์š”์ฒญ"์„ Python stdlib์˜ ์ผ๋ถ€๋กœ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

์‹ค์ œ๋กœ๋Š” ์•„๋‹™๋‹ˆ๋‹ค: http://docs.python-requests.org/en/latest/dev/philosophy/#standard -library

์ด๊ฒƒ์€ ๋ฒ„๊ทธ๊ฐ€ ์•„๋‹ˆ๋ผ ๊ธฐ๋Šฅ ์š”์ฒญ์ž…๋‹ˆ๋‹ค. ์š”์ฒญ์€ ์•„๋ฌด ์ž˜๋ชป๋„ ํ•˜์ง€ ์•Š๊ณ  ๋‹จ์ˆœํžˆ ์„ ํƒ์ ์ธ ์ผ์„ ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์ด ๋ฐ”๋กœ ๊ธฐ๋Šฅ์˜ ์ •์˜์ž…๋‹ˆ๋‹ค.

๋˜ํ•œ stdlib๋ฅผ ์ค€๋น„ํ•˜๋Š” ๊ฒƒ์ด ๋ฐ”๋กœ ์š”์ฒญ์ด ๊ธฐ๋Šฅ ์ •์ง€ ์ƒํƒœ์— ์žˆ๋Š” ์ด์œ ์ž…๋‹ˆ๋‹ค. ์š”์ฒญ์ด stdlib์— ์žˆ์œผ๋ฉด ์ ์‹œ์— ๋ฒ„๊ทธ๋ฅผ ์ˆ˜์ •ํ•˜๊ธฐ๊ฐ€ ๋งค์šฐ ์–ด๋ ค์›Œ์ง‘๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ์ ์œผ๋กœ ์ƒˆ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๋ฉด ๋ฒ„๊ทธ๊ฐ€ ์ถ”๊ฐ€๋˜๊ฑฐ๋‚˜ ๋™์ž‘์ด ํ‡ดํ–‰ํ•˜๋Š” ๊ฒฝ์šฐ ๋‹ค์Œ ๋งˆ์ด๋„ˆ ๋ฆด๋ฆฌ์Šค๊นŒ์ง€ stdlib์˜ ๋ฒ„์ „์„ ์ˆ˜์ •ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ๋‚˜์  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋งˆํฌ ์Š๋ผ์ดํžˆ, 19.03.2013 08:41:

์ž‘๊ฐ€๊ฐ€ ๊ณ ๋ฏผํ•˜๊ณ  ์žˆ๋‹ค๊ณ  ๋“ค์—ˆ๋‹ค.
"์š”์ฒญ"์„ Python stdlib์˜ ์ผ๋ถ€๋กœ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

์‹ค์ œ๋กœ๋Š” ์•„๋‹™๋‹ˆ๋‹ค: http://docs.python-requests.org/en/latest/dev/philosophy/#standard -library

๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ์—ฌ๊ธฐ์—์„œ ์ฝ์—ˆ๋‹ค:

http://python-notes.boredomandlaziness.org/en/latest/conferences/pyconus2013/20130313-language-summit.html

์Šคํ…ŒํŒ

์ด๊ฒƒ์ด ๊ธฐ๋Šฅ ์š”์ฒญ์ด ์•„๋‹Œ ๋””์ž์ธ ๋ฒ„๊ทธ์ธ ์ด์œ ๋Š” ์ด๋ฏธ ์„ค๋ช…ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ์กด API๋Š” ์ž˜๋ชป๋œ ์ถ”์ƒํ™”๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์—ฐ๊ฒฐ์˜ ํ˜‘์ƒ ์„ธ๋ถ€ ์ •๋ณด๋ฅผ ์›๊ฒฉ ์‚ฌ์ดํŠธ์— ๋”ฐ๋ผ ์‚ฌ์šฉ์ž ๊ณต๊ฐ„์œผ๋กœ ๋ˆ„์ถœํ•˜๋ฏ€๋กœ ์‚ฌ์šฉ์ž๊ฐ€ ์‹ ๊ฒฝ์จ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ํ˜„์žฌ ์›์‹œ ์ŠคํŠธ๋ฆผ ์ฝ๊ธฐ ์ง€์›์„ ์‚ฌ์šฉํ•˜๊ธฐ ์–ด๋ ต๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๋ณธ์งˆ์ ์œผ๋กœ ์ด๊ฒƒ์€ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ์š”์ฒญ์ด ์•„๋‹ˆ๋ผ ์†์ƒ๋œ ๊ธฐ๋Šฅ์„ ์ˆ˜์ •ํ•˜๊ธฐ ์œ„ํ•œ ์š”์ฒญ์ž…๋‹ˆ๋‹ค.

๊น”๋”ํ•˜๊ฒŒ ์ •๋ฆฌํ•ด๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค. ๋ฒ„๊ทธ๋Š” ์›์‹œ ์ŠคํŠธ๋ฆผ ์ฝ๊ธฐ ๊ธฐ๋Šฅ์˜ ์‹ค์ œ ์‚ฌ์šฉ์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์ผ๋ถ€, ํŠนํžˆ ์ „์ฒด ์กฐ๊ฑด๋ถ€ ์ŠคํŠธ๋ฆผ ์••์ถ• ํ•ด์ œ ๋ถ€๋ถ„์„ ๋‹ค์‹œ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์••์ถ•์„ ํ—ˆ์šฉํ•˜๋Š” ์ฆ‰์‹œ ๊ธฐ๋Šฅ์ด ์—†์œผ๋ฉด ๊ธฐ๋Šฅ์ด ์“ธ๋ชจ๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” "์š”์ฒญ"์— ์ด๋ฏธ ์žˆ๋Š” ์ฝ”๋“œ์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ž˜๋ชป๋œ ์œ„์น˜์—์„œ ์‚ฌ์šฉ๋˜์—ˆ์„ ๋ฟ์ž…๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์„œ๋ฒ„๊ฐ€ ์ˆ˜๋ฝ ํ—ค๋”๋ฅผ ์กด์ค‘ํ•˜๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ์ œ์–ดํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์›์‹œ ์ฝ๊ธฐ ์ˆ˜์ค€๋ณด๋‹ค ๋‚ฎ์€ ์ˆ˜์ค€์—์„œ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์••์ถ•์€ ์—ฐ๊ฒฐ์˜ ํˆฌ๋ช…ํ•œ ํ˜‘์ƒ ์„ธ๋ถ€ ์‚ฌํ•ญ์ด์–ด์•ผ ํ•˜๋ฉฐ, ๊ด€๋ จ ํ—ค๋”๋ฅผ ํ™œ์„ฑํ™”ํ•˜๋Š” ์‚ฌ์šฉ์ž์—๊ฒŒ ํ”ผํ•ด๋ฅผ ์ฃผ์ง€ ์•Š์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.

ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์••์ถ•๋œ ์ŠคํŠธ๋ฆผ์— ๊ด€์‹ฌ์„ ๊ฐ€์งˆ ์‚ฌ์šฉ ์‚ฌ๋ก€๋Š” ์ƒ๊ฐํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ํŠนํžˆ ์„œ๋ฒ„๊ฐ€ ํด๋ผ์ด์–ธํŠธ์˜ ํฌ๋ง์„ ๊ธฐ์˜๊ฒŒ ๋ฌด์‹œํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ŠคํŠธ๋ฆผ์ด ์‹ค์ œ๋กœ ์••์ถ•๋˜๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ์˜ˆ์ธกํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ์—๋Š” ๋”์šฑ ๊ทธ๋ ‡์Šต๋‹ˆ๋‹ค. ์ˆœ์ˆ˜ํ•œ ํ˜‘์ƒ ์„ธ๋ถ€ ์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ์›์‹œ ์ŠคํŠธ๋ฆผ ์ฝ๊ธฐ๊ฐ€ ๊ฐ€์žฅ ์ผ๋ฐ˜์ ์ธ ๊ฒƒ๋ณด๋‹ค ๊ทนํžˆ ๊ฐ€๋Šฅ์„ฑ์ด ๋‚ฎ์€ ์‚ฌ์šฉ ์‚ฌ๋ก€๋ฅผ ์„ ํ˜ธํ•˜์—ฌ ์ž˜๋ชป๋œ ์ถ”์ƒํ™”๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ์ž…๋‹ˆ๋‹ค.

์ € ํ•  ์ˆ˜ ์žˆ์–ด์š”. ์˜ˆ๋ฅผ ๋“ค์–ด ๋Œ€์šฉ๋Ÿ‰ ํ…์ŠคํŠธ ๊ธฐ๋ฐ˜ ํŒŒ์ผ์„ ๋‹ค์šด๋กœ๋“œํ•˜๊ณ  ์••์ถ•๋œ ์ƒํƒœ๋กœ ์œ ์ง€ํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ? No way to save original-compressed data to disk ๋ผ๋Š” ์ œ๋ชฉ์˜ ์ƒˆ๋กœ์šด '๋””์ž์ธ ๋ฒ„๊ทธ'๋กœ ์ด ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ถ”์ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ ์•„์ด๋””์–ด๋Š” ์˜๋„์ ์œผ๋กœ ์ง„๋ถ€ํ•˜๊ณ  ์–ด๋ฆฌ์„์€ ๊ฒƒ์ด์ง€๋งŒ ์š”์ ์„ ์„ค๋ช…ํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ์š”์ฒญ์ด ๋ชจ๋“  ์‚ฌ๋žŒ์—๊ฒŒ ๊ทธ๋“ค์ด ์›ํ•˜๋Š” ์ƒํ˜ธ ์ž‘์šฉ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์ •ํ™•ํžˆ ์ œ๊ณตํ•  ์˜๋ฌด๋Š” ์—†์Šต๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ๊ทธ๋ ‡๊ฒŒ ํ•˜๋Š” ๊ฒƒ์€ API์˜ ๋‹จ์ˆœ์„ฑ์ธ Requests์˜ ์ฃผ์š” ๋ชฉํ‘œ์— ์ง์ ‘์ ์œผ๋กœ ๋ฐ˜๋Œ€๋˜๋Š” ์‹คํ–‰์ด ๋ฉ๋‹ˆ๋‹ค. ์œ ์šฉํ•œ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ–ˆ์Œ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  API๋ฅผ ๋ณต์žกํ•˜๊ฒŒ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด์˜๊ฐ€ ์ œ๊ธฐ๋œ ์š”์ฒญ์— ๋Œ€ํ•œ ๊ธธ๊ณ  ๊ธด_ ์ œ์•ˆ๋œ ๋ณ€๊ฒฝ ๋ชฉ๋ก์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์š”์ฒญ์€ ๋ชจ๋“  ์‚ฌ์šฉ ์‚ฌ๋ก€์— ๋Œ€ํ•ด urllib2๋ฅผ ๋Œ€์ฒดํ•˜๋Š” ๊ฒƒ์„ ๋ชฉํ‘œ๋กœ ํ•˜์ง€ ์•Š์œผ๋ฉฐ ๊ฐ€์žฅ ์ผ๋ฐ˜์ ์ธ ๊ฒฝ์šฐ๋ฅผ ๋‹จ์ˆœํ™”ํ•˜๋Š” ๊ฒƒ์„ ๋ชฉํ‘œ๋กœ ํ•ฉ๋‹ˆ๋‹ค.

์ด ๊ฒฝ์šฐ Requests๋Š” ๋Œ€๋ถ€๋ถ„์˜ ์‚ฌ์šฉ์ž๊ฐ€ ํŒŒ์ผ๊ณผ ๊ฐ™์€ ๊ฐ์ฒด๋ฅผ ์›ํ•˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๋ฏ€๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ƒํ˜ธ ์ž‘์šฉ์„ ์ œ์•ˆํ•ฉ๋‹ˆ๋‹ค.

  • Response.text ๋ฐ Response.content : ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฅผ ํ•œ ๋ฒˆ์— ์›ํ•ฉ๋‹ˆ๋‹ค.
  • Response.iter_lines() ๋ฐ Response.iter_content() : ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฅผ ํ•œ ๋ฒˆ์— ์›ํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค.
  • Response.raw : ๋‹ค๋ฅธ ๋‘ ๊ฐ€์ง€ ์˜ต์…˜์ด ๋งˆ์Œ์— ๋“ค์ง€ ์•Š์œผ๋‹ˆ ์ง์ ‘ ํ•˜์‹ญ์‹œ์˜ค.

์ด๋“ค์€ Requests์˜ ์ผ๋ฐ˜์ ์ธ ์šฉ๋„๋ฅผ ์••๋„์ ์œผ๋กœ ๋Œ€ํ‘œํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์„ ํƒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋‹น์‹ ์€ " ๋Œ€๋ถ€๋ถ„์˜ ์‚ฌ์šฉ์ž๋Š” ์–ด์จŒ๋“  ์ฝ˜ํ…์ธ  ๋ฐ˜๋ณต์ž์— ๋Œ€ํ•ด ์‹ ๊ฒฝ ์“ฐ์ง€ ์•Š์„ ๊ฒƒ "์ด๋ผ๊ณ  ๋งํ–ˆ๊ณ  " response.stream ๋Š” ๋Œ€๋ถ€๋ถ„์˜ ์ŠคํŠธ๋ฆฌ๋ฐ ์‚ฌ์šฉ์ž๊ฐ€ ์›ํ•˜๋Š” ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค ". ์ด ํ”„๋กœ์ ํŠธ์— ๋Œ€ํ•œ ๊ฒฝํ—˜์€ ๋™์˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด ์ฝ˜ํ…์ธ  ๋ฐ˜๋ณต์ž๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ํŒŒ์ผ๊ณผ ๊ฐ™์€ ๊ฐ์ฒด๋ฅผ ๊ฐ„์ ˆํžˆ ์›ํ•˜๋Š” ์‚ฌ๋žŒ์€ ๋งŽ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋งˆ์ง€๋ง‰ ์š”์ : ์••์ถ•์ด ์—ฐ๊ฒฐ์˜ ํˆฌ๋ช…ํ•œ ํ˜‘์ƒ ์„ธ๋ถ€ ์‚ฌํ•ญ์ด์–ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ ์—ฐ๊ฒฐ ๋…ผ๋ฆฌ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” urllib3์— ๋Œ€ํ•ด ์ ์ ˆํ•œ ๋ฒ„๊ทธ๋ฅผ ์ œ๊ธฐํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์š”์ฒญ์ด ๊ท€ํ•˜์˜ ์‚ฌ์šฉ ์‚ฌ๋ก€์— ๋ถ€์ ์ ˆํ•˜๋‹ค๊ณ  ๋Š๋ผ์…จ๋‹ค๋‹ˆ ์œ ๊ฐ์ž…๋‹ˆ๋‹ค.

ํ˜„์žฌ ๊ตฌํ˜„์—์„œ response.raw ๊ฐ€ ์†์ƒ๋˜์—ˆ์œผ๋ฉฐ ๋ถ€๋ถ„์ ์œผ๋กœ๋Š” ์ด์— ๋™์˜ํ•ฉ๋‹ˆ๋‹ค(์ ์–ด๋„ ํ—ค๋”๋ฅผ ๊ตฌ๋ฌธ ๋ถ„์„ํ•˜์ง€ ์•Š๊ณ  ์••์ถ• ์„ธ๋ถ€ ์ •๋ณด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์–ด์•ผ ํ•จ).

๊ทธ๋Ÿฌ๋‚˜ ๊ท€ํ•˜์˜ ์ œ์•ˆ์€ ์—ฌ์ „ํžˆ โ€‹โ€‹๊ธฐ๋Šฅ ์š”์ฒญ์ž…๋‹ˆ๋‹ค ...

@๋ฃจ์นด์‚ฌ
urllib3์— ๋Œ€ํ•œ ๋ฒ„๊ทธ ์‹ ๊ณ ๊ฐ€ ์š”์ฒญ์˜ API๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ ์–ด๋„ ๊ทธ ์ž์ฒด๋Š” ์•„๋‹™๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ๊ท€ํ•˜์˜ "์‚ฌ์šฉ ์‚ฌ๋ก€"๊ฐ€ ๊ณ ์•ˆ๋˜์—ˆ๋‹ค๋Š” ๋ฐ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ๋งํ–ˆ๋“ฏ์ด ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์„œ๋ฒ„ ์ธก์—์„œ ์••์ถ•์„ ์ ๊ทน์ ์œผ๋กœ ์ œ์–ดํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ(๋น„ํ™œ์„ฑํ™”ํ•˜์ง€๋งŒ ์•ˆ์ •์ ์œผ๋กœ ํ™œ์„ฑํ™”ํ•˜์ง€ ๋ชปํ•˜๋Š” ๊ฒฝ์šฐ) ์••์ถ• ํŒŒ์ผ์„ ๋””์Šคํฌ์— ์ €์žฅํ•  ์ˆ˜ ์žˆ๋„๋ก ํด๋ผ์ด์–ธํŠธ์— ์˜์กดํ•˜๋Š” ๊ฒƒ์€ ๊ทธ๋‹ค์ง€ ํฅ๋ฏธ๋กญ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. .

@schlamar
๊ทธ๋ ‡๊ฒŒ ์ฝ์„ ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์— ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ์–ด๋–ค ๊ฒƒ์ด๋“  ๊ดœ์ฐฎ๋‹ค๊ณ  ํ™•์‹ ํ•ฉ๋‹ˆ๋‹ค. ๊ฑฐ๊ธฐ์— ๊ฐ€๊ธฐ ์œ„ํ•ด ์ƒˆ ํ‹ฐ์ผ“์„ ์—ฌ๋Š” ๊ฒƒ์ด ํ•„์š”ํ•˜๋‹ค๋ฉด ๊ทธ๋ ‡๊ฒŒ ํ•˜์‹ญ์‹œ์˜ค.

๊ฑฐ๊ธฐ์— ๊ฐ€๊ธฐ ์œ„ํ•ด ์ƒˆ ํ‹ฐ์ผ“์„ ์—ฌ๋Š” ๊ฒƒ์ด ํ•„์š”ํ•˜๋‹ค๋ฉด ๊ทธ๋ ‡๊ฒŒ ํ•˜์‹ญ์‹œ์˜ค.

๋‚˜๋Š” ์—ฌ์ „ํžˆ Kenneth๊ฐ€ ๊ธฐ๋Šฅ ์ •์ง€๋กœ ์ธํ•ด ์ด๊ฒƒ์„ ๊ฑฐ๋ถ€ํ•  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ชจ๋“  ๊ฒƒ์ด ์ข‹๋‹ค

  1. iter_content ๋ฅผ ํŒŒ์ผ๋ฅ˜ ๊ฐ์ฒด๋กœ ๊ฐ์‹ธ๊ฑฐ๋‚˜
  2. ํ—ค๋”๋ฅผ ๊ตฌ๋ฌธ ๋ถ„์„ํ•˜๊ณ  ์ ์ ˆํ•œ ๊ฒฝ์šฐ response.raw ์••์ถ•์„ ํ•ด์ œํ•ฉ๋‹ˆ๋‹ค.

๋‘ ๊ฐ€์ง€ ์†”๋ฃจ์…˜ ๋ชจ๋‘ ์œ„์˜ ๋Œ“๊ธ€์— ์žˆ์œผ๋ฉฐ ํ›„์ž๋Š” ๊ท€ํ•˜๊ฐ€ ๊ฒŒ์‹œํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ์š”์ฒญ์— ์ง์ ‘ ํฌํ•จ๋˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ์™œ ๊ทธ๋Ÿฌํ•œ ๋ฌธ์ œ์ž…๋‹ˆ๊นŒ?

์—ฌ๊ธฐ์—์„œ 100% ๋ช…ํ™•ํžˆ ํ•ฉ์‹œ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ๊ธฐ๋Šฅ์ด ์ •์ง€๋œ ๋™์•ˆ ์š”์ฒญ์— ๋“ค์–ด๊ฐˆ ๊ฐ€๋Šฅ์„ฑ์€ ์—†์Šต๋‹ˆ๋‹ค. ๊ณ ์žฅ๋‚œ ๊ฒƒ์€ ์—†์œผ๋ฉฐ API๊ฐ€ ๊ท€ํ•˜์˜ ์š”๊ตฌ์— ์™„๋ฒฝํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ณ ์žฅ๋‚œ ๊ฒƒ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— ์ค‘์š”ํ•œ ๊ฒƒ์€ Kenneth๊ฐ€ ์›ํ•˜๋Š”์ง€ ์—ฌ๋ถ€๋ฟ์ž…๋‹ˆ๋‹ค. ์š”์ฒญ์€ ๋ฏผ์ฃผ์ฃผ์˜๊ฐ€ ์•„๋‹ˆ๋ผ 1์ธ 1ํ‘œ์ž…๋‹ˆ๋‹ค. Kenneth๋Š” ๋‚จ์ž์ด๊ณ  ๊ทธ๋Š” ํˆฌํ‘œ๊ถŒ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. Kenneth๋Š” 8๊ฐœ์›” ์ „์— ์ด ๋ฌธ์ œ๋ฅผ ๋‹ซ์•˜์œผ๋ฏ€๋กœ ๊ทธ๊ฐ€ ๊ทธ๊ฒƒ์„ ์›ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์ด ๊ฝค ๋ถ„๋ช…ํ•œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

urllib3์— ๋Œ€ํ•œ ๋ฒ„๊ทธ ์‹ ๊ณ ๊ฐ€ ์š”์ฒญ์˜ API๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ ์–ด๋„ ๊ทธ ์ž์ฒด๋Š” ์•„๋‹™๋‹ˆ๋‹ค.

์••์ถ•๋˜์ง€ ์•Š์€ ํŒŒ์ผ ๊ฐœ์ฒด๋ฅผ ํ•ญ์ƒ ๋ฐ˜ํ™˜ํ•˜๋„๋ก urllib3์„ ํŒจ์น˜ํ•˜๋ฉด ์ด ๋ฌธ์ œ๊ฐ€ ์ €์ ˆ๋กœ ํ•ด๊ฒฐ๋ฉ๋‹ˆ๋‹ค(์ข‹์€ ์ƒ๊ฐ์€ ์•„๋‹™๋‹ˆ๋‹ค).

์•„, ์†”๋ฃจ์…˜ ๋ฒˆํ˜ธ 3(ํ…Œ์ŠคํŠธ๋˜์ง€ ์•Š์Œ)์ด ์žˆ์Šต๋‹ˆ๋‹ค.

response.raw.read = functools.partial(response.raw.read, decode_content=True)

https://github.com/shazow/urllib3/blob/master/urllib3/response.py#L112 ์ฐธ์กฐ

ํฅ๋ฏธ๋กญ๋‹ค - ๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ์ง€๊ธˆ๊นŒ์ง€ ์กด์žฌํ•˜๋Š”์ง€ ๋ชฐ๋ž์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ๊ธฐ๋Šฅ์„ ํ›จ์”ฌ ์‰ฝ๊ฒŒ ๋ž˜ํ•‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ์‹ค์ œ๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๊นŒ? ์ฆ‰, ์••์ถ• ํ•ด์ œ๊ธฐ๊ฐ€ ์ƒํƒœ ์ €์žฅ ๋ฐ ์ฆ๋ถ„์ž…๋‹ˆ๊นŒ? ์˜ˆ๋ฅผ ๋“ค์–ด, ๋‘ ๋ฒˆ์งธ read(123) ํ˜ธ์ถœ์€ ๋” ์ด์ƒ gzip ํŒŒ์ผ์˜ ์œ ํšจํ•œ ์‹œ์ž‘์„ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ์‹ค์ œ๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๊นŒ? ์ฆ‰, ์••์ถ• ํ•ด์ œ๊ธฐ๊ฐ€ ์ƒํƒœ ์ €์žฅ ๋ฐ ์ฆ๋ถ„์ž…๋‹ˆ๊นŒ?

์˜ค, ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋…์ŠคํŠธ๋ง์„ ์ฝ์ง€ ์•Š์•˜๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์—ฌ๊ธฐ ๋‚ด ์ œ์•ˆ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  1. HTTPResponse.read ๊ฐ€ amt ๋ฐ decode_content ๋™์‹œ์— ์ž‘๋™ํ•˜๋„๋ก urllib3์„ ํŒจ์น˜ํ•ฉ๋‹ˆ๋‹ค.
  2. HTTPResponse._decode_content๋ฅผ ๊ณต๊ฐœ ๋ฉค๋ฒ„๋กœ ๋งŒ๋“ญ๋‹ˆ๋‹ค( read ๋ฉ”์„œ๋“œ๋ฅผ ํŒจ์น˜ํ•˜๋Š” ๋Œ€์‹  response.raw.decode_content = True ๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Œ).
  3. decode_content=True ์—์„œ iter_content decode_content=True ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์š”์ฒญ์—์„œ ์™„์ „ํžˆ ์••์ถ• ํ•ด์ œ

@Lukasa ๊ธฐ๋Šฅ ์ •์ง€๋ฅผ ์œ„๋ฐ˜ํ•˜์ง€๋Š” ์•Š์„ ๊ฒƒ ๊ฐ™์€๋ฐ์š”?

@schlamar : ์›์น™์ ์œผ๋กœ

์–ด์จŒ๋“  ์š”์ฒญ์˜ stream_decompress ๊ฐ€ ๊นจ์กŒ์Šต๋‹ˆ๋‹ค: #1249

+1

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰