栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Python登录CSDN

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Python登录CSDN

环境
  • 操作系统:windows 10 x64
  • 集成环境:Visual Studio Code
  • Python版本:v3.10.5 64位
    – 解码需要os、sqlite3、win32crypt、base64、cryptography、json库
    – 访问网页需要urllib、http库
一、说明

本文是承接另一篇博文基于Python通过Chrome的Cookie登录百度账户的姊妹篇。在对代码进行封装后,尝试对CSDN进行访问。对于一些思路的说明,可以参考上文。

二、工程文件结构

工程目录

  • [dir] log
  • [dir] modules
  • [dir] resource
  • [file] main.py
  • [file] app.py
三、资源构建 1、在resource文件夹内创建配置文件config

resource

  • [file] config

内容如下:

{
    ".csdn.net": ["TRUE","FALSE"],
    ".www.csdn.net": ["TRUE","FALSE"]
}
2、在modules文件夹内创建支持模块conn.py、cookie.py、decode.py,_init_.py:

modules

  • [file] conn.py
  • [file] cookie.py
  • [file] decode.py
  • [file] _init_.py.py

内容如下:


2.1 conn.py,继承于Connection类,加了上下文管理方便使用with调用
import sqlite3
from typing import *


class Conn(sqlite3.Connection):
    def __init__(self, path) -> None:
        super().__init__(path)
        self._path = path

    def __enter__(self) -> sqlite3.Connection.cursor:
        return self.cursor()

    def __exit__(self, exc_type, exc_value, exc_traceback) -> None:
        self.cursor().close()
        self.close()
        if exc_traceback is None:
            ...
        else:
            ...

    def __repr__(self) -> str:
        return '_conn(path = %s)' % self._path


2.2 cookie.py,用于将给的原材料加工成可以使用的cookie文件
import json
import time
from typing import *


with open('./resource/config', 'r') as f:
    BAIDU_BOOL = json.load(f)

# cookie文件头,最后一步手工生成cookie会用得到
COOKIE_HEADER = """# Netscape HTTP Cookie Filen# http://curl.haxx.se/rfc/cookie_spec.htmln# This is a generated file!  Do not edit.nn"""


class Cookie:
    '''这个类可以用来生成cookie文件'''
    def __init__(self, cookieList: List[Tuple[str, str, str, str, str]]) -> None:
        self.cookieList = cookieList

    def __repr__(self) -> str:
        return 'Cookie(count=%d)' % len(self.cookieList)

    def getOne(self):
        '''此方法可以将cookie封装成生成器对象,通过next()函数调用'''
        for i in self.cookieList:
            creation_utc, host_key, name, value, path = i
            cookieContent = str(host_key) + 't' + str(BAIDU_BOOL[host_key][0] if host_key in BAIDU_BOOL.keys() else 'FALSE') + 't' + str(path) + 't' + str(
                BAIDU_BOOL[host_key][1] if host_key in BAIDU_BOOL.keys() else 'FALSE') + 't' + str(creation_utc) + 't' + str(name) + 't' + str(value)
            yield cookieContent

    def getAll(self):
        '''此方法可以将cookie的所有内容输出到控制台'''
        for i in self.cookieList:
            creation_utc, host_key, name, value, path = i
            cookieContent = str(host_key) + 't' + str(BAIDU_BOOL[host_key][0] if host_key in BAIDU_BOOL.keys() else 'FALSE') + 't' + str(path) + 't' + str(
                BAIDU_BOOL[host_key][1] if host_key in BAIDU_BOOL.keys() else 'FALSE') + 't' + str(creation_utc) + 't' + str(name) + 't' + str(value)
            print(cookieContent)

    def getOutFile(self, path: str = './log/'):
        '''此方法可以将cookie封装进文件'''
        with open(path + 'Cookie'+str(int(time.time())) + '.log', 'w') as f:
            # 写入头
            f.write(COOKIE_HEADER)
            # 写入体
            for i in self.cookieList:
                creation_utc, host_key, name, value, path = i
                cookieContent = str(host_key) + 't' + str(BAIDU_BOOL[host_key][0] if host_key in BAIDU_BOOL.keys() else 'FALSE') + 't' + str(path) + 't' + str(
                    BAIDU_BOOL[host_key][1] if host_key in BAIDU_BOOL.keys() else 'FALSE') + 't' + str(creation_utc) + 't' + str(name) + 't' + str(value) + 'n'
                f.write(cookieContent)


2.3 decode.py,用于解密chrome浏览器的cookie
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
import json
import base64
import win32crypt

def DecodeKey(path: str) -> str:
    '''本函数用于将local state中封装的密钥解密出来'''
    with open(path, 'r', encoding='utf-8') as f:
        jsonStr = json.load(f)
        encryptedKey = jsonStr['os_crypt']['encrypted_key']
    encrypted_key_with_header = base64.b64decode(encryptedKey)
    encrypted_key = encrypted_key_with_header[5:]
    return win32crypt.CryptUnprotectData(encrypted_key, None, None, None, 0)[1]

def DecodeValue(bytes: bytes, key: str) -> str:
    '''本函数用于将cookie中加密的value解密出来'''
    # 根据百度的结果,valEncrypted的构成分为三部分,都是固定长度
    nonce = bytes[3:15]
    cipherbytes = bytes[15:]

    aesgcm = AESGCM(key)
    plainbytes = aesgcm.decrypt(nonce, cipherbytes, None)

    return plainbytes.decode('utf-8')

2.4 _init_.py,头文件
from . conn import *
from . cookie import *
from . decode import *
四、主程序构建 1、构建main.py,用于获取csdn的cookie
from modules import *
import os


# 存储cookie、密钥的文件路径
CHROME_COOKIE_PATH = r'GoogleChromeUser DataDefaultnetworkCookies'
CHROME_LOCALSTATE_PATH = r'GoogleChromeUser DataLocal State'

path = os.environ['LOCALAPPDATA']
dbCookies = path + CHROME_COOKIE_PATH  # cookie文件,本质是一个sqlite数据库
fileLocalState = path + CHROME_LOCALSTATE_PATH  # 存储密钥的文件,本质是一个Json文件

# 通过模糊搜索csdn寻找cookie
KEY_WORD = r'%csdn%'

with Conn(dbCookies) as cur:
    sql = """select creation_utc,host_key,name,encrypted_value,path from cookies where host_key like '%s'""" % KEY_WORD
    cur.execute(sql)
    valCookiesWithEncode = cur.fetchall()

valCookiesWithDecode = []

# 从Local State文件里获取key
key = DecodeKey(fileLocalState)

for i in valCookiesWithEncode:
    creation_utc, host_key, name, valEncrypted, path = i

    value = DecodeValue(valEncrypted, key)
    valCookiesWithDecode.append(
        tuple((creation_utc, host_key, name, value, path)))

cookies = Cookie(valCookiesWithDecode)
cookies.getOutFile()
2、构建app.py,用于访问CSDN

这一步相对灵活,根据实际情况更新header。在浏览器上多用F12,如果爬取失败,检查一下爬取的内容是否藏在了XHR里面了。

from urllib.parse import *
from urllib.request import *
from http.cookiejar import *
import time
import ssl
import gzip
import re

ssl._create_default_https_context = ssl._create_unverified_context

# 要爬取的网页,注意csnd的网页内容不一定就在地址栏上,可能存放于xhr里面
url = 'https://bizapi.csdn.net/community-personal/v1/get-work?username=weixin_41936572'

# 建议将要爬取的网页里所有的header属性全部带进来(遇到:开头的可以删掉:)
# 这个headers不能直接用,我删了一些东西,请自己制作headers
headers = {
    'authority': 'bizapi.csdn.net',
    'method': 'GET',
    'path': '/community-personal/v1/get-work?username=weixin_41936572',
    'scheme': 'https',
    'accept': 'application/json, text/plain, */*',
    'accept-encoding': 'gzip, deflate, br',
    'accept-language': 'zh-CN,zh;q=0.9',
    'cache-control': 'no-cache',
    'cookie': '',
    'origin': 'https://i.csdn.net',
    'pragma': 'no-cache',
    'referer': 'https://i.csdn.net/',
    'sec-ch-ua': '".Not/A)Brand";v="99", "Google Chrome";v="103", "Chromium";v="103"',
    'sec-ch-ua-mobile': '?0',
    'sec-ch-ua-platform': '"Windows"',
    'sec-fetch-dest': 'empty',
    'sec-fetch-mode': 'cors',
    'sec-fetch-site': 'same-site',
    'sec-fetch-user': '?1',
    'upgrade-insecure-requests': 1,
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36',
    'x-ca-key': 203796071,
    'x-ca-nonce': '',
    'x-ca-signature': '',
    'x-ca-signature-headers': 'x-ca-key,x-ca-nonce'
}

# 这一步的文件改成自己通过main.py抓到的版本
cookie_jar = MozillaCookieJar('./log/Cookie1658368460.log')
cookie_jar.load(ignore_discard=True, ignore_expires=True)

cookie_processor = HTTPCookieProcessor(cookie_jar)
opener = build_opener(cookie_processor)

request = Request(url, headers=headers, method='GET')

response = opener.open(request)
data = response.read()
print(gzip.decompress(data))

cookie_jar.save('./log/Cookie'+str(int(time.time())) + '.log',
                ignore_discard=True, ignore_expires=True)

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1022198.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号