기술나눔

Python 크롤러 튜토리얼 6부 - 세션을 사용하여 요청 시작

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

세션을 사용하는 이유

이전에는 reqesuts를 사용하여 요청을 시작하는 방법을 소개했습니다. 오늘은 세션을 사용하여 요청을 시작하는 방법을 소개하겠습니다. 세션에 대한 간단한 이해는 세션 메커니즘입니다. 브라우저에 로그인한 후에는 나중에 서비스 데이터를 요청할 때 다시 로그인할 필요가 없으며, 각 요청은 자동으로 쿠키에 저장됩니다. reqeusts.request를 사용하는 경우 매번 쿠키 매개변수를 수동으로 전달해야 합니다. reqeuest.Session() 세션 객체를 사용하면 요청 전반에 걸쳐 특정 매개변수를 유지할 수 있습니다. 또한 동일한 세션 인스턴스에서 이루어진 모든 요청 간에 쿠키를 유지하므로 매번 쿠키 상태를 수동으로 처리할 필요가 없습니다.

참조 문서:
공식 문서

사용하는 방법

session의 사용법은 실제로 reqeust 메소드와 유사하며, session.get(), session.post(), session.request() 등의 메소드도 지원합니다.

s = requests.Session()

s.get('https://httpbin.org/cookies/set/sessioncookie/123456789')
r = s.get('https://httpbin.org/cookies')

print(r.text)
# '{"cookies": {"sessioncookie": "123456789"}}'
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

모범 사례 쿠키 재사용

일부 웹사이트 처리 시 필요한 로그인 인증 권한을 세션을 통해 요청할 수 있으며, 로그인 후 획득한 쿠키가 저장되므로 나중에 로그인이 필요할 때마다 저장된 쿠키를 바로 이용하여 이 쿠키를 사용할 수 있습니다. 세션을 시작한 다음 반복되는 로그인을 피하기 위해 요청을 시작합니다. 여러 시스템의 데이터를 동시에 크롤링하는 데 적합합니다.

쿠키 재사용 사례:

import json
import traceback

import requests.utils

from executor.page_executor import PageExecutor
from file_path import get_absolute_path


cookie_path = get_absolute_path('data/cookie.txt')
request_session: requests.Session = None

def __load_cookie():
    '''
    加载本地cookie,如果存在加载,如果不存在就返回空
    :param session:
    :return:
    '''
    try:
        with open(cookie_path, "r") as f:
            load_cookie = json.load(f)
            return requests.utils.cookiejar_from_dict(load_cookie)
    except Exception as e:
        traceback.print_exc()
        return None

def get_session():
    global request_session
    if request_session is not None:
        return request_session
    else:
        request_session = requests.Session()
        exist_cookies = __load_cookie()
        if exist_cookies is not None:
            request_session.cookies.update(exist_cookies)

        return request_session

def save_cookie():
    # 登录成功, session里的cookie是最全的,response返回的cookie不全
    cookiejar = requests.utils.dict_from_cookiejar(request_session.cookies)
    with open(cookie_path, "w") as f:
        json.dump(cookiejar, f, indent=True)
    whv_logger.info('cookies saved to ./data/cookie.txt')


def update_cookie():
    '''
    为什么需要一个新的session
    # 走到这一步,说明session已经过期,重新获取session,需要重新处理下session
    # 1. 但是因为携带有旧的session,导致携带旧的__RequestVerificationToken和新的__RequestVerificationToken一起请求,登录失败
    # 2. 所以需要重新处理下session,主要是处理__RequestVerificationToken
    :return:
    '''
    error_cookie_jar = requests.utils.dict_from_cookiejar(request_session.cookies)

    new_cookie_jar = {'__RequestVerificationToken': error_cookie_jar['__RequestVerificationToken']}
    new_cookie = requests.utils.cookiejar_from_dict(new_cookie_jar)

    # 清空旧的cookie
    request_session.cookies.clear_session_cookies()
    # 填充新的cookie
    request_session.cookies.update(new_cookie)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63